mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
Merge pull request #9366 from supabase/chore/misc-ui-fixes-061022
Chore/misc UI fixes 061022
This commit is contained in:
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'
|
||||
|
||||
|
||||
Reference in new issue
Block a user