Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions frontend/src/components/BlockHTML.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ const getDynamicContent = () => {
let value;
if (props.block.getDataKey("comesFrom") === "props") {
// props are checked first as unavailablity of comesFrom means it comes from dataScript (legacy)
value = getPropValue(
props.block.getDataKey("key"),
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(props.block.getDataKey("key"), props.block);
} else if (props.block.getDataKey("comesFrom") === "blockDataScript") {
value = getBlockDataScriptValue(props.block.getDataKey("key"));
} else {
Expand All @@ -55,13 +49,7 @@ const getDynamicContent = () => {
?.forEach((dataKeyObj: BlockDataKey) => {
let value;
if (dataKeyObj.comesFrom === "props") {
value = getPropValue(
dataKeyObj.key as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(dataKeyObj.key as string, props.block, props.uid);
} else if (dataKeyObj.comesFrom === "blockDataScript") {
value = getBlockDataScriptValue(dataKeyObj.key as string);
} else {
Expand Down
99 changes: 40 additions & 59 deletions frontend/src/components/BuilderBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const canvasStore = useCanvasStore();
const component = ref<HTMLElement | InstanceType<typeof TextBlock> | null>(null);
const attrs = useAttrs();
const editor = ref<InstanceType<typeof BlockEditor> | null>(null);
const isMounted = ref(false);

const pageStore = usePageStore();
const blockDataStore = useBlockDataStore();
const blockUidStore = useBlockUidStore();
Expand Down Expand Up @@ -179,7 +181,7 @@ const attributes = computed(() => {
}

Object.keys(additionalAttributes).forEach((key) => {
if (!RESTRICTED_ATTRIBS.includes(key)) {
if (RESTRICTED_ATTRIBS.includes(key)) {
delete additionalAttributes[key];
}
});
Expand Down Expand Up @@ -219,13 +221,7 @@ const attributes = computed(() => {
if (props.block.getDataKey("type") === "attribute") {
let value;
if (props.block.getDataKey("comesFrom") === "props") {
value = getPropValue(
props.block.getDataKey("key") as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(props.block.getDataKey("key") as string, props.block, uidToUse);
} else if (props.block.getDataKey("comesFrom") === "blockDataScript") {
value = getBlockDataScriptValue(props.block.getDataKey("key") as string);
} else {
Expand All @@ -243,13 +239,7 @@ const attributes = computed(() => {
const property = dataKeyObj.property as string;
let value;
if (dataKeyObj.comesFrom === "props") {
value = getPropValue(
dataKeyObj.key as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(dataKeyObj.key as string, props.block, uidToUse);
} else if (dataKeyObj.comesFrom === "blockDataScript") {
value = getBlockDataScriptValue(dataKeyObj.key as string);
} else {
Expand Down Expand Up @@ -283,13 +273,7 @@ const styles = computed(() => {
if (props.block.getDataKey("type") === "style") {
let value;
if (props.block.getDataKey("comesFrom") === "props") {
value = getPropValue(
props.block.getDataKey("key") as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(props.block.getDataKey("key") as string, props.block, uidToUse);
} else if (props.block.getDataKey("comesFrom") === "blockDataScript") {
value = getBlockDataScriptValue(props.block.getDataKey("key") as string);
} else {
Expand All @@ -308,13 +292,7 @@ const styles = computed(() => {
const property = dataKeyObj.property as string;
let value;
if (dataKeyObj.comesFrom === "props") {
value = getPropValue(
dataKeyObj.key as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(dataKeyObj.key as string, props.block, uidToUse);
} else if (dataKeyObj.comesFrom === "blockDataScript") {
value = getBlockDataScriptValue(dataKeyObj.key as string);
} else {
Expand Down Expand Up @@ -396,31 +374,34 @@ onMounted(async () => {
}
blockUidStore.registerBlockUid(uidToUse, props.block);
blockUidStore.setParentUid(uidToUse, props.parentBlockUid || "root");
isMounted.value = true;
});

const allResolvedProps = computed(() => {
if (!isMounted.value) {
return {};
}
const defaultProps = Object.entries(props.defaultProps || {}).reduce((acc, [key, value]) => {
acc[key] = value.value;
return acc;
}, {} as Record<string, any>);

const blockProps = Object.entries({
...props.block.getBlockProps(),
}).reduce((acc, [key]) => {
acc[key] = getPropValue(key, props.block, uidToUse);
return acc;
}, {} as Record<string, any>);

const parentProps = Object.entries(getParentProps(props.block, uidToUse)).reduce((acc, [key, value]) => {
acc[key] = getPropValue(key, value.block!, value.blockUid);
return acc;
}, {} as Record<string, any>);

return {
...Object.fromEntries(
Object.entries(props.defaultProps || {}).map(([key, value]) => {
return [key, value.value];
}),
),
...Object.fromEntries(
Object.entries({ ...props.block.getBlockProps(), ...getParentProps(props.block) }).map(
([key, prop]) => {
return [
key,
getPropValue(
key,
props.block,
getDataScriptValue,
(path: string) => getDataForKey({ ...props.blockData }, path), // block props can not refer to own block data items
props.defaultProps,
),
];
},
),
),
...parentProps,
...blockProps,
...defaultProps,
};
});

Expand Down Expand Up @@ -496,12 +477,18 @@ watch(
});
});
},
{ immediate: true },
{ immediate: true, deep: true },
);

watchEffect(() => {
blockDataStore.setPageData(uidToUse, props.data || {});
blockDataStore.setBlockData(uidToUse, props.blockData || {}, "passedDown");
});

watchEffect(() => {
blockDataStore.setPageData(uidToUse, props.data || {});
});

watchEffect(() => {
blockDataStore.setBlockDefaultProps(uidToUse, props.defaultProps || {});
});

Expand All @@ -525,13 +512,7 @@ const hiddenDueToVisibilityCondition = computed(() => {
const value = getDataScriptValue(key as string);
return !Boolean(value);
} else {
const value = getPropValue(
key as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
const value = getPropValue(key as string, props.block, uidToUse);
return !Boolean(value);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const allBlockProps = computed(() => {
if (!currentBlock || typeof currentBlock.getBlockProps !== "function") return {};

const ownBlockProps = currentBlock.getBlockProps();
const inheritedBlockProps = getParentProps(currentBlock, {});
const inheritedBlockProps = getParentProps(currentBlock);
const defaultProps = getDefaultPropsList(currentBlock, blockController);

return {
Expand Down
20 changes: 3 additions & 17 deletions frontend/src/components/Controls/DynamicValueHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const filteredBlockProps = computed(() => {
} else {
const currentBlock = props.block || blockController.getFirstSelectedBlock();
if (currentBlock) {
parentProps = Object.keys(getParentProps(currentBlock, {}));
parentProps = Object.keys(getParentProps(currentBlock));
} else {
parentProps = [];
}
Expand Down Expand Up @@ -185,15 +185,7 @@ const filteredItems = computed(() => {
(item) =>
item.key.toLowerCase().includes(query) ||
String(getDataScriptValue(item.key)).toLowerCase().includes(query) ||
String(
getPropValue(
item.key,
props.block || blockController.getFirstSelectedBlock(),
getDataScriptValue,
getBlockDataScriptValue,
defaultProps.value,
),
)
String(getPropValue(item.key, props.block || blockController.getFirstSelectedBlock()))
.toLowerCase()
.includes(query),
);
Expand All @@ -203,13 +195,7 @@ const selectedItem = ref<DynamicValueItem | null>(props.selectedValue || null);

const getValue = (item: DynamicValueItem): any => {
if (item.comesFrom == "props") {
return getPropValue(
item.key,
props.block || blockController.getFirstSelectedBlock(),
getDataScriptValue,
getBlockDataScriptValue,
defaultProps.value,
);
return getPropValue(item.key, props.block || blockController.getFirstSelectedBlock());
} else if (item.comesFrom == "blockDataScript") {
return getBlockDataScriptValue(item.key);
} else {
Expand Down
16 changes: 2 additions & 14 deletions frontend/src/components/TextBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,7 @@ const getDynamicContent = () => {
let value;
if (props.block.getDataKey("comesFrom") === "props") {
// props are checked first as unavailablity of comesFrom means it comes from dataScript (legacy)
value = getPropValue(
props.block.getDataKey("key"),
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(props.block.getDataKey("key"), props.block, props.uid);
} else if (props.block.getDataKey("comesFrom") === "blockDataScript") {
value = getBlockDataScriptValue(props.block.getDataKey("key"));
} else {
Expand All @@ -152,13 +146,7 @@ const getDynamicContent = () => {
?.forEach((dataKeyObj: BlockDataKey) => {
let value;
if (dataKeyObj.comesFrom === "props") {
value = getPropValue(
dataKeyObj.key as string,
props.block,
getDataScriptValue,
getBlockDataScriptValue,
props.defaultProps,
);
value = getPropValue(dataKeyObj.key as string, props.block, props.uid);
} else if (dataKeyObj.comesFrom === "blockDataScript") {
value = getBlockDataScriptValue(dataKeyObj.key as string);
} else {
Expand Down
62 changes: 46 additions & 16 deletions frontend/src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1120,19 +1120,33 @@ const getValueForInheritedProp = (
return undefined;
};

const getParentProps = (baseBlock: Block, baseProps: BlockProps = {}): BlockProps => {
type BlockPropsWithTraceback = Record<
string,
BlockProps[string] & { block?: Block; blockUid?: string | null }
>;

const getParentProps = (
baseBlock: Block,
blockUid?: string | null,
baseProps: BlockPropsWithTraceback = {},
): BlockPropsWithTraceback => {
const parentBlock = baseBlock.getParentBlock();
const parentBlockUid = useBlockUidStore().getParentUid(blockUid || "");
if (parentBlock) {
const parentProps: BlockProps = {};
const parentProps: BlockPropsWithTraceback = {};
Object.entries(parentBlock.getBlockProps())
.filter(([_, propDetails]) => {
return propDetails.isPassedDown;
})
.map(([propName, propDetails]) => {
parentProps[propName] = propDetails;
.forEach(([propName, propDetails]) => {
parentProps[propName] = {
...propDetails,
block: parentBlock,
blockUid: parentBlockUid,
};
});
const combinedProps = { ...parentProps, ...baseProps };
return getParentProps(parentBlock, combinedProps);
return getParentProps(parentBlock, parentBlockUid, combinedProps);
} else {
return baseProps;
}
Expand Down Expand Up @@ -1184,28 +1198,46 @@ const getDefaultPropsList = (block: Block, blockController: any): BlockProps =>

const PARSEABLE_STANDARD_TYPES = ["number", "boolean", "object", "array"];

const getPropValue = (
propName: string,
block: Block,
getDataScriptValue: (path: string) => any,
getBlockScriptValue: (path: string) => any,
defaultProps?: Record<string, any> | null,
): any => {
const getPropValue = (propName: string, block: Block, blockUid?: string | null): any => {
const blockDataStore = useBlockDataStore();

const uidToUse = blockUid || block.blockId;

const defaultProps = blockDataStore.getDefaultProps(uidToUse);
// Check default props first
if (defaultProps?.[propName] !== undefined) {
return defaultProps[propName].value;
}

let parentProps: BlockPropsWithTraceback | null = null;

// Find matching prop from block or parent
const blockProps = block.getBlockProps();
const matchingProp = blockProps[propName] ?? getParentProps(block, {})[propName];
let matchingProp: BlockPropsWithTraceback[string] =
blockProps[propName] ?? (parentProps = getParentProps(block, blockUid))[propName];

if (!matchingProp) {
return undefined;
}

// Handle dynamic props
if (matchingProp.isDynamic) {
if (matchingProp.comesFrom === "props" && matchingProp.value) {
if (parentProps === null) {
parentProps = getParentProps(block, blockUid);
}
const newMatchingProp = parentProps[matchingProp.value];
if (!newMatchingProp.block) return undefined;
return getPropValue(matchingProp.value, newMatchingProp.block, newMatchingProp.blockUid);
}
const getDataScriptValue = (path: string) => {
const pageData = blockDataStore.getPageData(uidToUse) || {};
return getDataForKey(pageData, path);
};
const getBlockScriptValue = (path: string) => {
const blockData = blockDataStore.getBlockData(uidToUse, "passedDown") || {};
return getDataForKey(blockData, path);
};
if (matchingProp.comesFrom === "dataScript" && matchingProp.value) {
return getDataScriptValue(matchingProp.value);
}
Expand All @@ -1230,7 +1262,6 @@ const getPropValue = (
if (PARSEABLE_STANDARD_TYPES.includes(type)) {
return matchingProp.value ? JSON.parse(matchingProp.value) : defaultValue;
}

return matchingProp.value || defaultValue;
}

Expand Down Expand Up @@ -1309,9 +1340,8 @@ function executeBlockClientScriptUnrestricted(
try {
document.querySelectorAll(`[data-created-by='${blockUid}']`).forEach((el) => el.remove());
fn.call(thisElement, context);
console.log("Executed unrestricted user script");
} catch (e) {
console.error("Error in user script 2:", e);
console.error("Error in user script (unrestricted):", e);
// toast.warning("An error occurred while executing block script: " + (e instanceof Error ? e.message : ""));
}
}
Expand Down
Loading