Skip to content

Commit

Permalink
[desk-tool] Add ValidationMenu
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent ce48f97 commit ba27f38
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"rules": {
"react/jsx-handler-names": "off",
"react/require-default-props": "off"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ export function DocumentPanel(props: DocumentPanelProps) {
[toggleHistory, toggleInspect]
)

const setFocusPath = useCallback(
(path: any) => {
if (formRef.current) {
formRef.current.handleFocus(path)
}
},
[formRef.current]
)

return (
<div className={styles.root}>
<div className={styles.headerContainer}>
Expand All @@ -85,12 +94,15 @@ export function DocumentPanel(props: DocumentPanelProps) {
idPrefix={props.idPrefix}
isClosable={props.isClosable}
isCollapsed={props.isCollapsed}
markers={props.markers}
menuItemGroups={props.menuItemGroups}
menuItems={menuItems}
onCloseView={props.onCloseView}
onContextMenuAction={handleContextMenuAction}
onSetActiveView={props.onSetActiveView}
onSplitPane={props.onSplitPane}
schemaType={props.schemaType}
setFocusPath={setFocusPath}
title={
<DocumentHeaderTitle
documentType={props.documentType}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
line-height: 17px;
}

.paneFunctions {
padding: 8px;
}

.contextMenuContainer {
padding: 8px;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {negate} from 'lodash'
import CloseIcon from 'part:@sanity/base/close-icon'
import LanguageFilter from 'part:@sanity/desk-tool/language-select-component?'
import React, {useCallback, useState} from 'react'
import {DocumentView, MenuAction, MenuItemGroup} from '../../types'
import {DocumentPanelContextMenu} from './contextMenu'
import {DocumentHeaderTabs} from './tabs'
import {TimelineDropdown} from './timelineDropdown'
import {ValidationMenu} from './validationMenu'

import styles from './header.css'

Expand All @@ -13,12 +15,15 @@ export interface DocumentPanelHeaderProps {
idPrefix: string
isClosable: boolean
isCollapsed: boolean
markers: any
menuItems: MenuAction[]
menuItemGroups: MenuItemGroup[]
onCloseView: () => void
onContextMenuAction: (action: MenuAction) => void
onSetActiveView: (id: string | null) => void
onSplitPane: () => void
schemaType: any
setFocusPath: (path: any) => void
title: React.ReactNode
views: DocumentView[]
}
Expand All @@ -30,6 +35,7 @@ export function DocumentPanelHeader(props: DocumentPanelHeaderProps) {
const contextMenuItems = props.menuItems.filter(isMenuButton)
const [isContextMenuOpen, setContextMenuOpen] = useState(false)
const [isVersionSelectOpen, setVersionSelectOpen] = useState(false)
const [isValidationOpen, setValidationOpen] = React.useState<boolean>(false)

const handleCloseContextMenu = useCallback(() => {
setContextMenuOpen(false)
Expand All @@ -43,13 +49,33 @@ export function DocumentPanelHeader(props: DocumentPanelHeaderProps) {
setVersionSelectOpen(!isVersionSelectOpen)
}, [isVersionSelectOpen])

const handleCloseValidationResults = useCallback(() => {
setValidationOpen(false)
}, [])

const handleToggleValidationResults = useCallback(() => {
setValidationOpen(!isValidationOpen)
}, [isValidationOpen])

return (
<div className={styles.root}>
<div className={styles.mainNav}>
<div className={styles.title}>
<strong>{props.title}</strong>
</div>

<div className={styles.paneFunctions}>
{LanguageFilter && <LanguageFilter />}
<ValidationMenu
isOpen={isValidationOpen}
markers={props.markers}
onClose={handleCloseValidationResults}
onToggle={handleToggleValidationResults}
schemaType={props.schemaType}
setFocusPath={props.setFocusPath}
/>
</div>

<div className={styles.contextMenuContainer}>
<DocumentPanelContextMenu
isCollapsed={props.isCollapsed}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Button from 'part:@sanity/components/buttons/default'
import ValidationList from 'part:@sanity/components/validation/list'
import ErrorOutlineIcon from 'part:@sanity/base/error-outline-icon'
import React from 'react'
import {Tooltip} from 'react-tippy'

interface ValidationMenuProps {
isOpen: boolean
markers: any[]
onClose: () => void
onToggle: () => void
schemaType: any
setFocusPath: (path: any) => void
}

export function ValidationMenu(props: ValidationMenuProps) {
const {isOpen, markers, onClose, onToggle, schemaType, setFocusPath} = props
const validationMarkers = markers.filter(marker => marker.type === 'validation')
const validationErrorMarkers = validationMarkers.filter(marker => marker.level === 'error')
const validationWarningwarnings = validationMarkers.filter(marker => marker.level === 'warning')

if (validationErrorMarkers.length === 0 && validationWarningwarnings.length === 0) {
return null
}

return (
<Tooltip
arrow
distance={13}
html={
<ValidationList
documentType={schemaType}
markers={validationMarkers}
isOpen={isOpen}
onClose={onClose}
onFocus={setFocusPath}
showLink
/>
}
inertia={false}
interactive
onRequestClose={onClose}
open={isOpen}
position="bottom"
theme="light"
trigger="click"
>
<Button
color={validationErrorMarkers.length > 0 ? 'danger' : 'warning'}
kind="simple"
icon={ErrorOutlineIcon}
onClick={onToggle}
padding="small"
selected={isOpen}
title="Show validation issues"
/>
</Tooltip>
)
}
12 changes: 11 additions & 1 deletion packages/design-studio/schemas/author.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@ export default {
type: 'document',
name: 'author',
title: 'Author',
fields: [{type: 'string', name: 'name', title: 'Name'}]
fields: [
{
type: 'string',
name: 'name',
title: 'Name',
validation: Rule =>
Rule.required()
.min(10)
.max(80)
}
]
}

0 comments on commit ba27f38

Please sign in to comment.