Skip to content

Commit

Permalink
Merge pull request #59 from kareemmahlees/feat/fk-relations
Browse files Browse the repository at this point in the history
Foreign key relations
  • Loading branch information
kareemmahlees authored May 5, 2024
2 parents 9e3dede + 87d9df7 commit 80778c6
Show file tree
Hide file tree
Showing 40 changed files with 801 additions and 304 deletions.
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
],
"commit": false,
"fixed": [],
"linked": [],
"linked": [["@tablex/core", "@tablex/lib", "@tablex/tailwind"]],
"access": "public",
"baseBranch": "master",
"updateInternalDependencies": "patch",
Expand Down
24 changes: 24 additions & 0 deletions .changeset/cool-terms-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@tablex/core": patch
---

## Backend Changes

### New

- `ColumnProps` returns a new prop `has_fk_relations`.
- A new Tauri command `fk_relations`.

### Refactor

- gather all enums and structs into `types.rs`.

## Frontend Changes

### New

- Dropdown menu with tabs for table names and a Table for related rows.

### Refactor

- Split `useQuery` hooks into custom hooks.
8 changes: 4 additions & 4 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''

assignees: ""
---

**Describe the bug**
Expand All @@ -20,8 +19,9 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.

**System Info (please complete the following information):**
- TableX Release: [e.g. Latest]
- Output of `pnpm tauri:info` [e.g. 22]

- TableX Release: [e.g. Latest]
- Output of `pnpm tauri:info` [e.g. 22]

**Additional context**
Add any other context about the problem here.
4 changes: 1 addition & 3 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ name: Feature request
about: Suggest an idea for this project
title: "[FEAT]"
labels: enhancement
assignees: ''

assignees: ""
---

**Is your feature request related to a problem? Please describe.**
Expand All @@ -13,6 +12,5 @@ A clear and concise description of what the problem is. Ex. I'm always frustrate
**Describe the solution you'd like**
A clear and concise description of what you want to happen.


