Skip to content

Commit e69cb3d

Browse files
committed
tree remove cache when edit item
1 parent bb87a7d commit e69cb3d

File tree

4 files changed

+87
-61
lines changed

4 files changed

+87
-61
lines changed

apps/sensenet/src/components/app-providers.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { DialogProvider } from './dialogs/dialog-provider'
2626

2727
import { GridLoadingProvider } from './grid/Providers/GridLoadingProvider'
2828
import { snInjector } from './sn-injector'
29+
import ExpandedItemsProvider from './tree/Contexts/ExpandedItemsProvider'
2930
import { TreeLoadingProvider } from './tree/Contexts/TreeLoadingProvider'
3031

3132
export type AppProvidersProps = {
@@ -80,7 +81,9 @@ export default function AppProviders({ children }: AppProvidersProps) {
8081
<ShareProvider>
8182
<ISAuthProvider>
8283
<ResponsiveContextProvider>
83-
<DialogProvider>{children}</DialogProvider>
84+
<ExpandedItemsProvider>
85+
<DialogProvider>{children}</DialogProvider>
86+
</ExpandedItemsProvider>
8487
</ResponsiveContextProvider>
8588
</ISAuthProvider>
8689
</ShareProvider>
@@ -90,7 +93,9 @@ export default function AppProviders({ children }: AppProvidersProps) {
9093
<ShareProvider>
9194
<SNAuthProvider>
9295
<ResponsiveContextProvider>
93-
<DialogProvider>{children}</DialogProvider>
96+
<ExpandedItemsProvider>
97+
<DialogProvider>{children}</DialogProvider>
98+
</ExpandedItemsProvider>
9499
</ResponsiveContextProvider>
95100
</SNAuthProvider>
96101
</ShareProvider>

apps/sensenet/src/components/content/Explore.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { DocumentViewer } from '../document-viewer'
2323
import { EditBinary } from '../edit/edit-binary'
2424
import { contentColumnDefs } from '../grid/Cols/ColumnDefs.'
2525
import { Grid } from '../grid/Grid'
26-
import ExpandedItemsProvider from '../tree/Contexts/ExpandedItemsProvider'
2726
import { SimpleTree } from '../tree/simpletree'
2827
import { BrowseView, EditView, ImageView, NewView, PermissionView, VersionView } from '../view-controls'
2928
import WopiPage from '../wopi-page'
@@ -298,23 +297,21 @@ export function Explore({
298297

299298
<div className={`${classes.treeAndDatagridWrapper} leftTree theme-${theme.palette.type} `}>
300299
{hasTree && (
301-
<ExpandedItemsProvider>
302-
<div className={classes.simpleTree}>
303-
<div className={classes.resizeButton} onMouseDown={handleMouseDown}>
304-
<div className={classes.symbol}>&#8596;</div>
305-
</div>
306-
<SimpleTree
307-
onItemClick={(item) => {
308-
onNavigate(item)
309-
}}
310-
parentPath={PathHelper.isAncestorOf(rootPath, currentPath) ? rootPath : currentPath}
311-
activeItemPath={currentPath}
312-
loadSettings={loadTreeSettings}
313-
onNavigate={onNavigate}
314-
rootLoaded={false}
315-
/>
300+
<div className={classes.simpleTree}>
301+
<div className={classes.resizeButton} onMouseDown={handleMouseDown}>
302+
<div className={classes.symbol}>&#8596;</div>
316303
</div>
317-
</ExpandedItemsProvider>
304+
<SimpleTree
305+
onItemClick={(item) => {
306+
onNavigate(item)
307+
}}
308+
parentPath={PathHelper.isAncestorOf(rootPath, currentPath) ? rootPath : currentPath}
309+
activeItemPath={currentPath}
310+
loadSettings={loadTreeSettings}
311+
onNavigate={onNavigate}
312+
rootLoaded={false}
313+
/>
314+
</div>
318315
)}
319316
<div className={classes.exploreContainer}>{renderContent()}</div>
320317
</div>

apps/sensenet/src/components/tree/Contexts/ExpandedItemsProvider.tsx

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { ODataCollectionResponse } from '@sensenet/client-core'
21
import { GenericContent } from '@sensenet/default-content-types'
32
import { useRepository } from '@sensenet/hooks-react'
4-
import React, { createContext, ReactNode, useEffect, useRef, useState } from 'react'
3+
import React, { createContext, ReactNode, useRef, useState } from 'react'
54
// Meghatározzuk a Context típusát: egy string tömb és egy setter függvény
65
type ExpandItemsContextType = [
76
Set<string>,
@@ -10,70 +9,80 @@ type ExpandItemsContextType = [
109
React.Dispatch<React.SetStateAction<Set<string>>>,
1110
(path: string) => Promise<GenericContent[] | undefined>,
1211
React.Dispatch<React.SetStateAction<number>>,
12+
(path: string) => void,
1313
]
1414

15-
// Létrehozzuk a Context-et alapértelmezett értékekkel
1615
export const ExpandItemsContext = createContext<ExpandItemsContextType | undefined>(undefined)
1716

1817
const ExpandedItemsProvider = ({ children }: { children: ReactNode }) => {
1918
const [expandItems, setExpandItems] = useState<Set<string>>(new Set())
2019
const [expandOriginalItems, setExpandOriginalItems] = useState<Set<string>>(new Set())
21-
const cache = useRef<{ [key: string]: { data: GenericContent[] | undefined; timestamp: number } }>({}) // Globális cache objektum
2220
const [cacheTime, setCacheTime] = useState<number>(6000)
21+
const cache = useRef<{ [key: string]: { data: GenericContent[] | undefined; timestamp: number } }>({})
2322
const repo = useRepository()
23+
2424
const loadChildren = async (path: string): Promise<GenericContent[] | undefined> => {
25-
//letölti a connteneteket a megadott path alapján
26-
const loadCollection = function loadCollection(
27-
contentPath: string,
28-
): Promise<ODataCollectionResponse<GenericContent>> {
29-
return repo.loadCollection<GenericContent>({
30-
path: contentPath,
31-
oDataOptions: {
32-
select: ['Id', 'Path', 'Name', 'DisplayName', 'Type', 'Actions', 'Icon', 'ParentId'],
33-
onlyselectList: true,
34-
},
35-
})
36-
}
37-
//cache logika
38-
if (path === undefined || path === '') return undefined
25+
if (!path) return undefined
26+
3927
const now = Date.now()
40-
//ha a cachben nincs elem akkor tovább megyünk
41-
if (cache.current[path] !== undefined) {
42-
//ha a cacheben van elem és undefined akkor várunk
43-
let i = 0
44-
while (cache.current[path].data === undefined) {
45-
setTimeout(() => {}, 200)
46-
i++
47-
if (i > 10) {
48-
return undefined
49-
}
28+
29+
const cached = cache.current[path]
30+
if (cached) {
31+
if (cached.data !== undefined && now - cached.timestamp < cacheTime) {
32+
return cached.data
5033
}
5134

52-
//ha a cacheben van elem és nem undefined akkor visszadjuk azt
53-
if (now - cache.current[path].timestamp < cacheTime) {
54-
return (
55-
cache.current[path] as {
56-
data: GenericContent[] | undefined
57-
timestamp: number
35+
// Wait if data is still loading (i.e., placeholder is in cache with undefined data)
36+
if (cached.data === undefined) {
37+
// Polling-based wait
38+
for (let i = 0; i < 10; i++) {
39+
await new Promise((res) => setTimeout(res, 200))
40+
const recheck = cache.current[path]
41+
if (recheck?.data !== undefined && now - recheck.timestamp < cacheTime) {
42+
return recheck.data
5843
}
59-
)?.data
44+
}
45+
return undefined // Timeout
6046
}
6147
}
48+
49+
// Mark as loading
50+
cache.current[path] = { data: undefined, timestamp: now }
51+
6252
try {
63-
const response = await loadCollection(path)
64-
//itt megkéne várni, esetleg egy await async meoldaná a problémát
53+
const response = await repo.loadCollection<GenericContent>({
54+
path,
55+
oDataOptions: {
56+
select: ['Id', 'Path', 'Name', 'DisplayName', 'Type', 'Actions', 'Icon', 'ParentId'],
57+
onlyselectList: true,
58+
},
59+
})
6560
const result = response?.d.results
66-
cache.current[path] = { data: result, timestamp: now }
61+
cache.current[path] = { data: result, timestamp: Date.now() }
6762
return result
68-
//ezt nem várja meg
6963
} catch (error) {
7064
console.error('#globalfetch: Fetch error:', error)
65+
// Clean up failed cache
66+
delete cache.current[path]
67+
return undefined
7168
}
7269
}
7370

71+
const deleteCache = (path: string) => {
72+
delete cache.current[path]
73+
}
74+
7475
return (
7576
<ExpandItemsContext.Provider
76-
value={[expandItems, setExpandItems, expandOriginalItems, setExpandOriginalItems, loadChildren, setCacheTime]}>
77+
value={[
78+
expandItems,
79+
setExpandItems,
80+
expandOriginalItems,
81+
setExpandOriginalItems,
82+
loadChildren,
83+
setCacheTime,
84+
deleteCache,
85+
]}>
7786
{children}
7887
</ExpandItemsContext.Provider>
7988
)

apps/sensenet/src/components/view-controls/edit-view.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { isExtendedError } from '@sensenet/client-core'
55
import { ActionNameType, EditView as SnEditView } from '@sensenet/controls-react'
66
import { GenericContent } from '@sensenet/default-content-types'
77
import { useLogger, useRepository } from '@sensenet/hooks-react'
8-
import React, { ReactElement, useEffect, useState } from 'react'
8+
import React, { ReactElement, useContext, useEffect, useState } from 'react'
99
import { useHistory, useRouteMatch } from 'react-router-dom'
1010
import { LocalizationObject } from '../../context'
1111
import { useGlobalStyles } from '../../globalStyles'
1212
import { useLocalization, usePersonalSettings, useSelectionService } from '../../hooks'
1313
import { navigateToAction } from '../../services'
1414
import { reactControlMapper } from '../react-control-mapper'
15+
import { ExpandItemsContext } from '../tree/Contexts/ExpandedItemsProvider'
1516
import { useViewControlStyles } from './common/styles'
1617
import { ViewTitle } from './common/view-title'
1718

@@ -36,6 +37,19 @@ export const EditView: React.FC<EditViewProps> = (props) => {
3637
const history = useHistory()
3738
const routeMatch = useRouteMatch<{ browseType: string; action?: string }>()
3839
const personalSettings = usePersonalSettings()
40+
const expContext = useContext(ExpandItemsContext)
41+
if (!expContext) {
42+
throw new Error('SimpleTree111 must be used within a ExpandItemsProvider')
43+
}
44+
const [
45+
_expandItems,
46+
_setExpandItems,
47+
_expandOriginalItems,
48+
_setExpandOriginalItems,
49+
_loadChildren,
50+
_setCacheTime,
51+
deleteCache,
52+
] = expContext
3953

4054
useEffect(() => {
4155
async function getExpandedContent() {
@@ -64,7 +78,8 @@ export const EditView: React.FC<EditViewProps> = (props) => {
6478
idOrPath: content.Id,
6579
content: saveableFields,
6680
})
67-
81+
const parentPath = content.Path.split('/').slice(0, -1).join('/')
82+
deleteCache(parentPath)
6883
logger.information({
6984
message: localization.editPropertiesDialog.saveSuccessNotification.replace(
7085
'{0}',

0 commit comments

Comments
 (0)