fix: refine widget interactions

This commit is contained in:
Thomas Camlong committed 2026-08-03 18:45:16 +02:00
1 parent fbe381cbb5
commit 7847eea1a3
27 files changed
+177 -122

No files matched your search

@@ -1,6 +1,6 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useMemo } from "react";
import JsxParser from "react-jsx-parser";
import { Alert, Stack, Text } from "@mantine/core";
import { IconAlertTriangle } from "@tabler/icons-react";
@@ -10,15 +10,8 @@ import { WHITELISTED_COMPONENTS, SAFE_BINDINGS } from "./jsx-whitelist";
export default function CustomJsxDisplay({ data }: { data: Record<string, unknown> }) {
const template = String(data.template ?? "");
const apiData = data.data;
const [hasParseError, setHasParseError] = useState(false);
const bindings = useMemo(() => SAFE_BINDINGS(apiData), [apiData]);
useEffect(() => {
setHasParseError(false);
}, [template, bindings]);
const handleError = useCallback(() => setHasParseError(true), []);
if (!template.trim()) {
return (
<Alert color="gray" variant="light" p="xs">
@@ -40,20 +33,12 @@ export default function CustomJsxDisplay({ data }: { data: Record<string, unknow
allowUnknownElements={false}
blacklistedAttrs={[/^on.+/i, /^dangerously/i]}
blacklistedTags={["script", "iframe", "object", "embed", "form", "style", "link", "meta", "base"]}
onError={handleError}
renderError={() => (
<Alert color="red" variant="light" icon={<IconAlertTriangle size={16} />} p="xs">
<Text size="xs">Invalid widget template</Text>
</Alert>
)}
/>
{hasParseError && (
<Alert color="yellow" variant="light" p="xs" mt="xs">
<Text size="xs" c="dimmed">
Invalid widget template
</Text>
</Alert>
)}
</Stack>
);
}
+6 -1
View File
@@ -18,7 +18,12 @@ const createOptions = () =>
export const { definition, componentLoader } = createWidgetDefinition("customApi", {
icon: IconApi,
queryKey: [["widget", "customApi", "getData"]],
queryMatcher: ({ input }, scope) => widgetQueryInputMatches(input, { definitionId: scope.options.definitionId }),
queryMatcher: ({ input }, scope) =>
widgetQueryInputMatches(input, {
boardId: scope.boardId,
itemId: scope.itemId,
definitionId: scope.options.definitionId,
}),
contextActions: ({ options, widgetRuntimeRef }) => {
return [
{