Skip to content

Commit

Permalink
Merge branch 'corel' into corel-115-version-docs-history-error
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanl17 authored Aug 30, 2024
2 parents 9bed7dc + d0b4ca6 commit 3eb6403
Show file tree
Hide file tree
Showing 55 changed files with 334 additions and 538 deletions.
35 changes: 15 additions & 20 deletions packages/sanity/src/core/bundles/components/BundlesMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,20 @@ export const BundlesMenu = memo(function BundlesMenu(props: BundleListProps): Re
if (!bundles) return []

return bundles
.filter(({slug, archivedAt}) => !isDraftOrPublished(slug) && !archivedAt)
.sort(
({slug: aSlug}, {slug: bSlug}) =>
Number(deletedBundles[aSlug]) - Number(deletedBundles[bSlug]),
)
.filter(({_id, archivedAt}) => !isDraftOrPublished(_id) && !archivedAt)
.sort(({_id: aId}, {_id: bId}) => Number(deletedBundles[aId]) - Number(deletedBundles[bId]))
}, [bundles, deletedBundles])
const hasBundles = sortedBundlesToDisplay.length > 0

const handleBundleChange = useCallback(
(bundle: Partial<BundleDocument>) => () => {
if (bundle.slug) {
setPerspective(bundle.slug)
}
(bundleId: string) => () => {
setPerspective(bundleId)
},
[setPerspective],
)

const isBundleDeleted = useCallback(
(slug: string) => Boolean(deletedBundles[slug]),
(bundleId: string) => Boolean(deletedBundles[bundleId]),
[deletedBundles],
)

Expand All @@ -80,11 +75,11 @@ export const BundlesMenu = memo(function BundlesMenu(props: BundleListProps): Re
<>
<MenuItem
iconRight={
currentGlobalBundle.slug === LATEST.slug ? (
currentGlobalBundle._id === LATEST._id ? (
<CheckmarkIcon data-testid="latest-checkmark-icon" />
) : undefined
}
onClick={handleBundleChange(LATEST)}
onClick={handleBundleChange('drafts')}
pressed={false}
text={LATEST.title}
data-testid="latest-menu-item"
Expand All @@ -95,15 +90,15 @@ export const BundlesMenu = memo(function BundlesMenu(props: BundleListProps): Re
<StyledBox data-testid="bundles-list">
{sortedBundlesToDisplay.map((bundle) => (
<MenuItem
key={bundle.slug}
onClick={handleBundleChange(bundle)}
key={bundle._id}
onClick={handleBundleChange(bundle._id)}
padding={1}
pressed={false}
disabled={isBundleDeleted(bundle.slug)}
data-testid={`bundle-${bundle.slug}`}
disabled={isBundleDeleted(bundle._id)}
data-testid={`bundle-${bundle._id}`}
>
<Tooltip
disabled={!isBundleDeleted(bundle.slug)}
disabled={!isBundleDeleted(bundle._id)}
content={t('bundle.deleted-tooltip')}
placement="bottom-start"
>
Expand All @@ -112,7 +107,7 @@ export const BundlesMenu = memo(function BundlesMenu(props: BundleListProps): Re
hue={bundle.hue}
icon={bundle.icon}
padding={2}
isDisabled={isBundleDeleted(bundle.slug)}
isDisabled={isBundleDeleted(bundle._id)}
/>

<Box flex={1} padding={2} style={{minWidth: 100}}>
Expand All @@ -135,9 +130,9 @@ export const BundlesMenu = memo(function BundlesMenu(props: BundleListProps): Re
<Text size={1}>
<CheckmarkIcon
style={{
opacity: currentGlobalBundle.slug === bundle.slug ? 1 : 0,
opacity: currentGlobalBundle._id === bundle._id ? 1 : 0,
}}
data-testid={`${bundle.slug}-checkmark-icon`}
data-testid={`${bundle._id}-checkmark-icon`}
/>
</Text>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ describe('BundlesMenu', () => {
const mockBundles: BundleDocument[] = [
{
hue: 'magenta',
_id: 'db76c50e-358b-445c-a57c-8344c588a5d5',
_type: 'bundle',
slug: 'spring-drop',
_id: 'spring-drop',
_type: 'release',
_rev: '6z08CvvPnPe5pWSKJ5zPRR',
icon: 'heart-filled',
description: 'What a spring drop, allergies galore 🌸',
Expand All @@ -47,13 +46,12 @@ describe('BundlesMenu', () => {
{
icon: 'drop',
title: 'Autumn Drop',
_type: 'bundle',
_type: 'release',
hue: 'yellow',
_id: '0e87530e-4378-45ff-9d6f-58207e89f3ed',
_id: 'autumn-drop',
_createdAt: '2024-07-02T11:37:06Z',
_rev: '6z08CvvPnPe5pWSKJ5zJiK',
_updatedAt: '2024-07-02T11:37:06Z',
slug: 'autumn-drop',
authorId: '',
},
{
Expand All @@ -63,10 +61,10 @@ describe('BundlesMenu', () => {
description: 'What a summer drop woo hoo! ☀️',
_updatedAt: '2024-07-02T11:36:00Z',
title: 'Summer Drop',
_type: 'bundle',
_type: 'release',
hue: 'red',
_id: 'f6b2c2cc-1732-4465-bfb3-dd205b5d78e9',
slug: 'summer-drop',
_id: 'summer-drop',
authorId: '',
},
]
Expand Down Expand Up @@ -157,7 +155,7 @@ describe('BundlesMenu', () => {

act(() => {
expect(screen.getByText(mockBundles[0].title)).toBeInTheDocument()
expect(screen.getByTestId(`${mockBundles[0].slug}-checkmark-icon`)).toBeInTheDocument()
expect(screen.getByTestId(`${mockBundles[0]._id}-checkmark-icon`)).toBeInTheDocument()
})
})

Expand Down Expand Up @@ -222,8 +220,8 @@ describe('BundlesMenu', () => {
deletedBundles: {
'mock-deleted-bundle': {
_id: 'mock-deleted-bundle',
_type: 'bundle',
slug: 'mock-deleted-bundle',
_type: 'release',
_id: 'mock-deleted-bundle',
title: 'Mock Deleted Bundle',
} as BundleDocument,
},
Expand All @@ -248,8 +246,8 @@ describe('BundlesMenu', () => {
deletedBundles: {
'mock-deleted-bundle': {
_id: 'mock-deleted-bundle',
_type: 'bundle',
slug: 'mock-deleted-bundle',
_type: 'release',
_id: 'mock-deleted-bundle',
title: 'Mock Deleted Bundle',
} as BundleDocument,
},
Expand All @@ -262,8 +260,8 @@ describe('BundlesMenu', () => {
...mockBundles,
{
_id: 'mock-deleted-bundle',
_type: 'bundle',
slug: 'mock-deleted-bundle',
_type: 'release',
_id: 'mock-deleted-bundle',
title: 'Mock Deleted Bundle',
} as BundleDocument,
]}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {ArrowRightIcon} from '@sanity/icons'
import {Box, Flex, useToast} from '@sanity/ui'
import {type FormEvent, useCallback, useState} from 'react'
import {useTranslation} from 'sanity'
import {type FormBundleDocument, useTranslation} from 'sanity'

import {Button, Dialog} from '../../../../ui-components'
import {type BundleDocument} from '../../../store/bundles/types'
import {useBundleOperations} from '../../../store/bundles/useBundleOperations'
import {usePerspective} from '../../hooks/usePerspective'
import {BundleForm, DEFAULT_BUNDLE} from './BundleForm'
import {createReleaseId} from '../../util/createReleaseId'
import {BundleForm} from './BundleForm'

interface BundleDetailsDialogProps {
onCancel: () => void
Expand All @@ -22,69 +23,56 @@ export function BundleDetailsDialog(props: BundleDetailsDialogProps): JSX.Elemen
const formAction = bundle ? 'edit' : 'create'
const {t} = useTranslation()

const [value, setValue] = useState<Partial<BundleDocument>>(() => {
if (bundle) {
return {
slug: bundle.slug,
title: bundle.title,
description: bundle.description,
hue: bundle.hue,
icon: bundle.icon,
publishedAt: bundle.publishedAt,
}
}

return DEFAULT_BUNDLE
const [value, setValue] = useState((): FormBundleDocument => {
return {
_id: bundle?._id || createReleaseId(),
_type: 'release',
title: bundle?.title,
description: bundle?.description,
hue: bundle?.hue || 'gray',
icon: bundle?.icon || 'cube',
publishedAt: bundle?.publishedAt,
} as const
})
const [isSubmitting, setIsSubmitting] = useState(false)

// TODO MAKE SURE THIS IS HOW WE WANT TO DO THIS
const {setPerspective} = usePerspective()

const bundleOperation = useCallback(
(formValue: Partial<BundleDocument>) => {
if (formAction === 'edit' && bundle?._id) {
const updatedBundle: Partial<BundleDocument> = {
...formValue,
_id: bundle._id,
}

return updateBundle(updatedBundle)
}
return createBundle(formValue)
const submit = useCallback(
(formValue: FormBundleDocument) => {
return formAction === 'edit' ? updateBundle(formValue) : createBundle(formValue)
},
[bundle?._id, createBundle, formAction, updateBundle],
[createBundle, formAction, updateBundle],
)

const handleOnSubmit = useCallback(
async (event: FormEvent<HTMLFormElement>) => {
if (value.slug) {
try {
event.preventDefault()
setIsSubmitting(true)
try {
event.preventDefault()
setIsSubmitting(true)

const submitValue = {...value, title: value.title?.trim()}
await bundleOperation(submitValue)
if (formAction === 'create') {
setPerspective(value.slug)
}
} catch (err) {
console.error(err)
toast.push({
closable: true,
status: 'error',
title: `Failed to ${formAction} release`,
})
} finally {
setIsSubmitting(false)
onSubmit()
const submitValue = {...value, title: value.title?.trim()}
await submit(submitValue)
if (formAction === 'create') {
setPerspective(value._id)
}
} catch (err) {
console.error(err)
toast.push({
closable: true,
status: 'error',
title: `Failed to ${formAction} release`,
})
} finally {
setIsSubmitting(false)
onSubmit()
}
},
[bundleOperation, formAction, onSubmit, setPerspective, value, toast],
[value, submit, formAction, setPerspective, toast, onSubmit],
)

const handleOnChange = useCallback((changedValue: Partial<BundleDocument>) => {
const handleOnChange = useCallback((changedValue: FormBundleDocument) => {
setValue(changedValue)
}, [])

Expand Down
21 changes: 6 additions & 15 deletions packages/sanity/src/core/bundles/components/dialog/BundleForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {type ColorHueKey} from '@sanity/color'
import {type IconSymbol} from '@sanity/icons'
import {Flex, Stack, Text, TextArea, TextInput} from '@sanity/ui'
import {useCallback, useMemo, useRef, useState} from 'react'
import {useCallback, useMemo, useState} from 'react'
import {
type FormBundleDocument,
FormFieldHeaderText,
type FormNodeValidation,
useDateTimeFormat,
Expand All @@ -14,35 +15,32 @@ import {DateTimeInput} from '../../../../ui-components/inputs/DateInputs/DateTim
import {getCalendarLabels} from '../../../form/inputs/DateInputs/utils'
import {type BundleDocument} from '../../../store/bundles/types'
import {BundleIconEditorPicker, type BundleIconEditorPickerValue} from './BundleIconEditorPicker'
import {useGetBundleSlug} from './useGetBundleSlug'

interface BaseBundleDocument extends Partial<BundleDocument> {
hue: ColorHueKey
icon: IconSymbol
}

export const DEFAULT_BUNDLE: BaseBundleDocument = {
slug: '',
title: '',
description: '',
hue: 'gray',
icon: 'cube',
}

export function BundleForm(props: {
onChange: (params: Partial<BundleDocument>) => void
value: Partial<BundleDocument>
onChange: (params: FormBundleDocument) => void
value: FormBundleDocument
}): JSX.Element {
const {onChange, value} = props
const {title, description, icon, hue, publishedAt} = value
// derive the action from whether the initial value prop has a slug
// only editing existing bundles will provide a value.slug
const {current: action} = useRef(value.slug ? 'edit' : 'create')
const isEditing = action === 'edit'
const {t} = useTranslation()

const dateFormatter = useDateTimeFormat()

// todo: figure out if these are needed
const [titleErrors, setTitleErrors] = useState<FormNodeValidation[]>([])
const [dateErrors, setDateErrors] = useState<FormNodeValidation[]>([])

Expand All @@ -60,22 +58,15 @@ export function BundleForm(props: {
[icon, hue],
)

const generateSlugFromTitle = useGetBundleSlug()

const handleBundleTitleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const pickedTitle = event.target.value
const {slug: existingSlug} = value

const nextSlug = (isEditing && existingSlug) || generateSlugFromTitle(pickedTitle)

onChange({
...value,
title: pickedTitle,
slug: nextSlug,
})
},
[generateSlugFromTitle, isEditing, onChange, value],
[onChange, value],
)

const handleBundleDescriptionChange = useCallback(
Expand Down
Loading

0 comments on commit 3eb6403

Please sign in to comment.