-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseRevalidateFieldDataPostMessageEvent.ts
More file actions
148 lines (129 loc) · 4.93 KB
/
useRevalidateFieldDataPostMessageEvent.ts
File metadata and controls
148 lines (129 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { VisualBuilder } from "..";
import { extractDetailsFromCslp, isValidCslp } from "../../cslp";
import { FieldSchemaMap } from "../utils/fieldSchemaMap";
import { hideFocusOverlay } from "../generators/generateOverlay";
import { handleBuilderInteraction } from "../listeners/mouseClick";
/**
* Revalidates field data and schema after variant linking operations.
* Unfocuses the selected element, revalidates data, and then reselects it.
*/
export async function handleRevalidateFieldData(): Promise<void> {
const focusedElement =
VisualBuilder.VisualBuilderGlobalState.value
.previousSelectedEditableDOM;
const hoveredElement =
VisualBuilder.VisualBuilderGlobalState.value.previousHoveredTargetDOM;
// Store element identifiers for refocusing
const elementCslp = focusedElement?.getAttribute("data-cslp");
const elementCslpUniqueId =
focusedElement?.getAttribute("data-cslp-unique-id") || null;
const shouldRefocus = !!focusedElement;
try {
// Step 1: Unfocus the current element
if (shouldRefocus) {
await unfocusElement();
}
// Step 2: Revalidate field data
const targetElement = hoveredElement || focusedElement;
if (targetElement) {
const cslp = targetElement.getAttribute("data-cslp");
if (isValidCslp(cslp)) {
const fieldMetadata = extractDetailsFromCslp(cslp);
// Try to revalidate specific field schema and data
// Clear the entire content type schema from cache to force fresh fetch
FieldSchemaMap.clearContentTypeSchema(
fieldMetadata.content_type_uid
);
}
}
// Fallback 1: Clear all field schema cache
FieldSchemaMap.clear();
} catch (error) {
console.error("Error handling revalidate field data:", error);
// Final fallback - refresh the page
window.location.reload();
} finally {
// Step 3: Refocus the element if we had one focused before
if (shouldRefocus && isValidCslp(elementCslp)) {
await refocusElement(elementCslp, elementCslpUniqueId);
}
}
}
/**
* Unfocuses the currently selected element and clears focus state
*/
async function unfocusElement(): Promise<void> {
const { visualBuilderContainer, overlayWrapper, focusedToolbar } =
getVisualBuilderElements();
if (!visualBuilderContainer || !overlayWrapper) return;
const dummyResizeObserver = new ResizeObserver(() => {});
// Hide focus overlay (cleanIndividualFieldResidual needs previousSelectedEditableDOM)
hideFocusOverlay({
visualBuilderContainer,
visualBuilderOverlayWrapper: overlayWrapper,
focusedToolbar,
resizeObserver: dummyResizeObserver,
noTrigger: true,
});
// Clear global state after cleanup
VisualBuilder.VisualBuilderGlobalState.value.previousSelectedEditableDOM =
null;
VisualBuilder.VisualBuilderGlobalState.value.isFocussed = false;
}
/**
* Refocuses an element by its CSLP identifier
*/
async function refocusElement(
cslp: string,
uniqueId: string | null
): Promise<void> {
try {
// Find the element (prefer unique ID, fallback to CSLP)
const elementToRefocus =
(uniqueId &&
document.querySelector(
`[data-cslp-unique-id="${uniqueId}"]`
)) ||
document.querySelector(`[data-cslp="${cslp}"]`);
if (!elementToRefocus) return;
const { visualBuilderContainer, overlayWrapper, focusedToolbar } =
getVisualBuilderElements();
if (!visualBuilderContainer || !overlayWrapper) return;
// Create synthetic click event
const syntheticEvent = new MouseEvent("click", {
bubbles: true,
cancelable: true,
});
Object.defineProperty(syntheticEvent, "target", {
value: elementToRefocus,
enumerable: true,
});
// Refocus using handleBuilderInteraction
await handleBuilderInteraction({
event: syntheticEvent,
previousSelectedEditableDOM: null,
visualBuilderContainer,
overlayWrapper,
focusedToolbar,
resizeObserver: new ResizeObserver(() => {}),
});
} catch (error) {
console.warn("Could not refocus element after revalidation:", error);
}
}
/**
* Gets the main visual builder DOM elements
*/
function getVisualBuilderElements() {
return {
visualBuilderContainer: document.querySelector(
".visual-builder__container"
) as HTMLDivElement | null,
overlayWrapper: document.querySelector(
".visual-builder__overlay__wrapper"
) as HTMLDivElement | null,
focusedToolbar: document.querySelector(
".visual-builder__focused-toolbar"
) as HTMLDivElement | null,
};
}