**Additional context**
Add any other context or screenshots about the feature request here.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ strip = true
[workspace.dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
# sqlx = { version = "0.6.3", features = ["runtime-tokio-rustls", "any", "time"] }
sqlx = { version = "0.6.3", features = [
"runtime-tokio-native-tls",
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ While not claiming that it is a replacement of any other tool, yet, it strives t

## Announcements 🎉

### v0.3.6

- TableX now supports Foreign key relations 🔗.

### v0.3.5

- TableX now ships with a little CLI tool that helps you to create & save `on the fly` connections with ease from your terminal ⭐, checkout the [CLI](./docs/CLI.md) documentation.
- TableX bundle size is now roughly 30% smaller 🚀

Expand Down
1 change: 1 addition & 0 deletions apps/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-query": "^5.8.4",
"@tanstack/react-router": "^1.19.2",
Expand Down
2 changes: 1 addition & 1 deletion apps/core/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ tauri = { version = "1.6.1", features = [
"process-command-api",
] }
sqlx = { workspace = true }
tokio = { version = "1", features = ["full"] }
clap = { version = "4.5.1", features = ["derive"] }
tokio = { workspace = true }
regex = "1.10.3"

[features]
Expand Down
2 changes: 1 addition & 1 deletion apps/core/src-tauri/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use clap::Command;
use clap::{error::ErrorKind, CommandFactory, Parser};
use tauri::{async_runtime::Mutex, Manager};
use tauri::{AppHandle, Window};
use tx_lib::Drivers;
use tx_lib::types::Drivers;

#[derive(Parser, Debug)]
#[command(version, about)]
Expand Down
2 changes: 1 addition & 1 deletion apps/core/src-tauri/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use tx_handlers::{mysql::MySQLHandler, postgres::PostgresHandler, sqlite::SQLite
use tx_lib::{
fs::{delete_from_connections_file, read_from_connections_file, write_into_connections_file},
handler::Handler,
Drivers,
types::Drivers,
};

#[tauri::command]
Expand Down
7 changes: 4 additions & 3 deletions apps/core/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use connection::{
connections_exist, create_connection_record, delete_connection_record, establish_connection,
get_connection_details, get_connections, test_connection,
};
use row::{create_row, delete_rows, get_paginated_rows, update_row};
use table::{get_columns_definition, get_tables};
use row::{create_row, delete_rows, get_fk_relations, get_paginated_rows, update_row};
use table::{get_columns_props, get_tables};
use tauri::async_runtime::Mutex;
use tauri::{Manager, Window, WindowEvent};

Expand Down Expand Up @@ -60,9 +60,10 @@ fn main() {
get_tables,
get_paginated_rows,
delete_rows,
get_columns_definition,
get_columns_props,
create_row,
update_row,
get_fk_relations
])
.on_window_event(move |event| {
if let WindowEvent::Destroyed = event.event() {
Expand Down
19 changes: 18 additions & 1 deletion apps/core/src-tauri/src/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ use serde_json::Value as JsonValue;
use std::collections::HashMap;
use tauri::async_runtime::Mutex;
use tauri::State;
use tx_lib::types::{FKRows, PaginatedRows};

#[tauri::command]
pub async fn get_paginated_rows(
state: State<'_, Mutex<SharedState>>,
table_name: String,
page_index: u16,
page_size: i32,
) -> Result<Map<String, JsonValue>, String> {
) -> Result<PaginatedRows, String> {
let state = state.lock().await;
let pool = state.pool.as_ref().unwrap();
let handler = state.handler.as_deref().unwrap();
Expand Down Expand Up @@ -101,3 +102,19 @@ pub async fn update_row(
.update_row(pool, table_name, set_condition, pk_col_name, pk_col_value)
.await
}

#[tauri::command]
pub async fn get_fk_relations(
state: tauri::State<'_, Mutex<SharedState>>,
table_name: String,
column_name: String,
cell_value: JsonValue,
) -> Result<Vec<FKRows>, String> {
let state = state.lock().await;
let pool = state.pool.as_ref().unwrap();
let handler = state.handler.as_deref().unwrap();

handler
.fk_relations(pool, table_name, column_name, cell_value)
.await
}
9 changes: 4 additions & 5 deletions apps/core/src-tauri/src/table.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::state::SharedState;
use serde_json::Value as JsonValue;
use sqlx::Row;
use std::collections::HashMap;
use tauri::{async_runtime::Mutex, State};
use tx_lib::types::ColumnProps;

#[tauri::command]
pub async fn get_tables(state: State<'_, Mutex<SharedState>>) -> Result<Vec<String>, String> {
Expand All @@ -23,14 +22,14 @@ pub async fn get_tables(state: State<'_, Mutex<SharedState>>) -> Result<Vec<Stri
}

#[tauri::command]
pub async fn get_columns_definition(
pub async fn get_columns_props(
state: State<'_, Mutex<SharedState>>,
table_name: String,
) -> Result<HashMap<String, HashMap<String, JsonValue>>, String> {
) -> Result<Vec<ColumnProps>, String> {
let state = state.lock().await;
let pool = state.pool.as_ref().unwrap();
let handler = state.handler.as_ref().unwrap();
let cols_defs = handler.get_columns_definition(pool, table_name).await?;
let cols_defs = handler.get_columns_props(pool, table_name).await?;

Ok(cols_defs)
}
19 changes: 8 additions & 11 deletions apps/core/src/commands/columns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@ import {
NUMERIC_DATA_TYPE,
STRING_DATA_TYPES
} from "@tablex/lib/constants"
import { ColumnProps } from "@tablex/lib/types"
import type { ColumnProps } from "@tablex/lib/types"
import { invoke } from "@tauri-apps/api/tauri"
import { z } from "zod"

export const getColsDefinitions = async (tableName: string) => {
const result = await invoke<Record<string, ColumnProps>>(
"get_columns_definition",
{
tableName
}
)
export const getColsProps = async (tableName: string) => {
const result = await invoke<ColumnProps[]>("get_columns_props", {
tableName
})
return result
}

export const getZodSchemaFromCols = async (tableName: string) => {
const cols = await getColsDefinitions(tableName)
const cols = await getColsProps(tableName)
const schemaObject: z.ZodRawShape = {}
Object.entries(cols).forEach(([colName, colProps]) => {
cols.forEach((colProps) => {
let validationRule: z.ZodTypeAny

switch (true) {
Expand Down Expand Up @@ -64,7 +61,7 @@ export const getZodSchemaFromCols = async (tableName: string) => {
validationRule = validationRule.optional()
}

schemaObject[colName] = validationRule
schemaObject[colProps.columnName] = validationRule
})

return z.object(schemaObject)
Expand Down
14 changes: 13 additions & 1 deletion apps/core/src/commands/row.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PaginatedRows } from "@tablex/lib/types"
import type { FkRows, PaginatedRows } from "@tablex/lib/types"
import { customToast } from "@tablex/lib/utils"
import type { QueryClient } from "@tanstack/react-query"
import type { Router } from "@tanstack/react-router"
Expand Down Expand Up @@ -140,3 +140,15 @@ export const copyRowIntoClipboard = async (
)
}
}

export const getFkRelations = async (
tableName: string,
columnName: string,
cellValue: any
) => {
return await invoke<FkRows[]>("get_fk_relations", {
tableName,
columnName,
cellValue
})
}
19 changes: 16 additions & 3 deletions apps/core/src/components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,21 @@ interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
virtualizerRef:React.RefObject<HTMLDivElement>
virtualizer:Virtualizer<any,any>
}

const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table
ref={ref}
className={cn("w-full caption-bottom text-sm", className)}
{...props}
/>
</div>
))
Table.displayName = "Table"

const VirtualTable = React.forwardRef<
HTMLTableElement,
TableProps
>(({ className,virtualizerRef,virtualizer, ...props }, ref) => (
Expand All @@ -22,7 +35,7 @@ const Table = React.forwardRef<
</div>
</div>
))
Table.displayName = "Table"
VirtualTable.displayName = "VirtualTable"

const TableHeader = React.forwardRef<
HTMLTableSectionElement,
Expand Down Expand Up @@ -118,6 +131,6 @@ export {
TableFooter,
TableHead,
TableHeader,
TableRow
TableRow, VirtualTable
}

55 changes: 55 additions & 0 deletions apps/core/src/components/ui/tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"use client"

import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"

import { cn } from "@tablex/lib/utils"

const Tabs = TabsPrimitive.Root

const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
className
)}
{...props}
/>
))
TabsList.displayName = TabsPrimitive.List.displayName

const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className
)}
{...props}
/>
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName

const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className
)}
{...props}
/>
))
TabsContent.displayName = TabsPrimitive.Content.displayName

export { Tabs, TabsList, TabsTrigger, TabsContent }
1 change: 1 addition & 0 deletions apps/core/src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import "@tanstack/react-table"
declare module "@tanstack/react-table" {
interface ColumnMeta {
name: string
hasFkRelations: boolean
}
}
Loading

0 comments on commit 80778c6

Please sign in to comment.