1
1
import { AddIcon , ChevronDownIcon , EarthGlobeIcon } from '@sanity/icons'
2
- import {
3
- Box ,
4
- type ButtonMode ,
5
- Card ,
6
- Container ,
7
- Flex ,
8
- Inline ,
9
- Stack ,
10
- Text ,
11
- useMediaIndex ,
12
- } from '@sanity/ui'
2
+ import { Box , type ButtonMode , Card , Flex , Inline , Stack , Text , useMediaIndex } from '@sanity/ui'
13
3
import { format , isSameDay } from 'date-fns'
14
4
import { AnimatePresence , motion } from 'framer-motion'
15
5
import { type MouseEventHandler , useCallback , useEffect , useMemo , useRef , useState } from 'react'
@@ -36,6 +26,7 @@ import {getReleaseDefaults} from '../../util/util'
36
26
import { ReleaseMenuButton } from '../components/ReleaseMenuButton/ReleaseMenuButton'
37
27
import { Table , type TableRowProps } from '../components/Table/Table'
38
28
import { type TableSort } from '../components/Table/TableProvider'
29
+ import { ReleaseIllustration } from '../resources/ReleaseIllustration'
39
30
import { CalendarPopover } from './CalendarPopover'
40
31
import {
41
32
DATE_SEARCH_PARAM_KEY ,
@@ -108,6 +99,7 @@ export function ReleasesOverview() {
108
99
109
100
const hasReleases = releases . length > 0 || archivedReleases . length > 0
110
101
const loadingOrHasReleases = loading || hasReleases
102
+ const hasNoReleases = ! loading && ! hasReleases
111
103
112
104
const tableReleases = useMemo < TableRelease [ ] > ( ( ) => {
113
105
if ( ! hasReleases || ! releasesMetadata ) return [ ]
@@ -259,7 +251,6 @@ export function ReleasesOverview() {
259
251
}
260
252
onClick = { handleOnClickCreateRelease }
261
253
text = { tCore ( 'release.action.create-new' ) }
262
- size = "large"
263
254
tooltipProps = { {
264
255
disabled : hasCreatePermission === true ,
265
256
content : tCore ( 'release.action.permission.error' ) ,
@@ -352,78 +343,112 @@ export function ReleasesOverview() {
352
343
[ releaseGroupMode , t ] ,
353
344
)
354
345
346
+ const NoRelease = ( ) => {
347
+ return (
348
+ < Flex
349
+ direction = "column"
350
+ flex = { 1 }
351
+ justify = { hasNoReleases ? 'center' : 'flex-start' }
352
+ align = { hasNoReleases ? 'center' : 'flex-start' }
353
+ style = { { position : 'relative' } }
354
+ >
355
+ < Flex gap = { 3 } direction = "column" style = { { maxWidth : '300px' } } >
356
+ < ReleaseIllustration />
357
+ < Text as = "h1" size = { 1 } weight = "semibold" data-testid = "no-releases-info-text" >
358
+ { t ( 'overview.title' ) }
359
+ </ Text >
360
+ < Text size = { 1 } muted >
361
+ { t ( 'overview.description' ) }
362
+ </ Text >
363
+ < Inline space = { 2 } >
364
+ { createReleaseButton }
365
+ < Button
366
+ as = "a"
367
+ href = "https://www.sanity.io/docs/content-releases"
368
+ target = "_blank"
369
+ mode = "ghost"
370
+ onClick = { handleOnClickCreateRelease }
371
+ text = { t ( 'overview.action.documentation' ) }
372
+ />
373
+ </ Inline >
374
+ </ Flex >
375
+ </ Flex >
376
+ )
377
+ }
378
+
355
379
return (
356
380
< Flex direction = "row" flex = { 1 } style = { { height : '100%' } } >
357
381
< Flex flex = { 1 } >
358
382
{ showCalendar && renderCalendarFilter }
359
- < Flex direction = "column" flex = { 1 } style = { { position : 'relative' } } >
360
- < Card flex = "none" padding = { 3 } >
361
- < Flex align = "center" flex = { 1 } gap = { 3 } >
362
- < Inline >
363
- { ! showCalendar && < CalendarPopover content = { renderCalendarFilter } /> }
364
- < Stack padding = { 2 } space = { 4 } >
365
- < Text as = "h1" size = { 1 } weight = "semibold" >
366
- { t ( 'overview.title' ) }
367
- </ Text >
368
- </ Stack >
369
- </ Inline >
370
-
371
- < Flex flex = { 1 } gap = { 1 } >
372
- { loadingOrHasReleases &&
373
- ( releaseFilterDate ? (
374
- < DateFilterButton filterDate = { releaseFilterDate } onClear = { clearFilterDate } />
375
- ) : (
376
- currentArchivedPicker
377
- ) ) }
378
- </ Flex >
379
- < Flex flex = "none" gap = { 2 } >
380
- < Button
381
- icon = { EarthGlobeIcon }
382
- iconRight = { ChevronDownIcon }
383
- mode = "bleed"
384
- size = "large"
385
- text = { `${ timeZone . abbreviation } (${ timeZone . namePretty } )` }
386
- onClick = { dialogTimeZoneShow }
387
- />
388
- { DialogTimeZone && < DialogTimeZone { ...dialogProps } /> }
389
- { loadingOrHasReleases && createReleaseButton }
390
- </ Flex >
383
+
384
+ { hasNoReleases ? (
385
+ < NoRelease />
386
+ ) : (
387
+ < >
388
+ < Flex direction = "column" flex = { 1 } style = { { position : 'relative' } } >
389
+ < Card flex = "none" padding = { 3 } >
390
+ < Flex align = "center" flex = { 1 } gap = { 3 } >
391
+ < Inline >
392
+ { ! showCalendar && < CalendarPopover content = { renderCalendarFilter } /> }
393
+ < Stack padding = { 2 } space = { 4 } >
394
+ < Text as = "h1" size = { 1 } weight = "semibold" >
395
+ { t ( 'overview.title' ) }
396
+ </ Text >
397
+ </ Stack >
398
+ </ Inline >
399
+
400
+ < Flex flex = { 1 } gap = { 1 } >
401
+ { loadingOrHasReleases &&
402
+ ( releaseFilterDate ? (
403
+ < DateFilterButton
404
+ filterDate = { releaseFilterDate }
405
+ onClear = { clearFilterDate }
406
+ />
407
+ ) : (
408
+ currentArchivedPicker
409
+ ) ) }
410
+ </ Flex >
411
+ < Flex flex = "none" gap = { 2 } >
412
+ < Button
413
+ icon = { EarthGlobeIcon }
414
+ iconRight = { ChevronDownIcon }
415
+ mode = "bleed"
416
+ size = "large"
417
+ text = { `${ timeZone . abbreviation } (${ timeZone . namePretty } )` }
418
+ onClick = { dialogTimeZoneShow }
419
+ />
420
+ { DialogTimeZone && < DialogTimeZone { ...dialogProps } /> }
421
+ { loadingOrHasReleases && createReleaseButton }
422
+ </ Flex >
423
+ </ Flex >
424
+ </ Card >
425
+ < Box ref = { scrollContainerRef } marginTop = { 3 } overflow = { 'auto' } >
426
+ { ( loading || hasReleases ) && (
427
+ < Table < TableRelease >
428
+ // for resetting filter and sort on table when filer changed
429
+ key = { releaseFilterDate ? 'by_date' : releaseGroupMode }
430
+ defaultSort = {
431
+ releaseGroupMode === 'archived'
432
+ ? DEFAULT_ARCHIVED_RELEASES_OVERVIEW_SORT
433
+ : DEFAULT_RELEASES_OVERVIEW_SORT
434
+ }
435
+ loading = { loadingTableData }
436
+ data = { filteredReleases }
437
+ columnDefs = { tableColumns }
438
+ emptyState = { t ( 'no-releases' ) }
439
+ // eslint-disable-next-line @sanity/i18n/no-attribute-string-literals
440
+ rowId = "_id"
441
+ rowActions = { renderRowActions }
442
+ rowProps = { getRowProps }
443
+ scrollContainerRef = { scrollContainerRef }
444
+ hideTableInlinePadding
445
+ />
446
+ ) }
447
+ </ Box >
391
448
</ Flex >
392
- </ Card >
393
- < Box ref = { scrollContainerRef } marginTop = { 3 } overflow = { 'auto' } >
394
- { ! loading && ! hasReleases ? (
395
- < Container style = { { margin : 0 } } width = { 0 } >
396
- < Stack space = { 5 } padding = { 4 } >
397
- < Text data-testid = "no-releases-info-text" muted size = { 2 } >
398
- { t ( 'overview.description' ) }
399
- </ Text >
400
- < Box > { createReleaseButton } </ Box >
401
- </ Stack >
402
- </ Container >
403
- ) : (
404
- < Table < TableRelease >
405
- // for resetting filter and sort on table when filer changed
406
- key = { releaseFilterDate ? 'by_date' : releaseGroupMode }
407
- defaultSort = {
408
- releaseGroupMode === 'archived'
409
- ? DEFAULT_ARCHIVED_RELEASES_OVERVIEW_SORT
410
- : DEFAULT_RELEASES_OVERVIEW_SORT
411
- }
412
- loading = { loadingTableData }
413
- data = { filteredReleases }
414
- columnDefs = { tableColumns }
415
- emptyState = { t ( 'no-releases' ) }
416
- // eslint-disable-next-line @sanity/i18n/no-attribute-string-literals
417
- rowId = "_id"
418
- rowActions = { renderRowActions }
419
- rowProps = { getRowProps }
420
- scrollContainerRef = { scrollContainerRef }
421
- hideTableInlinePadding
422
- />
423
- ) }
424
- </ Box >
425
- { renderCreateReleaseDialog ( ) }
426
- </ Flex >
449
+ { renderCreateReleaseDialog ( ) }
450
+ </ >
451
+ ) }
427
452
</ Flex >
428
453
</ Flex >
429
454
)
0 commit comments