Skip to content

Commit 5a26381

Browse files
feat(structure): History UI updates (#7462)
Merge draft changes into the publish action. Moves revision into the history panel Co-authored-by: RitaDias <[email protected]>
1 parent 3b615f9 commit 5a26381

29 files changed

+1343
-362
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export {DateInput, type DateInputProps} from './DateInput'
22
export {DateTimeInput, type DateTimeInputProps} from './DateTimeInput'
3+
export {getCalendarLabels} from './utils'

packages/sanity/src/core/form/inputs/DateInputs/utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export function isValidDate(date: Date): boolean {
44
return date instanceof Date && !isNaN(date.valueOf())
55
}
66

7+
/**
8+
* @internal
9+
*/
710
export function getCalendarLabels(
811
t: (key: string, values?: Record<string, unknown>) => string,
912
): CalendarLabels {

packages/sanity/src/core/i18n/bundles/studio.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ export const studioLocaleStrings = defineLocalesResources('studio', {
197197
'calendar.weekday-names.short.wednesday': 'Wed',
198198

199199
/** Label for the close button label in Review Changes pane */
200-
'changes.action.close-label': 'Close review changes',
200+
'changes.action.close-label': 'Close history',
201201
/** Cancel label for revert button prompt action */
202202
'changes.action.revert-all-cancel': 'Cancel',
203203
/** Revert all confirm label for revert button action - used on prompt button + review changes pane */
@@ -313,7 +313,7 @@ export const studioLocaleStrings = defineLocalesResources('studio', {
313313
/** Label for when the action of the change was a removal, eg a field was cleared, an array item was removed, an asset was deselected or similar */
314314
'changes.removed-label': 'Removed',
315315
/** Title for the Review Changes pane */
316-
'changes.title': 'Review changes',
316+
'changes.title': 'History',
317317

318318
/** --- Common components --- */
319319
/** Tooltip text for context menu buttons */
@@ -359,6 +359,8 @@ export const studioLocaleStrings = defineLocalesResources('studio', {
359359
'document-status.not-published': 'Not published',
360360
/** Label to show in the document footer indicating the published date of the document */
361361
'document-status.published': 'Published {{date}}',
362+
/** Label to show in the document footer indicating the revision from date of the document */
363+
'document-status.revision-from': 'Revision from <em>{{date}}</em>',
362364

363365
/** The value of the <code>_key</code> property must be a unique string. */
364366
'form.error.duplicate-keys-alert.details.additional-description':
@@ -1592,7 +1594,8 @@ export const studioLocaleStrings = defineLocalesResources('studio', {
15921594
'sheet-list.select-fields': 'Select up to 5 field types',
15931595
/** Accessibility label for the navbar status button */
15941596
'status-button.aria-label': 'Configuration status',
1595-
1597+
/** Title for the changes tooltip in the history inspector*/
1598+
'timeline.changes.title': 'Changes by',
15961599
/** Description for error when the timeline for the given document can't be loaded */
15971600
'timeline.error.load-document-changes-description':
15981601
'Document history transactions have not been affected.',
@@ -1656,7 +1659,7 @@ export const studioLocaleStrings = defineLocalesResources('studio', {
16561659
* Label for determining since which version the changes for timeline menu dropdown are showing.
16571660
* Receives the time label as a parameter (`timestamp`).
16581661
*/
1659-
'timeline.since': 'Since: {{timestamp, datetime}}',
1662+
'timeline.since': '{{timestamp, datetime}}',
16601663
/** Label for missing change version for timeline menu dropdown are showing */
16611664
'timeline.since-version-missing': 'Since: unknown version',
16621665
/** Aria label for the action buttons in the PTE toolbar */

packages/sanity/src/core/store/_legacy/history/history/TimelineController.ts

+5
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ export class TimelineController {
126126
return this._revTime && typeof this._revTime === 'object' ? this._revTime : null
127127
}
128128

129+
get isLoading(): boolean {
130+
return this._isRunning
131+
}
132+
129133
get realRevChunk(): Chunk {
130134
return this.revTime || this.timeline.lastChunk()
131135
}
@@ -258,6 +262,7 @@ export class TimelineController {
258262
!this._isSuspended
259263

260264
if (!shouldFetchMore) {
265+
this._isRunning = false
261266
return
262267
}
263268

packages/sanity/src/core/store/_legacy/history/useTimelineStore.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ export function useTimelineStore({
194194
findRangeForSince: (chunk: Chunk) => controller.findRangeForNewSince(chunk),
195195
loadMore: () => {
196196
controller.setLoadMore(true)
197-
timelineStateRef.current.isLoading = true
198197
},
199198
getSnapshot: () => timelineStateRef.current,
200199
subscribe: (callback: () => void) => {
@@ -217,7 +216,7 @@ export function useTimelineStore({
217216
return {
218217
chunks,
219218
diff: innerController.sinceTime ? innerController.currentObjectDiff() : null,
220-
isLoading: false,
219+
isLoading: innerController.isLoading,
221220
isPristine: timelineReady ? chunks.length === 0 && hasMoreChunks === false : null,
222221
hasMoreChunks: !innerController.timeline.reachedEarliestEntry,
223222
lastNonDeletedRevId: lastNonDeletedChunk?.[0]?.id,

packages/sanity/src/structure/documentActions/HistoryRestoreAction.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {RestoreIcon} from '@sanity/icons'
1+
import {RevertIcon} from '@sanity/icons'
22
import {useCallback, useEffect, useMemo, useRef, useState} from 'react'
33
import {
44
type DocumentActionComponent,
@@ -66,14 +66,14 @@ export const HistoryRestoreAction: DocumentActionComponent = ({id, type, revisio
6666

6767
return {
6868
label: t('action.restore.label'),
69-
color: 'primary',
69+
tone: 'caution',
7070
onHandle: handle,
7171
title: t(
7272
isRevisionInitial
7373
? 'action.restore.disabled.cannot-restore-initial'
7474
: 'action.restore.tooltip',
7575
),
76-
icon: RestoreIcon,
76+
icon: RevertIcon,
7777
dialog,
7878
disabled: isRevisionInitial,
7979
}

packages/sanity/src/structure/documentActions/PublishAction.tsx

+2-7
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,14 @@ export const PublishAction: DocumentActionComponent = (props) => {
111111

112112
useEffect(() => {
113113
const didPublish = publishState === 'publishing' && !hasDraft
114-
if (didPublish) {
115-
if (changesOpen) {
116-
// Re-open the panel
117-
onHistoryOpen()
118-
}
119-
}
114+
120115
const nextState = didPublish ? 'published' : null
121116
const delay = didPublish ? 200 : 4000
122117
const timer = setTimeout(() => {
123118
setPublishState(nextState)
124119
}, delay)
125120
return () => clearTimeout(timer)
126-
}, [changesOpen, publishState, hasDraft, onHistoryOpen])
121+
}, [changesOpen, publishState, hasDraft])
127122

128123
const telemetry = useTelemetry()
129124

packages/sanity/src/structure/i18n/resources.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ const structureLocaleStrings = defineLocalesResources('structure', {
6969
/** Tooltip when publish button is waiting for validation and async tasks to complete.*/
7070
'action.publish.waiting': 'Waiting for tasks to finish before publishing',
7171

72-
/** Message prompting the user to confirm that they want to restore to an earlier version*/
72+
/** Message prompting the user to confirm that they want to restore to an earlier revision*/
7373
'action.restore.confirm.message': 'Are you sure you want to restore this document?',
74-
/** Fallback tooltip for when user is looking at the initial version */
75-
'action.restore.disabled.cannot-restore-initial': "You can't restore to the initial version",
74+
/** Fallback tooltip for when user is looking at the initial revision */
75+
'action.restore.disabled.cannot-restore-initial': "You can't restore to the initial revision",
7676

7777
/** Label for the "Restore" document action */
78-
'action.restore.label': 'Restore',
78+
'action.restore.label': 'Revert to revision',
7979
/** Default tooltip for the action */
80-
'action.restore.tooltip': 'Restore to this version',
80+
'action.restore.tooltip': 'Restore to this revision',
8181

8282
/** Tooltip when action is disabled because the document is not already published */
8383
'action.unpublish.disabled.not-published': 'This document is not published',
@@ -90,7 +90,7 @@ const structureLocaleStrings = defineLocalesResources('structure', {
9090
'This document has live edit enabled and cannot be unpublished',
9191

9292
/** The text for the restore button on the deleted document banner */
93-
'banners.deleted-document-banner.restore-button.text': 'Restore most recent version',
93+
'banners.deleted-document-banner.restore-button.text': 'Restore most recent revision',
9494
/** The text content for the deleted document banner */
9595
'banners.deleted-document-banner.text': 'This document has been deleted.',
9696
/** The text content for the deprecated document type banner */
@@ -147,7 +147,14 @@ const structureLocaleStrings = defineLocalesResources('structure', {
147147
'buttons.split-pane-close-button.title': 'Close split pane',
148148
/** The title for the close group button on the split pane on the document panel header */
149149
'buttons.split-pane-close-group-button.title': 'Close pane group',
150-
150+
/** The label used in the changes inspector for the from selector */
151+
'changes.from.label': 'From',
152+
/* The label for the history tab in the changes inspector*/
153+
'changes.tab.history': 'History',
154+
/* The label for the review tab in the changes inspector*/
155+
'changes.tab.review-changes': 'Review changes',
156+
/** The label used in the changes inspector for the to selector */
157+
'changes.to.label': 'To',
151158
/** The text in the "Cancel" button in the confirm delete dialog that cancels the action and closes the dialog */
152159
'confirm-delete-dialog.cancel-button.text': 'Cancel',
153160
/** Used in `confirm-delete-dialog.cdr-summary.title` */
@@ -378,7 +385,7 @@ const structureLocaleStrings = defineLocalesResources('structure', {
378385
'<Strong>{{title}}</Strong> was restored',
379386
/** The text when an unpublish operation succeeded */
380387
'panes.document-operation-results.operation-success_unpublish':
381-
'<Strong>{{title}}</Strong> was unpublished. A draft has been created from the latest published version.',
388+
'<Strong>{{title}}</Strong> was unpublished. A draft has been created from the latest published revision.',
382389
/** The document title shown when document title is "undefined" in operation message */
383390
'panes.document-operation-results.operation-undefined-title': 'Untitled',
384391
/** The title of the reconnecting toast */
@@ -467,6 +474,15 @@ const structureLocaleStrings = defineLocalesResources('structure', {
467474
'structure-error.reload-button.text': 'Reload',
468475
/** Labels the structure path of the structure error screen */
469476
'structure-error.structure-path.label': 'Structure path',
477+
478+
/** The aria label for the menu button in the timeline item */
479+
'timeline-item.menu-button.aria-label': 'Open action menu',
480+
/** The text for the tooltip in menu button the timeline item */
481+
'timeline-item.menu-button.tooltip': 'Actions',
482+
/** The text for the collapse action in the timeline item menu */
483+
'timeline-item.menu.action-collapse': 'Collapse',
484+
/** The text for the expand action in the timeline item menu */
485+
'timeline-item.menu.action-expand': 'Expand',
470486
})
471487

472488
/**

packages/sanity/src/structure/panes/document/DocumentPaneProvider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ export const DocumentPaneProvider = memo((props: DocumentPaneProviderProps) => {
390390
}
391391

392392
if (resolvedChangesInspector) {
393-
openInspector(resolvedChangesInspector.name)
393+
openInspector(resolvedChangesInspector.name, {changesInspectorTab: 'review'})
394394
}
395395
}, [features.reviewChanges, openInspector, resolvedChangesInspector])
396396

packages/sanity/src/structure/panes/document/document-layout/DocumentLayout.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {type Path} from 'sanity-diff-patch'
2525
import {styled} from 'styled-components'
2626

2727
import {TooltipDelayGroupProvider} from '../../../../ui-components'
28-
import {Pane, PaneFooter, usePane, usePaneLayout} from '../../../components'
28+
import {Pane, PaneFooter, usePane, usePaneLayout, usePaneRouter} from '../../../components'
2929
import {DOCUMENT_PANEL_PORTAL_ELEMENT} from '../../../constants'
3030
import {structureLocaleNamespace} from '../../../i18n'
3131
import {useStructureTool} from '../../../useStructureTool'
@@ -82,7 +82,7 @@ export function DocumentLayout() {
8282
schemaType,
8383
value,
8484
} = useDocumentPane()
85-
85+
const {params: paneParams} = usePaneRouter()
8686
const {features} = useStructureTool()
8787
const {t} = useTranslation(structureLocaleNamespace)
8888
const {collapsed: layoutCollapsed} = usePaneLayout()
@@ -228,7 +228,7 @@ export function DocumentLayout() {
228228
<Flex direction="column" flex={1} height={layoutCollapsed ? undefined : 'fill'}>
229229
<StyledChangeConnectorRoot
230230
data-testid="change-connector-root"
231-
isReviewChangesOpen={changesOpen}
231+
isReviewChangesOpen={changesOpen && paneParams?.changesInspectorTab === 'review'}
232232
onOpenReviewChanges={onHistoryOpen}
233233
onSetFocus={onConnectorSetFocus}
234234
>

packages/sanity/src/structure/panes/document/documentPanel/header/DocumentPanelHeader.tsx

+1-12
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@ import {
1010
useMemo,
1111
useState,
1212
} from 'react'
13-
import {
14-
type DocumentActionDescription,
15-
useFieldActions,
16-
useTimelineSelector,
17-
useTranslation,
18-
} from 'sanity'
13+
import {type DocumentActionDescription, useFieldActions, useTranslation} from 'sanity'
1914

2015
import {Button, TooltipDelayGroupProvider} from '../../../../../ui-components'
2116
import {
@@ -33,7 +28,6 @@ import {type PaneMenuItem} from '../../../../types'
3328
import {useStructureTool} from '../../../../useStructureTool'
3429
import {ActionDialogWrapper, ActionMenuListItem} from '../../statusBar/ActionMenuButton'
3530
import {isRestoreAction} from '../../statusBar/DocumentStatusBarActions'
36-
import {TimelineMenu} from '../../timeline'
3731
import {useDocumentPane} from '../../useDocumentPane'
3832
import {DocumentHeaderTabs} from './DocumentHeaderTabs'
3933
import {DocumentHeaderTitle} from './DocumentHeaderTitle'
@@ -57,7 +51,6 @@ export const DocumentPanelHeader = memo(
5751
onPaneSplit,
5852
menuItemGroups,
5953
schemaType,
60-
timelineStore,
6154
connectionState,
6255
views,
6356
unstable_languageFilter,
@@ -84,9 +77,6 @@ export const DocumentPanelHeader = memo(
8477
const contextMenuNodes = useMemo(() => menuNodes.filter(isNotMenuNodeButton), [menuNodes])
8578
const showTabs = views.length > 1
8679

87-
// Subscribe to external timeline state changes
88-
const rev = useTimelineSelector(timelineStore, (state) => state.revTime)
89-
9080
const {collapsed, isLast} = usePane()
9181
// Prevent focus if this is the last (non-collapsed) pane.
9282
const tabIndex = isLast && !collapsed ? -1 : 0
@@ -152,7 +142,6 @@ export const DocumentPanelHeader = memo(
152142
/>
153143
)
154144
}
155-
subActions={<TimelineMenu chunk={rev} mode="rev" placement="bottom-end" />}
156145
actions={
157146
<Flex align="center" gap={1}>
158147
{unstable_languageFilter.length > 0 && (

0 commit comments

Comments
 (0)