mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 02:45:07 +03:00
feat: add storage settings with upload file size limit
This commit is contained in:
1 parent
27e5362d85
commit
0fba3f2320
6 files changed
+146
-3
No files matched your search
@@ -12,6 +12,12 @@ export const generateSettingsMenu = (ref: string): ProductMenuGroup[] => {
|
||||
{ name: 'Database', key: 'database', url: `/project/${ref}/settings/database`, items: [] },
|
||||
{ name: 'API', key: 'api', url: `/project/${ref}/settings/api`, items: [] },
|
||||
{ name: 'Auth Settings', key: 'auth', url: `/project/${ref}/auth/settings`, items: [] },
|
||||
{
|
||||
name: 'Storage Settings',
|
||||
key: 'storage',
|
||||
url: `/project/${ref}/storage/settings`,
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
name: 'Billing & Usage',
|
||||
key: 'billing',
|
||||
|
||||
@@ -24,7 +24,7 @@ interface Props {}
|
||||
const StorageMenu: FC<Props> = () => {
|
||||
const router = useRouter()
|
||||
const { ref, bucketId } = router.query
|
||||
const page = router.pathname.split('/')[4] as undefined | 'policies' | 'usage'
|
||||
const page = router.pathname.split('/')[4] as undefined | 'policies' | 'settings' | 'usage'
|
||||
|
||||
const { ui } = useStore()
|
||||
const projectRef = ui.selectedProject?.ref
|
||||
@@ -92,8 +92,13 @@ const StorageMenu: FC<Props> = () => {
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<Menu.Group title="Settings" />
|
||||
<Menu.Group title="Config" />
|
||||
|
||||
<Link href={`/project/${projectRef}/storage/settings`}>
|
||||
<Menu.Item rounded active={page === 'settings'}>
|
||||
<Typography.Text className="truncate">Settings</Typography.Text>
|
||||
</Menu.Item>
|
||||
</Link>
|
||||
<Link href={`/project/${projectRef}/storage/policies`}>
|
||||
<Menu.Item rounded active={page === 'policies'}>
|
||||
<Typography.Text className="truncate">Policies</Typography.Text>
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import useSWR from 'swr'
|
||||
import { FC, useState } from 'react'
|
||||
import { AutoField } from 'uniforms-bootstrap4'
|
||||
import { Typography } from '@supabase/ui'
|
||||
|
||||
import { API_URL } from 'lib/constants'
|
||||
import { patch, get } from 'lib/common/fetch'
|
||||
import { useStore } from 'hooks'
|
||||
import SchemaFormPanel from 'components/to-be-cleaned/forms/SchemaFormPanel'
|
||||
|
||||
const StorageSettings: FC<any> = ({ projectRef }) => {
|
||||
const { data, error } = useSWR(`${API_URL}/projects/${projectRef}/config?app=storage`, get)
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="p-6 mx-auto sm:w-full md:w-3/4 text-center">
|
||||
<Typography.Title level={3}>Error loading storage settings</Typography.Title>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return (
|
||||
<div className="p-6 mx-auto sm:w-full md:w-3/4 text-center">
|
||||
<Typography.Title level={3}>Loading...</Typography.Title>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return <StorageConfig config={data} projectRef={projectRef} />
|
||||
}
|
||||
|
||||
const StorageConfig = ({ config, projectRef }: any) => {
|
||||
const { ui } = useStore()
|
||||
|
||||
const [updates, setUpdates] = useState(config)
|
||||
|
||||
const updateConfig = async (updatedConfig: any) => {
|
||||
try {
|
||||
const response = await patch(
|
||||
`${API_URL}/projects/${projectRef}/config?app=storage`,
|
||||
updatedConfig
|
||||
)
|
||||
if (response.error) {
|
||||
throw response.error
|
||||
} else {
|
||||
ui.setNotification({ category: 'success', message: 'Settings saved' })
|
||||
}
|
||||
} catch (error: any) {
|
||||
ui.setNotification({ category: 'error', message: `Update config failed: ${error.message}` })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col w-full min-h-full">
|
||||
<SchemaFormPanel
|
||||
title="Settings"
|
||||
schema={{
|
||||
properties: {
|
||||
fileSizeLimit: {
|
||||
title: 'Upload file size limit',
|
||||
type: 'integer',
|
||||
help: 'The maximum size in bytes of a file that can be uploaded.',
|
||||
},
|
||||
},
|
||||
required: ['fileSizeLimit'],
|
||||
type: 'object',
|
||||
}}
|
||||
model={updates}
|
||||
onSubmit={(model: any) => updateConfig(model)}
|
||||
onReset={() => setUpdates(config)}
|
||||
>
|
||||
<AutoField name="fileSizeLimit" showInlineError errorMessage="Must be a number." />
|
||||
</SchemaFormPanel>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StorageSettings
|
||||
@@ -137,8 +137,21 @@ const StorageSidebar = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="my-4 px-3">
|
||||
<Menu.Group title="Settings" />
|
||||
<Menu.Group title="Config" />
|
||||
<div className="space-y-1">
|
||||
<div>
|
||||
<Link href={`/project/${ref}/storage/settings`}>
|
||||
<a>
|
||||
<Menu.Item
|
||||
key="settings"
|
||||
rounded
|
||||
active={router.pathname === '/project/[ref]/storage/settings'}
|
||||
>
|
||||
<Typography.Text>Settings</Typography.Text>
|
||||
</Menu.Item>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<Link href={`/project/${ref}/storage/policies`}>
|
||||
<a>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import StorageExplorer from './StorageExplorer/StorageExplorer'
|
||||
import StoragePolicies from './StoragePolicies/StoragePolicies'
|
||||
import StorageSettings from './StorageSettings/StorageSettings'
|
||||
import StorageUsage from './StorageUsage/StorageUsage'
|
||||
import StorageSidebar from './StorageSidebar'
|
||||
|
||||
@@ -10,6 +11,7 @@ import ToggleBucketPublicModal from './ToggleBucketPublicModal'
|
||||
export {
|
||||
StorageExplorer,
|
||||
StoragePolicies,
|
||||
StorageSettings,
|
||||
StorageUsage,
|
||||
StorageSidebar,
|
||||
CreateBucketModal,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
import { API_URL, PROJECT_STATUS } from 'lib/constants'
|
||||
import { useStore, withAuth } from 'hooks'
|
||||
import { post } from 'lib/common/fetch'
|
||||
import { StorageLayout } from 'components/layouts'
|
||||
import { StorageSettings } from 'components/to-be-cleaned/Storage'
|
||||
|
||||
/**
|
||||
* PageLayout is used to setup layout - as usual it will requires inject global store
|
||||
*/
|
||||
const PageLayout = () => {
|
||||
const router = useRouter()
|
||||
const { ref } = router.query
|
||||
|
||||
const { ui } = useStore()
|
||||
const project = ui.selectedProject
|
||||
|
||||
useEffect(() => {
|
||||
if (project && project.status === PROJECT_STATUS.INACTIVE) {
|
||||
post(`${API_URL}/projects/${ref}/restore`, {})
|
||||
}
|
||||
}, [project])
|
||||
|
||||
if (!project) return <div></div>
|
||||
|
||||
return (
|
||||
<StorageLayout title="Settings">
|
||||
<div className="storage-container flex flex-grow p-4">
|
||||
<StorageSettings projectRef={ref} />
|
||||
</div>
|
||||
</StorageLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default withAuth(observer(PageLayout))
|
||||
Reference in new issue
Block a user