feat: add storage settings with upload file size limit

This commit is contained in:
Beng Eu committed 2022-03-02 14:27:14 +08:00
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))