@@ -9,6 +9,11 @@ import { VersionSelector } from 'client/versionSelector/VersionSelector';
9
9
import { ContentView } from '../contentView/ContentView' ;
10
10
import { formatTimestamp } from '@common/shared/timestamp' ;
11
11
import { EmptyState } from '@common/shared/EmptyState/EmptyState' ;
12
+ import {
13
+ setCachedVersionSelector ,
14
+ getCachedVersionSelector ,
15
+ clearCachedVersionSelector ,
16
+ } from 'client/versionSelector/VersionSelectorCache' ;
12
17
13
18
import style from './Content.module.css' ;
14
19
@@ -18,15 +23,12 @@ const getDefaultView = (isWebpage: boolean, hasAttachment: boolean): ViewVariant
18
23
return undefined ;
19
24
} ;
20
25
21
- const updateContentUrl = ( nodeId : string , locale : string , versionId ?: string ) => {
22
- const newUrl = `${ xpArchiveConfig . basePath } /${ nodeId } /${ locale } /${ versionId ?? '' } ` ;
23
- window . history . pushState ( { } , '' , newUrl ) ;
24
- } ;
25
-
26
26
export const Content = ( ) => {
27
27
const { selectedContentId, selectedLocale, selectedVersion, setSelectedVersion } =
28
28
useAppState ( ) ;
29
29
30
+ const prevContentIdRef = React . useRef ( selectedContentId ) ;
31
+
30
32
useEffect ( ( ) => {
31
33
const pathSegments = window . location . pathname . split ( '/' ) ;
32
34
if ( pathSegments . length >= 5 ) {
@@ -43,21 +45,58 @@ export const Content = () => {
43
45
} ) ;
44
46
45
47
useEffect ( ( ) => {
46
- if ( selectedVersion ) {
47
- updateContentUrl ( selectedContentId ?? '' , selectedLocale , selectedVersion ) ;
48
- } else if ( data ?. versions ?. [ 0 ] ) {
49
- const latestVersionId = data . versions [ 0 ] . versionId ;
50
- setSelectedVersion ( latestVersionId ) ;
51
- updateContentUrl ( selectedContentId ?? '' , selectedLocale , latestVersionId ) ;
48
+ const versionId = selectedVersion ?? data ?. versions ?. [ 0 ] ?. versionId ;
49
+ if ( versionId ) {
50
+ if ( ! selectedVersion ) {
51
+ setSelectedVersion ( versionId ) ;
52
+ }
53
+ const newUrl = `${ xpArchiveConfig . basePath } /${ selectedContentId } /${ selectedLocale } /${ versionId } ` ;
54
+ window . history . pushState ( { } , '' , newUrl ) ;
52
55
}
53
56
} , [ data , selectedContentId , selectedLocale , selectedVersion ] ) ;
54
57
55
- const isWebpage = ! ! data ?. html && ! data . json . attachment ;
56
- const hasAttachment = ! ! data ?. json . attachment ;
58
+ const isWebpage = ! ! data ?. html && ! data ? .json ? .attachment ;
59
+ const hasAttachment = ! ! data ?. json ? .attachment ;
57
60
const [ selectedView , setSelectedView ] = useState < ViewVariant | undefined > (
58
61
getDefaultView ( isWebpage , hasAttachment )
59
62
) ;
60
- const [ isVersionPanelOpen , setIsVersionPanelOpen ] = useState ( false ) ;
63
+
64
+ const [ versionSelectorCache , setVersionSelectorCache ] = useState ( ( ) => {
65
+ const cache = getCachedVersionSelector ( selectedContentId ?? '' ) ;
66
+ return {
67
+ component : cache . component ,
68
+ versions : cache . versions ,
69
+ isOpen : cache . isOpen ,
70
+ } ;
71
+ } ) ;
72
+
73
+ const [ cachedDisplayData , setCachedDisplayData ] = useState ( {
74
+ displayName : '' ,
75
+ path : '' ,
76
+ } ) ;
77
+
78
+ useEffect ( ( ) => {
79
+ if ( prevContentIdRef . current && prevContentIdRef . current !== selectedContentId ) {
80
+ clearCachedVersionSelector ( prevContentIdRef . current ) ;
81
+ }
82
+
83
+ if ( data ?. versions && selectedContentId ) {
84
+ setVersionSelectorCache ( ( prev ) => ( {
85
+ component : null ,
86
+ versions : data . versions ,
87
+ isOpen : prev . isOpen ,
88
+ } ) ) ;
89
+
90
+ if ( data . json ?. displayName || data . json ?. _path ) {
91
+ setCachedDisplayData ( {
92
+ displayName : data . json . displayName || '' ,
93
+ path : data . json . _path || '' ,
94
+ } ) ;
95
+ }
96
+ }
97
+
98
+ prevContentIdRef . current = selectedContentId ;
99
+ } , [ selectedContentId , data ?. versions , data ?. json ] ) ;
61
100
62
101
useEffect ( ( ) => {
63
102
setSelectedView ( getDefaultView ( isWebpage , hasAttachment ) ) ;
@@ -68,6 +107,15 @@ export const Content = () => {
68
107
} `;
69
108
70
109
const getVersionDisplay = ( ) => {
110
+ if ( selectedVersion && versionSelectorCache . versions . length > 0 ) {
111
+ const cachedVersion = versionSelectorCache . versions . find (
112
+ ( v ) => v . versionId === selectedVersion
113
+ ) ;
114
+ if ( cachedVersion ?. timestamp ) {
115
+ return formatTimestamp ( cachedVersion . timestamp ) ;
116
+ }
117
+ }
118
+
71
119
if ( selectedVersion && data ?. versions ) {
72
120
return formatTimestamp (
73
121
data . versions . find ( ( v ) => v . versionId === selectedVersion ) ?. timestamp ?? ''
@@ -91,15 +139,49 @@ export const Content = () => {
91
139
variant = { 'secondary' }
92
140
icon = { < SidebarRightIcon /> }
93
141
iconPosition = { 'right' }
94
- onClick = { ( ) => setIsVersionPanelOpen ( true ) }
142
+ onClick = { ( ) => {
143
+ setVersionSelectorCache ( ( prev ) => ( {
144
+ ...prev ,
145
+ isOpen : true ,
146
+ } ) ) ;
147
+ } }
95
148
>
96
149
{ getVersionDisplay ( ) }
97
150
</ Button >
98
- < VersionSelector
99
- versions = { data ?. versions || [ ] }
100
- isOpen = { isVersionPanelOpen }
101
- onClose = { ( ) => setIsVersionPanelOpen ( false ) }
102
- />
151
+
152
+ { versionSelectorCache . component
153
+ ? versionSelectorCache . component
154
+ : ( ( ) => {
155
+ const versionSelectorVersions =
156
+ versionSelectorCache . versions . length > 0
157
+ ? versionSelectorCache . versions
158
+ : data ?. versions || [ ] ;
159
+
160
+ const handleClose = ( ) => {
161
+ setVersionSelectorCache ( ( prev ) => ( {
162
+ ...prev ,
163
+ isOpen : false ,
164
+ } ) ) ;
165
+ } ;
166
+
167
+ const handleMount = ( component : React . ReactNode ) => {
168
+ setCachedVersionSelector (
169
+ selectedContentId ?? '' ,
170
+ component ,
171
+ versionSelectorVersions ,
172
+ versionSelectorCache . isOpen
173
+ ) ;
174
+ } ;
175
+
176
+ return (
177
+ < VersionSelector
178
+ versions = { versionSelectorVersions }
179
+ isOpen = { versionSelectorCache . isOpen }
180
+ onClose = { handleClose }
181
+ onMount = { handleMount }
182
+ />
183
+ ) ;
184
+ } ) ( ) }
103
185
</ div >
104
186
< div className = { style . viewSelector } >
105
187
< Label className = { style . label } > Visning</ Label >
@@ -128,10 +210,10 @@ export const Content = () => {
128
210
129
211
< div className = { style . titleAndUrl } >
130
212
< Heading size = { 'medium' } level = { '2' } >
131
- { data ?. json . displayName ?? ' '}
213
+ { data ?. json ? .displayName || cachedDisplayData . displayName || 'Laster... '}
132
214
</ Heading >
133
215
< div className = { style . url } >
134
- < Detail > { data ?. json . _path ?? '' } </ Detail >
216
+ < Detail > { data ?. json ? ._path || cachedDisplayData . path || '' } </ Detail >
135
217
</ div >
136
218
</ div >
137
219
</ div >
0 commit comments