Merge pull request #9366 from supabase/chore/misc-ui-fixes-061022

Chore/misc UI fixes 061022
This commit is contained in:
Terry Sutton authored and GitHub committed 2022-10-06 09:47:38 -02:30
commit dbaeab0627
10 files changed
+51 -31

No files matched your search

@@ -8,7 +8,7 @@ import RowRenderer from './RowRenderer'
import AwesomeDebouncePromise from 'awesome-debounce-promise'
function rowKeyGetter(row: SupaRow) {
return row.idx
return row?.idx ?? -1
}
interface IGrid extends GridProps {
@@ -21,6 +21,8 @@ const RowContextMenu: React.FC<RowContextMenuProps> = ({}) => {
const { props } = p
const { rowIdx } = props
const row = state.rows[rowIdx]
if (!row) return
const { error } = state.rowService!.delete([row])
if (error) {
if (state.onError) state.onError(error)
@@ -1,19 +1,15 @@
import { FC } from 'react'
import { IconX, Loading } from 'ui'
import { IconX } from 'ui'
import { LogData, QueryType } from './Logs.types'
import DatabaseApiSelectionRender, {
DatabaseApiSelectionHeaderRender,
} from './LogSelectionRenderers/DatabaseApiSelectionRender'
import DatabaseApiSelectionRender from './LogSelectionRenderers/DatabaseApiSelectionRender'
import DatabasePostgresSelectionRender from './LogSelectionRenderers/DatabasePostgresSelectionRender'
import FunctionInvocationSelectionRender, {
FunctionInvocationHeaderRender,
} from './LogSelectionRenderers/FunctionInvocationSelectionRender'
import FunctionInvocationSelectionRender from './LogSelectionRenderers/FunctionInvocationSelectionRender'
import FunctionLogsSelectionRender from './LogSelectionRenderers/FunctionLogsSelectionRender'
import DefaultExplorerSelectionRenderer from './LogSelectionRenderers/DefaultExplorerSelectionRenderer'
import DefaultPreviewSelectionRenderer from './LogSelectionRenderers/DefaultPreviewSelectionRenderer'
import { isDefaultLogPreviewFormat, LogsEndpointParams, LogsTableName } from '.'
import { isDefaultLogPreviewFormat, LogsEndpointParams } from '.'
import useSingleLog from 'hooks/analytics/useSingleLog'
import Connecting from 'components/ui/Loading/Loading'
@@ -64,6 +64,11 @@ const StorageLayout: FC<Props> = ({ title, children }) => {
storageExplorerStore.setLoaded(true)
}
const onSelectCreateBucket = async (bucketName: string, isPublic: boolean) => {
const bucket = await createBucket(bucketName, isPublic)
if (bucket.name) router.push(`/project/${ref}/storage/buckets/${bucket.name}`)
}
const onSelectDeleteBucket = async (bucket: any) => {
const res = await deleteBucket(bucket)
// Ideally this should be within deleteBucket as its a necessary side effect
@@ -101,7 +106,7 @@ const StorageLayout: FC<Props> = ({ title, children }) => {
<CreateBucketModal
visible={showCreateBucketModal}
onSelectCancel={closeCreateBucketModal}
onSelectSave={createBucket}
onSelectSave={onSelectCreateBucket}
/>
<DeleteBucketModal
visible={showDeleteBucketModal}
@@ -358,7 +358,10 @@ const Results = ({ results }) => {
function onCopyCell() {
if (columns && cellPosition) {
const { idx, rowIdx } = cellPosition
const colKey = columns[idx].key
const column = columns[idx]
if (!column) return
const colKey = column.key
const cellValue = results[rowIdx]?.[colKey] ?? ''
const value = formatClipboardValue(cellValue)
copyToClipboard(value)
@@ -4,13 +4,13 @@ import { Modal, Alert, Button, Input, Toggle } from 'ui'
interface Props {
visible: boolean
onSelectCancel: () => {}
onSelectSave: () => {}
onSelectSave: (bucketName: string, isPublic: boolean) => {}
}
const CreateBucketModal: FC<Props> = ({
visible = false,
onSelectCancel = () => {},
onSelectSave = (bucketName: string, isPublic: boolean) => {},
onSelectSave = () => {},
}) => {
const [saving, setSaving] = useState(false)
const [error, setError] = useState('')
@@ -234,6 +234,8 @@ const StorageExplorer = observer(({ bucket }) => {
const onDeleteSelectedFiles = async () => {
if (selectedItemsToDelete.length === 1) {
const [itemToDelete] = selectedItemsToDelete
if (!itemToDelete) return
switch (itemToDelete.type) {
case STORAGE_ROW_TYPES.FOLDER:
await deleteFolder(itemToDelete)
@@ -404,31 +404,39 @@ class StorageExplorerStore {
// Already generated signed URL
copyToClipboard(filePreview.url, () => {
this.ui.setNotification({
message: `Copied URL for ${file.name} to clipboard.`,
category: 'success',
message: `Copied URL for ${file.name} to clipboard.`,
duration: 4000,
})
})
} else {
// Need to generate signed URL, and might as well save it to cache as well
const signedUrl = await this.fetchFilePreview(file.name)
let formattedUrl = new URL(signedUrl)
formattedUrl.searchParams.set('t', new Date().toISOString())
copyToClipboard(formattedUrl.toString(), () => {
try {
let formattedUrl = new URL(signedUrl)
formattedUrl.searchParams.set('t', new Date().toISOString())
copyToClipboard(formattedUrl.toString(), () => {
this.ui.setNotification({
category: 'success',
message: `Copied URL for ${file.name} to clipboard.`,
duration: 4000,
})
})
const fileCache = {
id: file.id,
url: formattedUrl.toString(),
expiresIn: DEFAULT_EXPIRY,
fetchedAt: Date.now(),
}
this.addFileToPreviewCache(fileCache)
} catch (error) {
this.ui.setNotification({
message: `Copied URL for ${file.name} to clipboard.`,
category: 'success',
duration: 4000,
category: 'error',
message: `Failed to copy URL: ${error}`,
})
})
const fileCache = {
id: file.id,
url: formattedUrl.toString(),
expiresIn: DEFAULT_EXPIRY,
fetchedAt: Date.now(),
}
this.addFileToPreviewCache(fileCache)
}
}
@@ -443,7 +451,7 @@ class StorageExplorerStore {
})
}
const { error } = await this.supabaseClient.storage.createBucket(bucketName, {
const { data, error } = await this.supabaseClient.storage.createBucket(bucketName, {
public: isPublic,
})
if (error) {
@@ -456,6 +464,7 @@ class StorageExplorerStore {
await this.fetchBuckets()
this.closeCreateBucketModal()
return data
}
openBucket = async (bucket) => {
@@ -73,6 +73,9 @@ export const LogsExplorerPage: NextPageWithLayout = () => {
pathname: router.pathname,
query: { ...router.query, q: template.searchString },
})
content.addRecentLogSqlSnippet({
sql: template.searchString,
})
}
const handleRun = (value?: string | React.MouseEvent<HTMLButtonElement>) => {
@@ -1,8 +1,8 @@
import React, { useEffect } from 'react'
import { useEffect } from 'react'
import Link from 'next/link'
import { observer } from 'mobx-react-lite'
import { Button, IconClock, IconSave, Loading } from 'ui'
import { useStore, withAuth } from 'hooks'
import { Button, IconClock } from 'ui'
import { useStore } from 'hooks'
import RecentQueriesItem from 'components/interfaces/Settings/Logs/RecentQueriesItem'
import LogsExplorerLayout from 'components/layouts/LogsExplorerLayout/LogsExplorerLayout'