Shift views to store and improve tce decsription

This commit is contained in:
Joshen Lim committed 2022-11-29 17:33:46 +08:00
1 parent 6d23225aeb
commit 40de9a3da0
6 files changed
+63 -35

No files matched your search

@@ -322,7 +322,7 @@ const ColumnEditor: FC<Props> = ({
<FormSectionContent loading={false} className="lg:!col-span-8">
<Toggle
label="Encrypt Column"
descriptionText="Encrypt the column's data with pgsodium's Transparent Column Encryption (TCE)"
descriptionText={`Encrypt the column's data with pgsodium's Transparent Column Encryption (TCE). Decrypted values will be stored within the "decrypted_${selectedTable.name}" view.`}
checked={columnFields.isEncrypted}
onChange={() => onUpdateField({ isEncrypted: !columnFields.isEncrypted })}
/>
@@ -149,6 +149,10 @@ const SidePanelEditor: FC<Props> = ({
closePanel()
}
if (configuration.isEncrypted) {
await meta.schemas.loadViews(selectedTable?.schema ?? '')
}
resolve()
}
@@ -2,9 +2,8 @@ import { FC, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
import { partition } from 'lodash'
// import { Button } from 'ui'
import { observer } from 'mobx-react-lite'
import {
Alert,
Button,
Dropdown,
IconChevronDown,
@@ -60,7 +59,6 @@ const TableEditorMenu: FC<Props> = ({
const canCreateTables = checkPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables')
const [searchText, setSearchText] = useState<string>('')
const [schemaViews, setSchemaViews] = useState<SchemaView[]>([])
const [isRefreshing, setIsRefreshing] = useState<boolean>(false)
// We may need to shift this to the schema store and do something like meta.schema.loadViews()
@@ -68,12 +66,10 @@ const TableEditorMenu: FC<Props> = ({
useEffect(() => {
let cancel = false
const fetchViews = async (selectedSchema: string) => {
const views: SchemaView[] = await meta.schemas.getViews(selectedSchema)
if (!cancel) setSchemaViews(views)
}
if (selectedSchema) {
fetchViews(selectedSchema)
await meta.schemas.loadViews(selectedSchema)
}
if (selectedSchema) fetchViews(selectedSchema)
return () => {
cancel = true
}
@@ -93,8 +89,8 @@ const TableEditorMenu: FC<Props> = ({
const filteredSchemaViews =
searchText.length === 0
? schemaViews
: schemaViews.filter((view) => view.name.includes(searchText))
? meta.schemas.views
: meta.schemas.views.filter((view) => view.name.includes(searchText))
const [protectedSchemas, openSchemas] = partition(schemas, (schema) =>
meta.excludedSchemas.includes(schema?.name ?? '')
@@ -117,7 +113,6 @@ const TableEditorMenu: FC<Props> = ({
// @ts-ignore
onChange={(name: string) => {
setSearchText('')
setSchemaViews([])
onSelectSchema(name)
}}
>
@@ -296,24 +291,24 @@ const TableEditorMenu: FC<Props> = ({
<Menu.Group
// @ts-ignore
title={
<>
<div className="flex w-full items-center justify-between">
<span>All views</span>
</div>
</>
<div className="flex w-full items-center justify-between">
<span>All views</span>
</div>
}
/>
{schemaViews.map((view: SchemaView) => {
{meta.schemas.views.map((view: SchemaView) => {
const viewId = Base64.encode(JSON.stringify(view))
const isActive = id === viewId
return (
<Link key={viewId} href={`/project/${projectRef}/editor/${viewId}`}>
<Menu.Item key={viewId} rounded active={isActive}>
<div className="flex justify-between">
<p className="truncate">{view.name}</p>
</div>
</Menu.Item>
<a>
<Menu.Item key={viewId} rounded active={isActive}>
<div className="flex justify-between">
<p className="truncate">{view.name}</p>
</div>
</Menu.Item>
</a>
</Link>
)
})}
@@ -339,4 +334,4 @@ const TableEditorMenu: FC<Props> = ({
)
}
export default TableEditorMenu
export default observer(TableEditorMenu)
+19 -5
View File
@@ -3,7 +3,7 @@ import { NextPage } from 'next'
import { useRouter } from 'next/router'
import { observer } from 'mobx-react-lite'
import { isUndefined, isNaN } from 'lodash'
import { Modal } from 'ui'
import { Checkbox, Modal } from 'ui'
import { PostgresTable, PostgresColumn } from '@supabase/postgres-meta'
import Base64 from 'lib/base64'
@@ -24,6 +24,8 @@ const TableEditorPage: NextPage = () => {
const [isDeleting, setIsDeleting] = useState<boolean>(false)
const [isDuplicating, setIsDuplicating] = useState<boolean>(false)
const [isDeleteWithCascade, setIsDeleteWithCascade] = useState(false)
const [selectedColumnToDelete, setSelectedColumnToDelete] = useState<PostgresColumn>()
const [selectedTableToDelete, setSelectedTableToDelete] = useState<PostgresTable>()
@@ -70,6 +72,7 @@ const TableEditorPage: NextPage = () => {
const onDeleteColumn = (column: PostgresColumn) => {
setIsDeleting(true)
setSelectedColumnToDelete(column)
setIsDeleteWithCascade(false)
}
const onAddTable = () => {
@@ -87,6 +90,7 @@ const TableEditorPage: NextPage = () => {
const onDeleteTable = (table: PostgresTable) => {
setIsDeleting(true)
setSelectedTableToDelete(table)
setIsDeleteWithCascade(false)
}
const onDuplicateTable = (table: PostgresTable) => {
@@ -141,7 +145,9 @@ const TableEditorPage: NextPage = () => {
try {
if (isUndefined(selectedTableToDelete)) return
const response: any = await meta.tables.del(selectedTableToDelete.id)
const response: any = await meta.tables.del(selectedTableToDelete.id, {
cascade: isDeleteWithCascade,
})
if (response.error) throw response.error
const tables = meta.tables.list((table: PostgresTable) => table.schema === selectedSchema)
@@ -217,9 +223,17 @@ const TableEditorPage: NextPage = () => {
}
children={
<Modal.Content>
<p className="py-4 text-sm text-scale-1100">
Are you sure you want to delete the selected table? This action cannot be undone.
</p>
<div className="py-4 space-y-4">
<p className="text-sm text-scale-1100">
Are you sure you want to delete the selected table? This action cannot be undone.
</p>
<Checkbox
label="Drop with cascade?"
description="Deletes the table and its dependent objects"
checked={isDeleteWithCascade}
onChange={() => setIsDeleteWithCascade(!isDeleteWithCascade)}
/>
</div>
</Modal.Content>
}
buttonLabel="Delete"
@@ -17,7 +17,7 @@ export interface IPostgresMetaInterface<T> {
load: () => void
create: (payload: any) => Promise<T | { error: ResponseError }>
update: (id: number | string, updates: any) => Promise<T | { error: ResponseError }>
del: (id: number | string) => Promise<boolean | { error: ResponseError }>
del: (id: number | string, payload?: any) => Promise<boolean | { error: ResponseError }>
list: (filter?: any) => T[]
find: (filter?: any) => T | undefined
byId: (id: number | string) => T | undefined
@@ -187,11 +187,11 @@ export default class PostgresMetaInterface<T> implements IPostgresMetaInterface<
}
}
async del(id: number | string) {
async del(id: number | string, payload: any = {}) {
try {
const headers = { 'Content-Type': 'application/json', ...this.headers }
const url = `${this.url}?id=${id}`
const response = await delete_<T>(url, {}, { headers })
const response = await delete_<T>(url, payload, { headers })
if (response.error) throw response.error
delete this.data[id]
+18 -3
View File
@@ -1,13 +1,22 @@
import { observable, makeObservable } from 'mobx'
import { PostgresSchema } from '@supabase/postgres-meta'
import PostgresMetaInterface, { IPostgresMetaInterface } from '../common/PostgresMetaInterface'
import { IRootStore } from '../RootStore'
import { ResponseError } from 'types'
interface SchemaView {
schema: string
name: string
}
export interface ISchemaStore extends IPostgresMetaInterface<PostgresSchema> {
getViews: (schema: string) => Promise<any | { error: ResponseError }>
views: SchemaView[]
loadViews: (schema: string) => Promise<any | { error: ResponseError }>
}
export default class SchemaStore extends PostgresMetaInterface<PostgresSchema> {
views: SchemaView[]
constructor(
rootStore: IRootStore,
dataUrl: string,
@@ -17,14 +26,20 @@ export default class SchemaStore extends PostgresMetaInterface<PostgresSchema> {
options?: { identifier: string }
) {
super(rootStore, dataUrl, headers, options)
makeObservable(this, {
views: observable,
})
this.views = []
}
async getViews(schema: string) {
async loadViews(schema: string) {
const query = `
select schemaname as schema, viewname as name from pg_catalog.pg_views
where schemaname = '${schema}'
order by schemaname, viewname;
`
return await this.rootStore.meta.query(query)
const views = await this.rootStore.meta.query(query)
this.views = views
return views
}
}