@developer_tribe/react-builder 1.2.24 → 1.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attributes-editor/SpecialCategorySection.d.ts +2 -1
- package/dist/attributes-editor/attributesEditorModelTypes.d.ts +2 -0
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +0 -2
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +0 -2
- package/dist/build-components/Button/ButtonProps.generated.d.ts +0 -2
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +0 -2
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +0 -2
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +0 -2
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +0 -2
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +0 -2
- package/dist/build-components/CountDown/CountDownProps.generated.d.ts +0 -2
- package/dist/build-components/Counter/CounterProps.generated.d.ts +0 -2
- package/dist/build-components/Image/ImageProps.generated.d.ts +0 -2
- package/dist/build-components/Main/MainProps.generated.d.ts +0 -2
- package/dist/build-components/NavigationBarColor/NavigationBarColorProps.generated.d.ts +0 -2
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +0 -2
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallCounter/PaywallCounterProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +0 -2
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +0 -2
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +0 -2
- package/dist/build-components/Separator/SeparatorProps.generated.d.ts +0 -2
- package/dist/build-components/StatusBarColor/StatusBarColorProps.generated.d.ts +0 -2
- package/dist/build-components/Text/TextProps.generated.d.ts +0 -2
- package/dist/build-components/patterns.generated.d.ts +76 -70
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +3 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.web.cjs.js +4 -4
- package/dist/index.web.cjs.js.map +1 -1
- package/dist/index.web.esm.js +2 -2
- package/dist/index.web.esm.js.map +1 -1
- package/dist/pages/ProjectPage.d.ts +2 -2
- package/dist/pages/projectPageUtils.d.ts +7 -1
- package/dist/types/Project.d.ts +6 -0
- package/dist/utils/patterns.d.ts +2 -0
- package/package.json +1 -1
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +11 -2
- package/src/AttributesEditor.tsx +15 -4
- package/src/assets/meta.json +1 -1
- package/src/assets/samples/paywall-app-delete-offer.json +0 -1
- package/src/assets/samples/paywall-app-open-offer.json +0 -1
- package/src/assets/samples/paywall-back-offer.json +0 -1
- package/src/assets/samples/paywall-notification-offer.json +0 -1
- package/src/assets/samples/simple-2.json +0 -1
- package/src/attributes-editor/AttributesEditorView.tsx +43 -36
- package/src/attributes-editor/SpecialCategorySection.tsx +5 -3
- package/src/attributes-editor/attributesEditorModelTypes.ts +2 -0
- package/src/attributes-editor/useAttributesEditorModel.ts +6 -0
- package/src/build-components/BIcon/BIconProps.generated.ts +0 -2
- package/src/build-components/BIcon/pattern.json +5 -3
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +0 -2
- package/src/build-components/BackgroundImage/pattern.json +12 -4
- package/src/build-components/Button/ButtonProps.generated.ts +0 -2
- package/src/build-components/Button/pattern.json +5 -3
- package/src/build-components/Carousel/CarouselProps.generated.ts +0 -2
- package/src/build-components/Carousel/pattern.json +11 -5
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +0 -2
- package/src/build-components/CarouselButtons/pattern.json +11 -4
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +0 -2
- package/src/build-components/CarouselDots/pattern.json +5 -3
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +0 -2
- package/src/build-components/CarouselItem/pattern.json +6 -6
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +0 -2
- package/src/build-components/CarouselProvider/pattern.json +6 -5
- package/src/build-components/CountDown/CountDownProps.generated.ts +0 -2
- package/src/build-components/CountDown/pattern.json +6 -3
- package/src/build-components/Counter/CounterProps.generated.ts +0 -2
- package/src/build-components/Counter/pattern.json +5 -1
- package/src/build-components/Image/ImageProps.generated.ts +0 -2
- package/src/build-components/Image/pattern.json +5 -3
- package/src/build-components/Main/MainProps.generated.ts +0 -2
- package/src/build-components/Main/pattern.json +5 -3
- package/src/build-components/NavigationBarColor/NavigationBarColorProps.generated.ts +0 -2
- package/src/build-components/NavigationBarColor/pattern.json +5 -3
- package/src/build-components/Onboard/OnboardProps.generated.ts +0 -2
- package/src/build-components/Onboard/pattern.json +9 -7
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +0 -2
- package/src/build-components/OnboardButton/pattern.json +16 -5
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +0 -2
- package/src/build-components/OnboardButtons/pattern.json +17 -6
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +0 -2
- package/src/build-components/OnboardDot/pattern.json +5 -3
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +0 -2
- package/src/build-components/OnboardFooter/pattern.json +5 -3
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +0 -2
- package/src/build-components/OnboardImage/pattern.json +7 -3
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +0 -2
- package/src/build-components/OnboardItem/pattern.json +13 -5
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +0 -2
- package/src/build-components/OnboardProvider/pattern.json +10 -4
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +0 -2
- package/src/build-components/OnboardSubtitle/pattern.json +7 -6
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +0 -2
- package/src/build-components/OnboardTitle/pattern.json +7 -6
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +0 -2
- package/src/build-components/PaywallBackground/pattern.json +5 -5
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +0 -2
- package/src/build-components/PaywallCloseButton/pattern.json +6 -6
- package/src/build-components/PaywallCounter/PaywallCounterProps.generated.ts +0 -2
- package/src/build-components/PaywallCounter/pattern.json +6 -3
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +0 -2
- package/src/build-components/PaywallOptions/pattern.json +6 -6
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +0 -2
- package/src/build-components/PaywallProvider/pattern.json +5 -3
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +0 -2
- package/src/build-components/PaywallSubscribeButton/pattern.json +6 -6
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +0 -2
- package/src/build-components/RadioButton/pattern.json +5 -3
- package/src/build-components/Separator/SeparatorProps.generated.ts +0 -2
- package/src/build-components/Separator/pattern.json +5 -3
- package/src/build-components/StatusBarColor/StatusBarColorProps.generated.ts +0 -2
- package/src/build-components/StatusBarColor/pattern.json +5 -3
- package/src/build-components/Text/TextProps.generated.ts +0 -2
- package/src/build-components/Text/pattern.json +11 -5
- package/src/build-components/View/pattern.json +18 -4
- package/src/build-components/patterns.generated.ts +72 -70
- package/src/components/AttributesEditorPanel.tsx +48 -32
- package/src/components/Builder.tsx +4 -1
- package/src/index.ts +1 -1
- package/src/pages/ProjectPage.tsx +45 -22
- package/src/pages/projectPageUtils.ts +15 -1
- package/src/types/Project.ts +7 -0
- package/src/utils/patterns.ts +2 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import type { Node, NodeData } from '../types/Node';
|
|
3
|
-
import type { Project, ProjectColors } from '../types/Project';
|
|
3
|
+
import type { Project, ProjectColors, ProjectMeta } from '../types/Project';
|
|
4
4
|
import { ToastContainer, toast } from 'react-toastify';
|
|
5
5
|
import { RenderPage } from '../RenderPage';
|
|
6
6
|
import { EditorHeader } from '../components/EditorHeader';
|
|
@@ -31,16 +31,16 @@ import {
|
|
|
31
31
|
deleteNodeFromTree,
|
|
32
32
|
findNodeByKey,
|
|
33
33
|
isNodeRecord,
|
|
34
|
-
nodeHasChild,
|
|
35
34
|
} from '../utils/nodeTree';
|
|
36
35
|
import type { Fonts } from '../types/Fonts';
|
|
37
36
|
import { useProjectFonts } from '../hooks/useProjectFonts';
|
|
38
|
-
import { resolveProjectForSave } from './projectPageUtils';
|
|
37
|
+
import { resolveProjectForSave, toProjectMeta } from './projectPageUtils';
|
|
39
38
|
import { getDefaultProject } from '../utils/getDefaultProject';
|
|
40
39
|
import { CURRENT_PROJECT_VERSION } from '../migrations/migratePipe';
|
|
41
40
|
export type ProjectPageProps = {
|
|
42
41
|
project: Project;
|
|
43
|
-
|
|
42
|
+
// TODO: Tüm onSaveProject call-site'ları toProjectMeta kullanacak şekilde migrate et
|
|
43
|
+
onSaveProject: (project: ProjectMeta) => void;
|
|
44
44
|
appConfig?: AppConfig;
|
|
45
45
|
logLevel?: LogLevel;
|
|
46
46
|
projectColors?: ProjectColors;
|
|
@@ -151,14 +151,15 @@ export function ProjectPage({
|
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
// Refresh current's reference so the Builder re-renders the updated subtree.
|
|
155
|
+
// deleteNodeFromTree creates new objects for ancestors of the removed node,
|
|
156
|
+
// so the old `current` reference becomes stale when the deleted node was a
|
|
157
|
+
// descendant of `current`.
|
|
158
|
+
if (isNodeRecord(current) && current.key) {
|
|
159
|
+
const nextCurrent = findNodeByKey(updated, current.key);
|
|
160
|
+
setCurrent(nextCurrent ?? updated);
|
|
161
|
+
} else {
|
|
162
|
+
setCurrent(updated);
|
|
162
163
|
}
|
|
163
164
|
},
|
|
164
165
|
[editorData, current],
|
|
@@ -226,8 +227,26 @@ export function ProjectPage({
|
|
|
226
227
|
return () => clearTimeout(timer);
|
|
227
228
|
}, [activeProject.data]);
|
|
228
229
|
|
|
230
|
+
// Ref for the full project (used inside effect for migration check etc.)
|
|
231
|
+
const activeProjectRef = useRef(activeProject);
|
|
232
|
+
activeProjectRef.current = activeProject;
|
|
233
|
+
// Ref for current editorData so the effect can compare without depending on it.
|
|
234
|
+
const editorDataRef = useRef(editorData);
|
|
235
|
+
editorDataRef.current = editorData;
|
|
236
|
+
|
|
229
237
|
useEffect(() => {
|
|
230
238
|
try {
|
|
239
|
+
const currentProject = activeProjectRef.current;
|
|
240
|
+
const projectData = currentProject.data;
|
|
241
|
+
|
|
242
|
+
// Guard: skip reinit when the incoming project data is the same reference
|
|
243
|
+
// we already hold in editorData. After a save round-trip the parent pushes
|
|
244
|
+
// a new project object whose .data is the very same reference as editorData.
|
|
245
|
+
// Re-processing it would flash a loading state and discard in-flight changes.
|
|
246
|
+
if (projectData != null && projectData === editorDataRef.current) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
231
250
|
// Reset to "loading" immediately on project change so the loader is shown
|
|
232
251
|
// until a valid node is available (and for at least 2 seconds).
|
|
233
252
|
if (!isEmptyProjectData) {
|
|
@@ -237,7 +256,7 @@ export function ProjectPage({
|
|
|
237
256
|
setValidationError(null);
|
|
238
257
|
setValidationErrorStack(null);
|
|
239
258
|
// Version gate: if project is older than the current schema, show migration UI.
|
|
240
|
-
const pipe = getMigrationPipe(
|
|
259
|
+
const pipe = getMigrationPipe(currentProject);
|
|
241
260
|
if (!bypassValidation && pipe.required) {
|
|
242
261
|
setMigrationGate(pipe);
|
|
243
262
|
setEditorData(null);
|
|
@@ -248,8 +267,8 @@ export function ProjectPage({
|
|
|
248
267
|
if (bypassValidation) {
|
|
249
268
|
// Best-effort: let the user continue with the raw data even if invalid.
|
|
250
269
|
// This may still crash the preview, but it unblocks users for debugging.
|
|
251
|
-
setEditorData(
|
|
252
|
-
setCurrent(
|
|
270
|
+
setEditorData(currentProject.data as Node);
|
|
271
|
+
setCurrent(currentProject.data as Node);
|
|
253
272
|
return;
|
|
254
273
|
}
|
|
255
274
|
if (isEmptyProjectData) {
|
|
@@ -258,7 +277,7 @@ export function ProjectPage({
|
|
|
258
277
|
return;
|
|
259
278
|
}
|
|
260
279
|
|
|
261
|
-
const inputNode: Node =
|
|
280
|
+
const inputNode: Node = currentProject.data as Node;
|
|
262
281
|
|
|
263
282
|
const processed = analyseAndProccess(inputNode);
|
|
264
283
|
if (!processed) return;
|
|
@@ -275,7 +294,9 @@ export function ProjectPage({
|
|
|
275
294
|
setEditorData(null);
|
|
276
295
|
setCurrent(null);
|
|
277
296
|
}
|
|
278
|
-
|
|
297
|
+
// Note: depend on activeProject.data (not activeProject object) to avoid
|
|
298
|
+
// reinit when the project wrapper changes but data is the same reference.
|
|
299
|
+
}, [activeProject.data, isEmptyProjectData, bypassValidation, setCurrent]);
|
|
279
300
|
|
|
280
301
|
const showLoading =
|
|
281
302
|
!isEmptyProjectData && (editorData === null || !minLoadingDelayDone);
|
|
@@ -300,13 +321,15 @@ export function ProjectPage({
|
|
|
300
321
|
if (onSaveProjectColors && resolvedProjectColors) {
|
|
301
322
|
onSaveProjectColors(resolvedProjectColors);
|
|
302
323
|
}
|
|
303
|
-
|
|
324
|
+
const projectMeta = toProjectMeta(
|
|
304
325
|
resolveProjectForSave({
|
|
305
326
|
project,
|
|
306
327
|
overrideProject,
|
|
307
328
|
data: editorData,
|
|
308
329
|
}),
|
|
309
330
|
);
|
|
331
|
+
logger.info('ProjectPage', 'saving project meta', projectMeta);
|
|
332
|
+
onSaveProject(projectMeta);
|
|
310
333
|
toast.success('Saved');
|
|
311
334
|
} catch (e) {
|
|
312
335
|
logger.error('ProjectPage', 'save project failed', e);
|
|
@@ -377,7 +400,7 @@ export function ProjectPage({
|
|
|
377
400
|
|
|
378
401
|
const { project: migratedProject } =
|
|
379
402
|
runProjectMigrations(projectForMigration);
|
|
380
|
-
onSaveProject(migratedProject);
|
|
403
|
+
onSaveProject(toProjectMeta(migratedProject));
|
|
381
404
|
setOverrideProject(migratedProject);
|
|
382
405
|
setBypassValidation(true);
|
|
383
406
|
setMigrationGate(null);
|
|
@@ -430,7 +453,7 @@ export function ProjectPage({
|
|
|
430
453
|
|
|
431
454
|
// This action only fixes project metadata. It intentionally does NOT
|
|
432
455
|
// validate/normalize node data (it might still be invalid).
|
|
433
|
-
onSaveProject(fixedProject);
|
|
456
|
+
onSaveProject(toProjectMeta(fixedProject));
|
|
434
457
|
setOverrideProject(fixedProject);
|
|
435
458
|
setBypassValidation(false);
|
|
436
459
|
setMigrationGate(null);
|
|
@@ -488,7 +511,7 @@ export function ProjectPage({
|
|
|
488
511
|
data: nodeCandidate as Project['data'],
|
|
489
512
|
};
|
|
490
513
|
|
|
491
|
-
onSaveProject(nextProject);
|
|
514
|
+
onSaveProject(toProjectMeta(nextProject));
|
|
492
515
|
setOverrideProject(nextProject);
|
|
493
516
|
setBypassValidation(false);
|
|
494
517
|
setValidationError(null);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Project } from '../types/Project';
|
|
1
|
+
import type { Project, ProjectMeta } from '../types/Project';
|
|
2
2
|
import type { Node } from '../types/Node';
|
|
3
3
|
import { getDefaultProject } from '../utils/getDefaultProject';
|
|
4
4
|
|
|
@@ -13,3 +13,17 @@ export function resolveProjectForSave(args: {
|
|
|
13
13
|
data: args.data,
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Strips a full Project down to its essential persistence fields.
|
|
19
|
+
* Use before handing the project to onSaveProject so consumers only
|
|
20
|
+
* receive the canonical metadata (name, version, type, data).
|
|
21
|
+
*/
|
|
22
|
+
export function toProjectMeta(project: Project): ProjectMeta {
|
|
23
|
+
return {
|
|
24
|
+
name: project.name,
|
|
25
|
+
version: project.version,
|
|
26
|
+
...(project.type ? { type: project.type } : {}),
|
|
27
|
+
data: project.data,
|
|
28
|
+
};
|
|
29
|
+
}
|
package/src/types/Project.ts
CHANGED
|
@@ -29,6 +29,13 @@ export interface ProjectBase<T> {
|
|
|
29
29
|
|
|
30
30
|
export interface Project extends ProjectBase<Node> {}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Lightweight subset of Project containing only the essential metadata
|
|
34
|
+
* needed for persistence (name, version, type, data).
|
|
35
|
+
* Excludes runtime/editor-only fields like appConfig and projectColors.
|
|
36
|
+
*/
|
|
37
|
+
export type ProjectMeta = Pick<Project, 'name' | 'version' | 'type' | 'data'>;
|
|
38
|
+
|
|
32
39
|
export type LogLevel = 'NONE' | 'ERROR' | 'WARN' | 'INFO' | 'VERBOSE';
|
|
33
40
|
|
|
34
41
|
export type LogSource = string;
|