Skip to content

Commit

Permalink
adds double click to foreign keys on grid
Browse files Browse the repository at this point in the history
  • Loading branch information
alaister authored and joshenlim committed Mar 15, 2023
1 parent 831b0ef commit be4c29d
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 32 deletions.
8 changes: 7 additions & 1 deletion studio/components/grid/SupabaseGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,13 @@ const SupabaseGridLayout = forwardRef<SupabaseGridRef, SupabaseGridProps>((props
onAddColumn={editable ? props.onAddColumn : undefined}
headerActions={headerActions}
/>
<Grid ref={gridRef} {...gridProps} rows={data?.rows ?? []} updateRow={props.updateTableRow} />
<Grid
ref={gridRef}
{...gridProps}
rows={data?.rows ?? []}
updateRow={props.updateTableRow}
onEditForeignKeyColumnValue={props.onEditForeignKeyColumnValue}
/>
<Footer isLoading={isLoading || isRefetching} />
<Shortcuts gridRef={gridRef} />
{mounted &&
Expand Down
46 changes: 45 additions & 1 deletion studio/components/grid/components/grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GridProps, SupaRow } from '../../types'
import { useDispatch, useTrackedState } from '../../store'
import RowRenderer from './RowRenderer'
import AwesomeDebouncePromise from 'awesome-debounce-promise'
import { ForeignRowSelectorProps } from 'components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector'

function rowKeyGetter(row: SupaRow) {
return row?.idx ?? -1
Expand All @@ -14,13 +15,27 @@ function rowKeyGetter(row: SupaRow) {
interface IGrid extends GridProps {
rows: any[]
updateRow: (previousRow: any, updatedData: any) => void
onEditForeignKeyColumnValue: (args: {
foreignKey: NonNullable<ForeignRowSelectorProps['foreignKey']>
row: any
column: any
}) => void
}

// [Joshen] Just for visibility this is causing some hook errors in the browser
export const Grid = memo(
forwardRef<DataGridHandle, IGrid>(
(
{ width, height, containerClass, gridClass, rowClass, rows, updateRow },
{
width,
height,
containerClass,
gridClass,
rowClass,
rows,
updateRow,
onEditForeignKeyColumnValue,
},
ref: React.Ref<DataGridHandle> | undefined
) => {
const dispatch = useDispatch()
Expand Down Expand Up @@ -60,6 +75,34 @@ export const Grid = memo(
})
}

const table = state.table

function getColumnForeignKey(columnName: string) {
const foreignKey = table?.columns.find((x) => x.name == columnName)?.foreignKey ?? {}

return Boolean(
foreignKey.targetTableSchema && foreignKey.targetTableName && foreignKey.targetColumnName
)
? foreignKey
: undefined
}

function onRowDoubleClick(row: any, column: any) {
const foreignKey = getColumnForeignKey(column.name)

if (foreignKey) {
onEditForeignKeyColumnValue({
foreignKey: {
target_column_name: foreignKey.targetColumnName!,
target_table_name: foreignKey.targetTableName!,
target_table_schema: foreignKey.targetTableSchema!,
},
row,
column,
})
}
}

if (!columnHeaders || columnHeaders.length == 0) {
return (
<div
Expand Down Expand Up @@ -92,6 +135,7 @@ export const Grid = memo(
onRowsChange={onRowsChange}
onSelectedCellChange={onSelectedCellChange}
onSelectedRowsChange={onSelectedRowsChange}
onRowDoubleClick={onRowDoubleClick}
className={gridClass}
rowClass={rowClass}
style={{ height: '100%' }}
Expand Down
6 changes: 6 additions & 0 deletions studio/components/grid/types/grid.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ForeignRowSelectorProps } from 'components/interfaces/TableGridEditor/SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector'
import React from 'react'
import { Dictionary } from './base'
import { SupaRow, SupaTable } from './table'
Expand Down Expand Up @@ -75,6 +76,11 @@ export interface SupabaseGridProps {
refreshDocs: () => void
onExpandJSONEditor: (column: string, row: SupaRow) => void
updateTableRow: (previousRow: any, updatedData: any) => void
onEditForeignKeyColumnValue: (args: {
foreignKey: NonNullable<ForeignRowSelectorProps['foreignKey']>
row: any
column: any
}) => void
}

export interface SupabaseGridRef {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ import { useStore } from 'hooks'
import { IconLoader, SidePanel } from 'ui'

import ActionBar from '../../ActionBar'
import { RowField } from '../RowEditor.types'
import { useEncryptedColumns } from './ForeignRowSelector.utils'
import SelectorGrid from './SelectorGrid'
import { useState } from 'react'
import Pagination from './Pagination'

export interface ForeignRowSelectorProps {
visible: boolean
referenceRow?: RowField
foreignKey?: {
target_table_schema: string
target_table_name: string
target_column_name: string
}
onSelect: (value: any) => void
closePanel: () => void
}

const ForeignRowSelector = ({
visible,
referenceRow,
foreignKey,
onSelect,
closePanel,
}: ForeignRowSelectorProps) => {
Expand All @@ -38,7 +41,7 @@ const ForeignRowSelector = ({
target_table_schema: schemaName,
target_table_name: tableName,
target_column_name: columnName,
} = referenceRow?.foreignKey ?? {}
} = foreignKey ?? {}

const tables = meta.tables.list()
const table = tables.find((table) => table.schema === schemaName && table.name === tableName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ const RowEditor = ({

<ForeignRowSelector
visible={isSelectingForeignKey}
referenceRow={referenceRow}
foreignKey={referenceRow?.foreignKey}
onSelect={onSelectForeignRowValue}
closePanel={() => {
setIsSelectingForeignKey(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC, useState } from 'react'
import { find, isEmpty, isUndefined } from 'lodash'
import { useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { find, isEmpty, isUndefined, noop } from 'lodash'
import { Dictionary } from 'components/grid'
import { Modal } from 'ui'
import type { PostgresTable, PostgresColumn } from '@supabase/postgres-meta'
Expand All @@ -19,17 +20,24 @@ import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectConte
import ConfirmationModal from 'components/ui/ConfirmationModal'
import JsonEdit from './RowEditor/JsonEditor/JsonEditor'
import { JsonEditValue } from './RowEditor/RowEditor.types'
import { useQueryClient } from '@tanstack/react-query'
import { sqlKeys } from 'data/sql/keys'
import ForeignRowSelector, {
ForeignRowSelectorProps,
} from './RowEditor/ForeignRowSelector/ForeignRowSelector'

interface Props {
export interface SidePanelEditorProps {
selectedSchema: string
selectedTable?: PostgresTable
selectedRowToEdit?: Dictionary<any>
selectedColumnToEdit?: PostgresColumn
selectedTableToEdit?: PostgresTable
selectedValueForJsonEdit?: JsonEditValue
sidePanelKey?: 'row' | 'column' | 'table' | 'json'
selectedForeignKeyToEdit?: {
foreignKey: NonNullable<ForeignRowSelectorProps['foreignKey']>
row: any
column: any
}
sidePanelKey?: 'row' | 'column' | 'table' | 'json' | 'foreign-row-selector'
isDuplicating?: boolean
closePanel: () => void
onRowCreated?: (row: Dictionary<any>) => void
Expand All @@ -41,21 +49,22 @@ interface Props {
onColumnSaved?: (hasEncryptedColumns?: boolean) => void
}

const SidePanelEditor: FC<Props> = ({
const SidePanelEditor = ({
selectedSchema,
selectedTable,
selectedRowToEdit,
selectedColumnToEdit,
selectedTableToEdit,
selectedValueForJsonEdit,
selectedForeignKeyToEdit,
sidePanelKey,
isDuplicating = false,
closePanel,
onRowCreated = () => {},
onRowUpdated = () => {},
onTableCreated = () => {},
onColumnSaved = () => {},
}) => {
onRowCreated = noop,
onRowUpdated = noop,
onTableCreated = noop,
onColumnSaved = noop,
}: SidePanelEditorProps) => {
const { meta, ui } = useStore()
const queryClient = useQueryClient()

Expand Down Expand Up @@ -156,6 +165,22 @@ const SidePanelEditor: FC<Props> = ({
} catch (error: any) {}
}

const onSaveForeignRow = async (value: any) => {
if (selectedTable === undefined || selectedForeignKeyToEdit === undefined) return

try {
const { row, column } = selectedForeignKeyToEdit
const payload = { [column.name]: value }
const identifiers = {} as Dictionary<any>
selectedTable.primary_keys.forEach((column) => (identifiers[column.name] = row![column.name]))

const isNewRecord = false
const configuration = { identifiers, rowIdx: row.idx }

saveRow(payload, isNewRecord, configuration, () => {})
} catch (error) {}
}

const saveColumn = async (
payload: CreateColumnPayload | UpdateColumnPayload,
foreignKey: ExtendedPostgresRelationship | undefined,
Expand Down Expand Up @@ -340,6 +365,12 @@ const SidePanelEditor: FC<Props> = ({
closePanel={onClosePanel}
onSaveJSON={onSaveJSON}
/>
<ForeignRowSelector
visible={sidePanelKey === 'foreign-row-selector'}
foreignKey={selectedForeignKeyToEdit?.foreignKey}
closePanel={onClosePanel}
onSelect={onSaveForeignRow}
/>
<ConfirmationModal
visible={isClosingPanel}
header="Confirm to close"
Expand Down
41 changes: 28 additions & 13 deletions studio/components/interfaces/TableGridEditor/TableGridEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FC, useRef, useEffect, useState } from 'react'
import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import { find, isUndefined } from 'lodash'
import { find, isUndefined, noop } from 'lodash'
import type { PostgresColumn, PostgresRelationship, PostgresTable } from '@supabase/postgres-meta'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { QueryKey, useQueryClient } from '@tanstack/react-query'
Expand Down Expand Up @@ -35,34 +35,45 @@ import {
useForeignKeyConstraintsQuery,
} from 'data/database/foreign-key-constraints-query'
import { FOREIGN_KEY_DELETION_ACTION } from 'data/database/database-query-constants'
import { ForeignRowSelectorProps } from './SidePanelEditor/RowEditor/ForeignRowSelector/ForeignRowSelector'

interface Props {
export interface TableGridEditorProps {
/** Theme for the editor */
theme?: 'dark' | 'light'

selectedSchema?: string
selectedTable: any // PostgresTable | SchemaView

/** Determines what side panel editor to show */
sidePanelKey?: 'row' | 'column' | 'table' | 'json'
sidePanelKey?: 'row' | 'column' | 'table' | 'json' | 'foreign-row-selector'
/** Toggles if we're duplicating a table */
isDuplicating: boolean
/** Selected entities if we're editing a row, column or table */
selectedRowToEdit?: Dictionary<any>
selectedColumnToEdit?: PostgresColumn
selectedTableToEdit?: PostgresTable
selectedValueForJsonEdit?: JsonEditValue
selectedForeignKeyToEdit?: {
foreignKey: NonNullable<ForeignRowSelectorProps['foreignKey']>
row: any
column: any
}

onAddRow: () => void
onEditRow: (row: Dictionary<any>) => void
onAddColumn: () => void
onEditColumn: (column: PostgresColumn) => void
onDeleteColumn: (column: PostgresColumn) => void
onExpandJSONEditor: (column: string, row: any) => void
onEditForeignKeyColumnValue: (args: {
foreignKey: NonNullable<ForeignRowSelectorProps['foreignKey']>
row: any
column: any
}) => void
onClosePanel: () => void
}

const TableGridEditor: FC<Props> = ({
const TableGridEditor = ({
theme = 'dark',

selectedSchema,
Expand All @@ -73,15 +84,17 @@ const TableGridEditor: FC<Props> = ({
selectedColumnToEdit,
selectedTableToEdit,
selectedValueForJsonEdit,

onAddRow = () => {},
onEditRow = () => {},
onAddColumn = () => {},
onEditColumn = () => {},
onDeleteColumn = () => {},
onExpandJSONEditor = () => {},
onClosePanel = () => {},
}) => {
selectedForeignKeyToEdit,

onAddRow = noop,
onEditRow = noop,
onAddColumn = noop,
onEditColumn = noop,
onDeleteColumn = noop,
onExpandJSONEditor = noop,
onEditForeignKeyColumnValue = noop,
onClosePanel = noop,
}: TableGridEditorProps) => {
const { project } = useProjectContext()
const { meta, ui, vault } = useStore()
const router = useRouter()
Expand Down Expand Up @@ -382,6 +395,7 @@ const TableGridEditor: FC<Props> = ({
onError={onError}
onSqlQuery={onSqlQuery}
onExpandJSONEditor={onExpandJSONEditor}
onEditForeignKeyColumnValue={onEditForeignKeyColumnValue}
/>
{!isUndefined(selectedSchema) && (
<SidePanelEditor
Expand All @@ -392,6 +406,7 @@ const TableGridEditor: FC<Props> = ({
selectedColumnToEdit={selectedColumnToEdit}
selectedTableToEdit={selectedTableToEdit}
selectedValueForJsonEdit={selectedValueForJsonEdit}
selectedForeignKeyToEdit={selectedForeignKeyToEdit}
sidePanelKey={sidePanelKey}
onRowCreated={onRowCreated}
onRowUpdated={onRowUpdated}
Expand Down
Loading

0 comments on commit be4c29d

Please sign in to comment.