mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
feat(studio): clean up support form message (#42174)
* feat(studio): clean up support form message Support form message currently has the studio version and dashboard logs link appended to the end. On request from the Support team, we're moving this to metadata fields so it won't be as distracting. * Hide IncidentAdmonition if event is maintenance --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
1 parent
eb85515acb
commit
9caa0d548a
5 files changed
+36
-34
No files matched your search
@@ -54,7 +54,8 @@ const getStatusDescription = (
|
||||
}
|
||||
|
||||
export function IncidentAdmonition({ isActive }: IncidentAdmonitionProps) {
|
||||
const { data: incidents, isLoading, isError } = useIncidentStatusQuery()
|
||||
const { data: allStatusPageEvents = [], isLoading, isError } = useIncidentStatusQuery()
|
||||
const incidents = allStatusPageEvents.filter((x) => x.impact !== 'maintenance')
|
||||
|
||||
// Don't render anything while loading, on error, or if no incidents
|
||||
if (isLoading || isError || !incidents || incidents.length === 0) {
|
||||
|
||||
@@ -27,24 +27,23 @@ export const formatMessage = ({
|
||||
message,
|
||||
attachments = [],
|
||||
error,
|
||||
commit,
|
||||
dashboardLogUrl,
|
||||
}: {
|
||||
message: string
|
||||
attachments?: string[]
|
||||
attachments?: Array<string>
|
||||
error: string | null | undefined
|
||||
commit: { commitSha: string; commitTime: string } | undefined
|
||||
dashboardLogUrl?: string
|
||||
}) => {
|
||||
const errorString = error != null ? `\n\nError: ${error}` : ''
|
||||
const attachmentsString =
|
||||
attachments.length > 0 ? `\n\nAttachments:\n${attachments.join('\n')}` : ''
|
||||
const commitString =
|
||||
commit != undefined
|
||||
? `\n\n---\nSupabase Studio version: SHA ${commit.commitSha} deployed at ${commit.commitTime === 'unknown' ? 'unknown time' : dayjs(commit.commitTime).format('YYYY-MM-DD HH:mm:ss Z')}`
|
||||
: ''
|
||||
const logString = dashboardLogUrl ? `\nDashboard logs: ${dashboardLogUrl}` : ''
|
||||
return `${message}${errorString}${attachmentsString}${commitString}${logString}`
|
||||
return `${message}${errorString}${attachmentsString}`
|
||||
}
|
||||
|
||||
export const formatStudioVersion = (commit: { commitSha: string; commitTime: string }): string => {
|
||||
const formattedTime =
|
||||
commit.commitTime === 'unknown'
|
||||
? 'unknown time'
|
||||
: dayjs(commit.commitTime).format('YYYY-MM-DD HH:mm:ss Z')
|
||||
return `SHA ${commit.commitSha} deployed at ${formattedTime}`
|
||||
}
|
||||
|
||||
export function getPageIcon(page: Page) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import type { SupportFormValues } from './SupportForm.schema'
|
||||
import type { SupportFormActions, SupportFormState } from './SupportForm.state'
|
||||
import {
|
||||
formatMessage,
|
||||
formatStudioVersion,
|
||||
getOrgSubscriptionPlan,
|
||||
NO_ORG_MARKER,
|
||||
NO_PROJECT_MARKER,
|
||||
@@ -141,8 +142,6 @@ export const SupportFormV2 = ({ form, initialError, state, dispatch }: SupportFo
|
||||
message: values.message,
|
||||
attachments,
|
||||
error: initialError,
|
||||
commit,
|
||||
dashboardLogUrl: dashboardLogUrl?.[0],
|
||||
}),
|
||||
verified: true,
|
||||
tags: ['dashboard-support-form'],
|
||||
@@ -155,6 +154,8 @@ export const SupportFormV2 = ({ form, initialError, state, dispatch }: SupportFo
|
||||
.map((x) => x.trim().replace(/ /g, '_').toLowerCase())
|
||||
.join(';'),
|
||||
browserInformation: detectBrowser(),
|
||||
dashboardLogs: dashboardLogUrl?.[0],
|
||||
dashboardStudioVersion: commit ? formatStudioVersion(commit) : undefined,
|
||||
}
|
||||
|
||||
if (values.projectRef !== NO_PROJECT_MARKER) {
|
||||
|
||||
@@ -86,9 +86,7 @@ const { mockCommitSha, mockCommitTime, mockUseDeploymentCommitQuery } = vi.hoist
|
||||
}
|
||||
})
|
||||
|
||||
const supportVersionInfo = `\n\n---\nSupabase Studio version: SHA ${mockCommitSha} deployed at ${dayjs(
|
||||
mockCommitTime
|
||||
).format('YYYY-MM-DD HH:mm:ss Z')}`
|
||||
const mockStudioVersion = `SHA ${mockCommitSha} deployed at ${dayjs(mockCommitTime).format('YYYY-MM-DD HH:mm:ss Z')}`
|
||||
|
||||
vi.mock('react-inlinesvg', () => ({
|
||||
__esModule: true,
|
||||
@@ -810,10 +808,9 @@ describe('SupportFormPage', () => {
|
||||
siteUrl: 'https://project-1.example.com',
|
||||
additionalRedirectUrls: 'https://project-1.example.com/callbacks',
|
||||
browserInformation: 'Chrome',
|
||||
dashboardStudioVersion: mockStudioVersion,
|
||||
})
|
||||
const expectedMessage =
|
||||
'Requests return status 500 when calling the RPC endpoint' + supportVersionInfo
|
||||
expect(payload.message).toBe(expectedMessage)
|
||||
expect(payload.message).toBe('Requests return status 500 when calling the RPC endpoint')
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading', { name: /support request sent/i })).toBeInTheDocument()
|
||||
@@ -901,9 +898,9 @@ describe('SupportFormPage', () => {
|
||||
siteUrl: 'https://project-2.supabase.dev',
|
||||
additionalRedirectUrls: 'https://project-2.supabase.dev/redirect',
|
||||
browserInformation: 'Chrome',
|
||||
dashboardStudioVersion: mockStudioVersion,
|
||||
})
|
||||
const expectedMessage = 'MFA challenge fails with an unknown error code' + supportVersionInfo
|
||||
expect(payload.message).toBe(expectedMessage)
|
||||
expect(payload.message).toBe('MFA challenge fails with an unknown error code')
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading', { name: /support request sent/i })).toBeInTheDocument()
|
||||
@@ -1002,10 +999,10 @@ describe('SupportFormPage', () => {
|
||||
siteUrl: 'https://project-3.apps.supabase.co',
|
||||
additionalRedirectUrls: 'https://project-3.apps.supabase.co/auth',
|
||||
browserInformation: 'Chrome',
|
||||
dashboardStudioVersion: mockStudioVersion,
|
||||
})
|
||||
expect(payload.message).toBe(
|
||||
'Connections time out after 30 seconds\n\nError: Connection timeout detected' +
|
||||
supportVersionInfo
|
||||
'Connections time out after 30 seconds\n\nError: Connection timeout detected'
|
||||
)
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -1381,10 +1378,9 @@ describe('SupportFormPage', () => {
|
||||
})
|
||||
|
||||
const payload = submitSpy.mock.calls[0]?.[0]
|
||||
expect(payload.message).toContain('Navigation menu does not respond after latest deploy')
|
||||
expect(payload.message).toMatch(
|
||||
/Dashboard logs: https:\/\/storage\.example\.com\/signed\/.+\.json/
|
||||
)
|
||||
expect(payload.message).toBe('Navigation menu does not respond after latest deploy')
|
||||
expect(payload.dashboardLogs).toMatch(/^https:\/\/storage\.example\.com\/signed\/.+\.json$/)
|
||||
expect(payload.dashboardStudioVersion).toBe(mockStudioVersion)
|
||||
})
|
||||
|
||||
test('shows toast on submission error and allows form re-editing and resubmission', async () => {
|
||||
@@ -1455,10 +1451,9 @@ describe('SupportFormPage', () => {
|
||||
|
||||
const payload = submitSpy.mock.calls[0]?.[0]
|
||||
expect(payload.subject).toBe('Cannot access settings')
|
||||
expect(payload.message).toMatch(
|
||||
'Settings page shows 500 error - updated description' + supportVersionInfo
|
||||
)
|
||||
expect(payload.message).toMatch(/Dashboard logs: https:\/\/storage\.example\.com\/.+\.json/)
|
||||
expect(payload.message).toBe('Settings page shows 500 error - updated description')
|
||||
expect(payload.dashboardLogs).toMatch(/^https:\/\/storage\.example\.com\/signed\/.+\.json$/)
|
||||
expect(payload.dashboardStudioVersion).toBe(mockStudioVersion)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(toastSuccessSpy).toHaveBeenCalledWith('Support request sent. Thank you!')
|
||||
@@ -1684,9 +1679,9 @@ describe('SupportFormPage', () => {
|
||||
verified: true,
|
||||
tags: ['dashboard-support-form'],
|
||||
browserInformation: 'Chrome',
|
||||
dashboardStudioVersion: mockStudioVersion,
|
||||
})
|
||||
const expectedMessage = 'I need help accessing my Supabase account' + supportVersionInfo
|
||||
expect(payload.message).toBe(expectedMessage)
|
||||
expect(payload.message).toBe('I need help accessing my Supabase account')
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading', { name: /support request sent/i })).toBeInTheDocument()
|
||||
|
||||
@@ -20,6 +20,8 @@ export type sendSupportTicketVariables = {
|
||||
siteUrl?: string
|
||||
additionalRedirectUrls?: string
|
||||
dashboardSentryIssueId?: string
|
||||
dashboardLogs?: string
|
||||
dashboardStudioVersion?: string
|
||||
}
|
||||
|
||||
export async function sendSupportTicket({
|
||||
@@ -36,6 +38,8 @@ export async function sendSupportTicket({
|
||||
siteUrl,
|
||||
additionalRedirectUrls,
|
||||
dashboardSentryIssueId,
|
||||
dashboardLogs,
|
||||
dashboardStudioVersion,
|
||||
}: sendSupportTicketVariables) {
|
||||
const { data, error } = await post('/platform/feedback/send', {
|
||||
body: {
|
||||
@@ -54,6 +58,8 @@ export async function sendSupportTicket({
|
||||
browserInformation,
|
||||
allowSupportAccess,
|
||||
dashboardSentryIssueId,
|
||||
dashboardLogs,
|
||||
dashboardStudioVersion,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in new issue
Block a user