mirror of
https://github.com/supabase/supabase.git
synced 2026-10-16 22:59:11 +03:00
8 files changed
+77
-15
No files matched your search
@@ -198,6 +198,8 @@ const Settings = () => {
|
||||
className="mb-4"
|
||||
label={authConfig.properties.MAILER_AUTOCONFIRM.title}
|
||||
onChange={(value) => {
|
||||
// If MAILER_AUTOCONFIRM is set to true, it means we are disabling email confirmations.
|
||||
// "Enable email confirmations" should be toggled off.
|
||||
handleToggle('MAILER_AUTOCONFIRM', !value)
|
||||
}}
|
||||
checked={!model.MAILER_AUTOCONFIRM}
|
||||
@@ -335,10 +337,13 @@ const Settings = () => {
|
||||
<UIToggle
|
||||
layout="horizontal"
|
||||
label={authConfig.properties.SMS_AUTOCONFIRM.title}
|
||||
onChange={() => {
|
||||
handleToggle('SMS_AUTOCONFIRM')
|
||||
onChange={(value) => {
|
||||
// If SMS_AUTOCONFIRM is set to true, it means we are disabling phone confirmations.
|
||||
// "Enable phone confirmations" should be toggled off.
|
||||
handleToggle('SMS_AUTOCONFIRM', !value)
|
||||
}}
|
||||
checked={model.SMS_AUTOCONFIRM}
|
||||
//
|
||||
checked={!model.SMS_AUTOCONFIRM}
|
||||
descriptionText={authConfig.properties.SMS_AUTOCONFIRM.help}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -3,7 +3,15 @@ import React, { useEffect, useRef, useState } from 'react'
|
||||
import { NextPage } from 'next'
|
||||
import { useRouter } from 'next/router'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Typography, IconLoader, IconAlertCircle, IconRewind, Button, IconInfo } from '@supabase/ui'
|
||||
import {
|
||||
Typography,
|
||||
IconLoader,
|
||||
IconAlertCircle,
|
||||
IconRewind,
|
||||
Button,
|
||||
IconInfo,
|
||||
Card,
|
||||
} from '@supabase/ui'
|
||||
|
||||
import { withAuth } from 'hooks'
|
||||
import { get } from 'lib/common/fetch'
|
||||
@@ -72,6 +80,9 @@ export const LogPage: NextPage = () => {
|
||||
if (prevPageData === null) {
|
||||
// reduce interval window limit by using the timestamp of the last log
|
||||
queryParams = genQueryParams(params)
|
||||
} else if (prevPageData.data.length === 0) {
|
||||
// no rows returned, indicates that no more data to retrieve and append.
|
||||
return null
|
||||
} else {
|
||||
const len = prevPageData.data.length
|
||||
const { timestamp: tsLimit }: LogData = prevPageData.data[len - 1]
|
||||
@@ -84,18 +95,16 @@ export const LogPage: NextPage = () => {
|
||||
}
|
||||
const {
|
||||
data = [],
|
||||
error: swrError,
|
||||
isValidating,
|
||||
mutate,
|
||||
size,
|
||||
setSize,
|
||||
} = useSWRInfinite<Logs>(getKeyLogs, get, { revalidateOnFocus: false })
|
||||
|
||||
// const { data, isValidating, mutate } = useSWR<Logs>(logUrl, get, { revalidateOnFocus: false })
|
||||
let logData: LogData[] = []
|
||||
let error: null | string = null
|
||||
|
||||
let error: null | string = swrError ? swrError.message : null
|
||||
data.forEach((response: Logs) => {
|
||||
if (response && response.data) {
|
||||
if (!error && response && response.data) {
|
||||
logData = [...logData, ...response.data]
|
||||
}
|
||||
if (!error && response && response.error) {
|
||||
@@ -220,9 +229,16 @@ export const LogPage: NextPage = () => {
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
<div className="flex w-full h-full justify-center items-center space-x-2 mx-auto">
|
||||
<IconAlertCircle size={16} />
|
||||
<Typography.Text type="secondary">Sorry! Could not fetch data</Typography.Text>
|
||||
<div className="flex w-full h-full justify-center items-center mx-auto">
|
||||
<Card className="flex flex-col gap-y-2">
|
||||
<div className="flex flex-row gap-x-2 py-2">
|
||||
<IconAlertCircle size={16} />
|
||||
<Typography.Text type="secondary">
|
||||
Sorry! An error occured when fetching data.
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<Typography.Text type="warning">{error}</Typography.Text>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
<LogTable data={logData} isCustomQuery={mode === 'custom'} />
|
||||
|
||||
@@ -42,15 +42,21 @@ LogPage.mockImplementation((props) => {
|
||||
const Page = jest.requireActual('pages/project/[ref]/settings/logs/[type]').LogPage
|
||||
// wrap with SWR to reset the cache each time
|
||||
return (
|
||||
<SWRConfig value={{ provider: () => new Map() }}>
|
||||
<SWRConfig
|
||||
value={{
|
||||
provider: () => new Map(),
|
||||
shouldRetryOnError: false,
|
||||
}}
|
||||
>
|
||||
<Page {...props} />
|
||||
</SWRConfig>
|
||||
)
|
||||
})
|
||||
|
||||
import { render, fireEvent, waitFor, screen } from '@testing-library/react'
|
||||
import { render, fireEvent, waitFor, screen, act } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { getToggleByText } from '../../helpers'
|
||||
import { wait } from '@testing-library/user-event/dist/utils'
|
||||
|
||||
beforeEach(() => {
|
||||
// reset mocks between tests
|
||||
@@ -298,3 +304,27 @@ test('load older btn will fetch older logs', async () => {
|
||||
})
|
||||
await waitFor(() => screen.getByText('second event'))
|
||||
})
|
||||
|
||||
test('bug: load older btn does not error out when previous page is empty', async () => {
|
||||
// bugfix for https://sentry.io/organizations/supabase/issues/2903331460/?project=5459134&referrer=slack
|
||||
get.mockImplementation((url) => {
|
||||
if (url.includes('count')) {
|
||||
return {}
|
||||
}
|
||||
return { data: [] }
|
||||
})
|
||||
render(<LogPage />)
|
||||
|
||||
userEvent.click(screen.getByText('Load older'))
|
||||
// NOTE: potential race condition, since we are asserting that something DOES NOT EXIST
|
||||
// wait for 500s to make sure all ui logic is complete
|
||||
// need to wrap in act because internal react state is changing during this time.
|
||||
await act(async () => await wait(100))
|
||||
|
||||
// clicking load older multiple times should not give error
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/Sorry/)).toBeNull()
|
||||
expect(screen.queryByText(/An error occured/)).toBeNull()
|
||||
expect(screen.queryByText(/undefined/)).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -122,6 +122,7 @@ If we put this token into https://jwt.io, we see it decodes to:
|
||||
```js
|
||||
{
|
||||
"role": "anon",
|
||||
"iss": "supabase",
|
||||
"iat": 1614205174,
|
||||
"exp": 1929781174
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ const fiveYears = new Date(now.getFullYear() + 5, now.getMonth(), now.getDate())
|
||||
const anonToken = `
|
||||
{
|
||||
"role": "anon",
|
||||
"iss": "supabase",
|
||||
"iat": ${Math.floor(today / 1000)},
|
||||
"exp": ${Math.floor(fiveYears / 1000)}
|
||||
}
|
||||
@@ -17,6 +18,7 @@ const anonToken = `
|
||||
const serviceToken = `
|
||||
{
|
||||
"role": "service_role",
|
||||
"iss": "supabase",
|
||||
"iat": ${Math.floor(today / 1000)},
|
||||
"exp": ${Math.floor(fiveYears / 1000)}
|
||||
}
|
||||
|
||||
@@ -243,10 +243,16 @@ const Nav = (props: Props) => {
|
||||
</div>
|
||||
<div className="hidden lg:flex items-center sm:space-x-3">
|
||||
<a href="https://github.com/supabase/supabase" target="_blank">
|
||||
<Button type="default" icon={<IconStar />}>
|
||||
<Button
|
||||
className="sbui-btn sbui-btn-text sbui-btn--tiny sbui-btn--text-align-center"
|
||||
icon={<IconStar />}
|
||||
>
|
||||
Star us on GitHub
|
||||
</Button>
|
||||
</a>
|
||||
<a href="https://app.supabase.io/">
|
||||
<Button type="default">Sign in</Button>
|
||||
</a>
|
||||
<a href="https://app.supabase.io/">
|
||||
<Button>Start your project</Button>
|
||||
</a>
|
||||
|
||||
@@ -104,6 +104,7 @@ function Database() {
|
||||
/>
|
||||
</div>,
|
||||
]}
|
||||
documentation_url={'/docs/guides/database'}
|
||||
/>
|
||||
|
||||
<SectionContainer>
|
||||
|
||||
@@ -87,6 +87,7 @@ function StoragePage() {
|
||||
/>
|
||||
</div>,
|
||||
]}
|
||||
documentation_url={'/docs/guides/storage'}
|
||||
/>
|
||||
|
||||
<SectionContainer>
|
||||
|
||||
Reference in new issue
Block a user