Skip to content

Commit

Permalink
feat: add a "configuration issues" button + dialog to the global nav …
Browse files Browse the repository at this point in the history
…bar in development
  • Loading branch information
bjoerge committed Aug 15, 2022
1 parent b6b8d5e commit ab1cdef
Show file tree
Hide file tree
Showing 7 changed files with 302 additions and 190 deletions.
9 changes: 9 additions & 0 deletions packages/sanity/src/studio/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {useWorkspace} from '../../workspace'
import {useColorScheme} from '../../colorScheme'
import {RouterState, useRouterState, useStateLink} from '../../../router'
import {useWorkspaces} from '../../workspaces'
import {isDev} from '../../../environment'
import {UserMenu} from './userMenu'
import {NewDocumentButton} from './NewDocumentButton'
import {PresenceMenu} from './presence'
Expand All @@ -34,6 +35,7 @@ import {SearchField} from './search'
import {ToolMenu as DefaultToolMenu} from './tools/ToolMenu'
import {ChangelogButton} from './changelog'
import {WorkspaceMenuButton} from './workspace'
import {ConfigIssuesButton} from './configIssues/ConfigIssuesButton'

const RootLayer = styled(Layer)`
min-height: auto;
Expand Down Expand Up @@ -110,6 +112,7 @@ export function Navbar(props: NavbarProps) {
collapsedPresenceMenu: mediaIndex <= 1,
loginStatus: mediaIndex > 1,
searchFullscreen: mediaIndex <= 1,
configIssues: mediaIndex > 1 && isDev,
workspaces: mediaIndex >= 3 && workspaces.length > 1,
tools: mediaIndex >= 3,
}),
Expand Down Expand Up @@ -282,6 +285,12 @@ export function Navbar(props: NavbarProps) {
</Box>
)}

{shouldRender.configIssues && (
<Box marginRight={2}>
<ConfigIssuesButton />
</Box>
)}

<Box marginRight={1}>
<PresenceMenu collapse={shouldRender.collapsedPresenceMenu} />
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React, {useCallback, useState} from 'react'
import {Box, Button, Dialog, Heading, Inline, Stack, Text, Tooltip} from '@sanity/ui'

import {InfoOutlineIcon, WarningOutlineIcon} from '@sanity/icons'
import {useId} from '@reach/auto-id'
import {useSchema} from '../../../../hooks'
import {SchemaProblemGroups} from '../../../screens/schemaErrors/SchemaProblemGroups'
import {useColorScheme} from '../../../colorScheme'

export function ConfigIssuesButton() {
const schema = useSchema()
const groupsWithWarnings =
schema._validation?.filter((group) =>
group.problems.some((problem) => problem.severity === 'warning')
) || []

// get root scheme
const {scheme} = useColorScheme()

const dialogId = useId() || 'config-issues-dialog'

const [isDialogOpen, setDialogOpen] = useState(false)
const [buttonElement, setButtonElement] = useState<HTMLButtonElement | null>(null)
const handleOpen = useCallback(() => setDialogOpen(true), [])

const handleClose = useCallback(() => {
setDialogOpen(false)

if (buttonElement) {
buttonElement.focus()
}
}, [buttonElement])

if (groupsWithWarnings.length === 0) {
return null
}

return (
<>
<Tooltip
content={
<Box padding={2}>
<Text size={1}>Found configuration issues</Text>
</Box>
}
placement="bottom"
portal
scheme={scheme}
>
<Box>
<Button
icon={WarningOutlineIcon}
mode="bleed"
tone="caution"
onClick={handleOpen}
ref={setButtonElement}
selected={isDialogOpen}
/>
</Box>
</Tooltip>

{isDialogOpen && (
<Dialog
header="Configuration issues"
width={2}
onClickOutside={handleClose}
onClose={handleClose}
// force root scheme here to "break out" of the navbar's dark scheme
scheme={scheme}
id={dialogId}
>
<Stack space={4} padding={4}>
<Inline space={2} paddingY={3}>
<Text muted size={1}>
<InfoOutlineIcon />
</Text>
<Text muted size={1}>
Note: Configuration checks are only performed during development and will not be
visible in production builds
</Text>
</Inline>

<Heading as="h2" size={1}>
Found {groupsWithWarnings.length} schema warnings
</Heading>
<SchemaProblemGroups problemGroups={groupsWithWarnings} />
</Stack>
</Dialog>
)}
</>
)
}
137 changes: 0 additions & 137 deletions packages/sanity/src/studio/screens/schemaErrors/SchemaErrors.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Schema, SchemaValidationProblemPath} from '@sanity/types'
import {Card, Container} from '@sanity/ui'
import {Schema} from '@sanity/types'
import {Card, Container, Heading, Stack} from '@sanity/ui'
import React, {useEffect} from 'react'
import {isProd} from '../../../environment'
import {SchemaErrors} from './SchemaErrors'
import {SchemaProblemGroups} from './SchemaProblemGroups'
import {reportWarnings} from './reportWarnings'

interface SchemaErrorsScreenProps {
schema: Schema
Expand All @@ -14,60 +14,16 @@ export function SchemaErrorsScreen({schema}: SchemaErrorsScreenProps) {
group.problems.some((problem) => problem.severity === 'error')
) || []

useEffect(() => _reportWarnings(schema), [schema])
useEffect(() => reportWarnings(schema), [schema])

return (
<Card height="fill" overflow="auto" paddingY={[4, 5, 6, 7]} paddingX={4} sizing="border">
<Container width={1}>
<SchemaErrors problemGroups={groupsWithErrors} />
<Stack space={5}>
<Heading as="h1">Schema errors</Heading>
<SchemaProblemGroups problemGroups={groupsWithErrors} />
</Stack>
</Container>
</Card>
)
}

function _reportWarnings(schema: Schema) {
if (isProd) {
return
}

/* eslint-disable no-console */
const problemGroups = schema._validation

const groupsWithWarnings = problemGroups?.filter((group) =>
group.problems.some((problem) => problem.severity === 'warning')
)
if (groupsWithWarnings?.length === 0) {
return
}
console.groupCollapsed(`⚠️ Schema has ${groupsWithWarnings?.length} warnings`)
groupsWithWarnings?.forEach((group) => {
const path = _renderPath(group.path)

console.group(`%cAt ${path}`, 'color: #FF7636')

group.problems.forEach((problem) => {
console.log(problem.message)
})

console.groupEnd()
})
console.groupEnd()
/* eslint-enable no-console */
}

function _renderPath(path: SchemaValidationProblemPath) {
return path
.map((segment) => {
if (segment.kind === 'type') {
return `${segment.name || '<unnamed>'}(${segment.type})`
}

if (segment.kind === 'property') {
return segment.name
}

return null
})
.filter(Boolean)
.join(' > ')
}

0 comments on commit ab1cdef

Please sign in to comment.