improved disabling validation

This commit is contained in:
Dmitri 2026-06-25 11:53:54 +02:00
parent 430c7faa98
commit 7a72aa7fa7
4 changed files with 27 additions and 9 deletions

View File

@ -69,7 +69,10 @@ import type {
GalleryCarouselMediaItem, GalleryCarouselMediaItem,
InfoPanelImage, InfoPanelImage,
} from '../types/constructor'; } from '../types/constructor';
import { isInfoPanelElementType } from '../lib/elementDefaults'; import {
isElementFlagEnabled,
isInfoPanelElementType,
} from '../lib/elementDefaults';
import type { ElementTransitionSettings } from '../types/transition'; import type { ElementTransitionSettings } from '../types/transition';
import { import {
entityToProjectSettings, entityToProjectSettings,
@ -693,10 +696,16 @@ export default function RuntimePresentation({
const handleElementClick = useCallback( const handleElementClick = useCallback(
(element: CanvasElement) => { (element: CanvasElement) => {
if (isNavigationType(element.type) && element.navDisabled) { if (
isNavigationType(element.type) &&
isElementFlagEnabled(element.navDisabled)
) {
return; return;
} }
if (isInfoPanelElementType(element.type) && element.infoPanelDisabled) { if (
isInfoPanelElementType(element.type) &&
isElementFlagEnabled(element.infoPanelDisabled)
) {
return; return;
} }
@ -1023,9 +1032,9 @@ export default function RuntimePresentation({
element={element} element={element}
isDisabled={ isDisabled={
(isNavigationType(element.type) && (isNavigationType(element.type) &&
Boolean(element.navDisabled)) || isElementFlagEnabled(element.navDisabled)) ||
(isInfoPanelElementType(element.type) && (isInfoPanelElementType(element.type) &&
Boolean(element.infoPanelDisabled)) isElementFlagEnabled(element.infoPanelDisabled))
} }
onClick={() => handleElementClick(element)} onClick={() => handleElementClick(element)}
resolveUrl={resolveUrlWithBlob} resolveUrl={resolveUrlWithBlob}

View File

@ -10,6 +10,7 @@ import React from 'react';
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import type { CanvasElement } from '../../../types/constructor'; import type { CanvasElement } from '../../../types/constructor';
import { resolveAssetPlaybackUrl } from '../../../lib/assetUrl'; import { resolveAssetPlaybackUrl } from '../../../lib/assetUrl';
import { isElementFlagEnabled } from '../../../lib/elementDefaults';
interface InfoPanelElementProps { interface InfoPanelElementProps {
element: CanvasElement; element: CanvasElement;
@ -27,7 +28,7 @@ const InfoPanelElement: React.FC<InfoPanelElementProps> = ({
onClick, onClick,
}) => { }) => {
const resolve = resolveUrl ?? resolveAssetPlaybackUrl; const resolve = resolveUrl ?? resolveAssetPlaybackUrl;
const isDisabled = element.infoPanelDisabled || false; const isDisabled = isElementFlagEnabled(element.infoPanelDisabled);
const triggerLabel = element.infoPanelTriggerLabel || 'Info'; const triggerLabel = element.infoPanelTriggerLabel || 'Info';
const fontFamily = element.infoPanelTriggerFontFamily || undefined; const fontFamily = element.infoPanelTriggerFontFamily || undefined;

View File

@ -73,6 +73,13 @@ export const createLocalId = (): string => {
export const clamp = (value: number, min: number, max: number): number => export const clamp = (value: number, min: number, max: number): number =>
Math.min(Math.max(value, min), max); Math.min(Math.max(value, min), max);
/**
* Strictly parse feature flags stored on element JSON.
*/
export const isElementFlagEnabled = (value: unknown): boolean =>
value === true ||
(typeof value === 'string' && value.trim().toLowerCase() === 'true');
/** /**
* Normalize appearDelaySec value * Normalize appearDelaySec value
*/ */

View File

@ -63,6 +63,7 @@ import {
normalizeAppearDurationSec, normalizeAppearDurationSec,
ELEMENT_TYPE_LABELS, ELEMENT_TYPE_LABELS,
getNavigationButtonKind, getNavigationButtonKind,
isElementFlagEnabled,
isNavigationElementType, isNavigationElementType,
isDescriptionElementType, isDescriptionElementType,
isMediaElementType, isMediaElementType,
@ -1475,7 +1476,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
if (transitionPreview || isTransitionBuffering) { if (transitionPreview || isTransitionBuffering) {
return; return;
} }
if (element.navDisabled) { if (isElementFlagEnabled(element.navDisabled)) {
return; return;
} }
@ -2162,9 +2163,9 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
isEditMode={isConstructorEditMode} isEditMode={isConstructorEditMode}
isDisabled={ isDisabled={
(isNavigationElementType(element.type) && (isNavigationElementType(element.type) &&
Boolean(element.navDisabled)) || isElementFlagEnabled(element.navDisabled)) ||
(isInfoPanelElementType(element.type) && (isInfoPanelElementType(element.type) &&
Boolean(element.infoPanelDisabled)) isElementFlagEnabled(element.infoPanelDisabled))
} }
onClick={() => onCanvasElementClick(element)} onClick={() => onCanvasElementClick(element)}
onMouseDown={(event) => onMouseDown={(event) =>