mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 10:25:06 +03:00
* update deps + image codemod (studio) * update next links (studio) * update deps * update links (ui) * remove next-transpile-modules * move next-themes dependency * chore: update ConfirmDialog * chore: remove old ConfirmModal js file. migrated to TS * dependency wrangling * remove empty page * update next links (www) * First run bump react-data-grid-v7 beta 4 * fix package-lock.json * more deps wrangling * update recharts * update sentry options * fix some broken things in www * studio fixes * fix graphiql * fix studio build * fix menu hydration * small build error * update turbo * fix www typescript errors * docs image codemod * links codemod docs * fix docs typescript errors * move useConsent to ui to prevent circular deps * Fix links * Fix homepage * Fix links * move studio/ to apps/ * Revert "move studio/ to apps/" This reverts commit1b0a985fcb. * disable outputFileTracingRoot * remove outputFileTracingRoot * fix homepage product cards * fix PrivacySettings links * Fix links * Fix the build for www. * Minor fixes for JWTGenerator. * Fix the docs and ui tests. * Revert codehike back to 0.8.3 * remove ConfirmAlert() * reenable babel because mobx hates me * fix blog image and comparison page avatar * Fix svg errors * update image synthax * Fix code hike * Move the button in a div so that it doesn't inherit its parent height and make the button look weird. * When components are defined in a component, they get recreated on each render. This makes them unstable in certain cases and causes infinite rerenders. * Replace the next/head usage with next/script. * Chore/upgrade next 13 fix table editor (#18431) * fix table editor styling and fix row deletion logic * Fix deleting selected rows from header, and fix checkboxes not clearing up * Fix deleting all rows when filter applied, and fix deleting all rows * Fix grid size styling issue * Fix TS error * Hydration errors * studio org pages fixes * fix more studio links * audit logs fixes * dropdown icon styling fixes * fix some images in www * upgrade to next 14 * try new sentry wrapper for api * see if this is even invoked * Revert "see if this is even invoked" This reverts commit86c3973ffa. * Revert "try new sentry wrapper for api" This reverts commitf67623ebad. * Revert "upgrade to next 14" This reverts commita24dd6131e. * chore: allow node version 19/20 * Try to fix the LogTable so that it renders with the newer "react-data-grid" version. * Fix type errors in the log renderer code. * Fix the replication screen. * Add the CSS for the GraphiQL. * Fix SQL editor results rendering * Lint * Fix SQL editor results height issue * Fix auth RLS not invalidating RQ when toggling RLS * Fix database tables new/edit column regressed * Fix migrations page empty state if migrations schema not yet created * Fix API side panel docs temp remove postgrest text for column description PK and FK * Fix + improve timeout handling in SQL editor --------- Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com> Co-authored-by: Terry Sutton <saltcod@gmail.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com> Co-authored-by: Kevin Grüneberg <k.grueneberg1994@gmail.com>
231 lines
6.3 KiB
TypeScript
231 lines
6.3 KiB
TypeScript
import * as React from 'react'
|
|
import { CalculatedColumn } from 'react-data-grid'
|
|
import { ColumnType, SupaColumn, SupaRow, SupaTable } from '../types'
|
|
import {
|
|
isArrayColumn,
|
|
isBoolColumn,
|
|
isCiTextColumn,
|
|
isDateColumn,
|
|
isDateTimeColumn,
|
|
isEnumColumn,
|
|
isForeignKeyColumn,
|
|
isJsonColumn,
|
|
isNumericalColumn,
|
|
isTextColumn,
|
|
isTimeColumn,
|
|
} from './types'
|
|
import {
|
|
BooleanEditor,
|
|
DateEditor,
|
|
DateTimeEditor,
|
|
DateTimeWithTimezoneEditor,
|
|
JsonEditor,
|
|
NumberEditor,
|
|
SelectEditor,
|
|
TextEditor,
|
|
TimeEditor,
|
|
TimeWithTimezoneEditor,
|
|
} from 'components/grid/components/editor'
|
|
import { AddColumn, ColumnHeader, SelectColumn } from 'components/grid/components/grid'
|
|
import { COLUMN_MIN_WIDTH } from 'components/grid/constants'
|
|
import {
|
|
BooleanFormatter,
|
|
DefaultFormatter,
|
|
ForeignKeyFormatter,
|
|
JsonFormatter,
|
|
} from 'components/grid/components/formatter'
|
|
|
|
export const ESTIMATED_CHARACTER_PIXEL_WIDTH = 9
|
|
|
|
export function getGridColumns(
|
|
table: SupaTable,
|
|
options?: {
|
|
editable?: boolean
|
|
defaultWidth?: string | number
|
|
onAddColumn?: () => void
|
|
onExpandJSONEditor: (column: string, row: SupaRow) => void
|
|
}
|
|
): any[] {
|
|
const columns = table.columns.map((x, idx) => {
|
|
const columnType = getColumnType(x)
|
|
const columnDefaultWidth = getColumnDefaultWidth(x)
|
|
const columnWidthBasedOnName =
|
|
(x.name.length + x.format.length) * ESTIMATED_CHARACTER_PIXEL_WIDTH
|
|
const columnWidth = options?.defaultWidth
|
|
? options.defaultWidth
|
|
: columnDefaultWidth < columnWidthBasedOnName
|
|
? columnWidthBasedOnName
|
|
: columnDefaultWidth
|
|
|
|
const columnDefinition: CalculatedColumn<SupaRow> = {
|
|
key: x.name,
|
|
name: x.name,
|
|
idx: idx + 1,
|
|
resizable: true,
|
|
sortable: true,
|
|
width: columnWidth,
|
|
minWidth: COLUMN_MIN_WIDTH,
|
|
frozen: x.isPrimaryKey || false,
|
|
isLastFrozenColumn: false,
|
|
// rowGroup: false,
|
|
renderHeaderCell: (props) => (
|
|
<ColumnHeader
|
|
{...props}
|
|
columnType={columnType}
|
|
isPrimaryKey={x.isPrimaryKey}
|
|
isEncrypted={x.isEncrypted}
|
|
format={x.format}
|
|
foreignKey={x.foreignKey}
|
|
/>
|
|
),
|
|
renderEditCell: options
|
|
? getColumnEditor(x, columnType, options?.editable ?? false, options.onExpandJSONEditor)
|
|
: undefined,
|
|
renderCell: getColumnFormatter(x, columnType),
|
|
|
|
// [Next 18 Refactor] Double check if this is correct
|
|
parent: undefined,
|
|
level: 0,
|
|
maxWidth: undefined,
|
|
draggable: false,
|
|
}
|
|
|
|
return columnDefinition
|
|
})
|
|
|
|
const gridColumns = [SelectColumn, ...columns]
|
|
if (options?.onAddColumn) {
|
|
gridColumns.push(AddColumn)
|
|
}
|
|
|
|
return gridColumns
|
|
}
|
|
|
|
function getColumnEditor(
|
|
columnDefinition: SupaColumn,
|
|
columnType: ColumnType,
|
|
isEditable: boolean,
|
|
onExpandJSONEditor: (column: string, row: any) => void
|
|
) {
|
|
if (!isEditable) {
|
|
if (['array', 'json'].includes(columnType)) {
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => (
|
|
<JsonEditor {...p} isEditable={isEditable} onExpandEditor={onExpandJSONEditor} />
|
|
)
|
|
} else if (!['number', 'boolean'].includes(columnType)) {
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => <TextEditor {...p} isEditable={isEditable} />
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
if (columnDefinition.isPrimaryKey || !columnDefinition.isUpdatable) {
|
|
return
|
|
}
|
|
|
|
switch (columnType) {
|
|
case 'boolean': {
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => <BooleanEditor {...p} isNullable={columnDefinition.isNullable} />
|
|
}
|
|
case 'date': {
|
|
return DateEditor
|
|
}
|
|
case 'datetime': {
|
|
return columnDefinition.format.endsWith('z') ? DateTimeWithTimezoneEditor : DateTimeEditor
|
|
}
|
|
case 'time': {
|
|
return columnDefinition.format.endsWith('z') ? TimeWithTimezoneEditor : TimeEditor
|
|
}
|
|
case 'enum': {
|
|
const options = columnDefinition.enum!.map((x) => {
|
|
return { label: x, value: x }
|
|
})
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => <SelectEditor {...p} options={options} />
|
|
}
|
|
case 'array':
|
|
case 'json': {
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => <JsonEditor {...p} onExpandEditor={onExpandJSONEditor} />
|
|
}
|
|
case 'number': {
|
|
return NumberEditor
|
|
}
|
|
case 'citext':
|
|
case 'text': {
|
|
// eslint-disable-next-line react/display-name
|
|
return (p: any) => (
|
|
<TextEditor {...p} isEditable={isEditable} isNullable={columnDefinition.isNullable} />
|
|
)
|
|
}
|
|
default: {
|
|
return undefined
|
|
}
|
|
}
|
|
}
|
|
|
|
function getColumnFormatter(columnDef: SupaColumn, columnType: ColumnType) {
|
|
switch (columnType) {
|
|
case 'boolean': {
|
|
return BooleanFormatter
|
|
}
|
|
case 'foreign_key': {
|
|
if (columnDef.isPrimaryKey || !columnDef.isUpdatable) {
|
|
return DefaultFormatter
|
|
} else {
|
|
return ForeignKeyFormatter
|
|
}
|
|
}
|
|
case 'json': {
|
|
return JsonFormatter
|
|
}
|
|
default: {
|
|
return DefaultFormatter
|
|
}
|
|
}
|
|
}
|
|
|
|
function getColumnType(columnDef: SupaColumn): ColumnType {
|
|
if (isForeignKeyColumn(columnDef)) {
|
|
return 'foreign_key'
|
|
} else if (isNumericalColumn(columnDef.dataType)) {
|
|
return 'number'
|
|
} else if (isArrayColumn(columnDef.dataType)) {
|
|
return 'array'
|
|
} else if (isJsonColumn(columnDef.dataType)) {
|
|
return 'json'
|
|
} else if (isTextColumn(columnDef.dataType)) {
|
|
return 'text'
|
|
} else if (isCiTextColumn(columnDef.format)) {
|
|
return 'citext'
|
|
} else if (isDateColumn(columnDef.format)) {
|
|
return 'date'
|
|
} else if (isTimeColumn(columnDef.format)) {
|
|
return 'time'
|
|
} else if (isDateTimeColumn(columnDef.format)) {
|
|
return 'datetime'
|
|
} else if (isBoolColumn(columnDef.dataType)) {
|
|
return 'boolean'
|
|
} else if (isEnumColumn(columnDef.dataType)) {
|
|
return 'enum'
|
|
} else return 'unknown'
|
|
}
|
|
|
|
export function getColumnDefaultWidth(columnDef: SupaColumn): number {
|
|
if (isNumericalColumn(columnDef.dataType)) {
|
|
return 120
|
|
} else if (
|
|
isDateTimeColumn(columnDef.format) ||
|
|
isDateColumn(columnDef.format) ||
|
|
isTimeColumn(columnDef.format)
|
|
) {
|
|
return 150
|
|
} else if (isBoolColumn(columnDef.dataType)) {
|
|
return 120
|
|
} else if (isEnumColumn(columnDef.dataType)) {
|
|
return 150
|
|
} else return 250
|
|
}
|