mirror of
https://github.com/formbricks/formbricks.git
synced 2026-03-19 00:23:35 -05:00
Compare commits
5 Commits
cursor/saf
...
cursor/for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
893384a19d | ||
|
|
1eba663294 | ||
|
|
c37e5c0750 | ||
|
|
75e47b4979 | ||
|
|
7504c47fc1 |
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
type CollisionDetection,
|
||||
DndContext,
|
||||
type DragEndEvent,
|
||||
KeyboardSensor,
|
||||
@@ -46,42 +45,6 @@ const SkeletonCell = () => (
|
||||
</Skeleton>
|
||||
);
|
||||
|
||||
/**
|
||||
* Safari-safe collision detection that validates getBoundingClientRect() properties
|
||||
* before using them. Safari can sometimes return DOMRect objects with undefined
|
||||
* properties (particularly 'top'), which causes dnd-kit to throw TypeErrors.
|
||||
*/
|
||||
const safariSafeClosestCenter: CollisionDetection = (args) => {
|
||||
const { droppableContainers } = args;
|
||||
|
||||
// Filter droppable containers to only include those with valid bounding rects
|
||||
const validDroppableContainers = droppableContainers.filter((container) => {
|
||||
const rect = container.rect.current;
|
||||
if (!rect) return false;
|
||||
|
||||
// Check if all required properties exist and are numbers
|
||||
return (
|
||||
typeof rect.top === "number" &&
|
||||
typeof rect.left === "number" &&
|
||||
typeof rect.right === "number" &&
|
||||
typeof rect.bottom === "number" &&
|
||||
typeof rect.width === "number" &&
|
||||
typeof rect.height === "number"
|
||||
);
|
||||
});
|
||||
|
||||
// If all containers were filtered out, return empty array (no collision)
|
||||
if (validDroppableContainers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Call the original closestCenter with validated containers
|
||||
return closestCenter({
|
||||
...args,
|
||||
droppableContainers: validDroppableContainers,
|
||||
});
|
||||
};
|
||||
|
||||
interface ResponseTableProps {
|
||||
data: TResponseTableData[];
|
||||
survey: TSurvey;
|
||||
@@ -265,7 +228,7 @@ export const ResponseTable = ({
|
||||
<div>
|
||||
<DndContext
|
||||
id="response-table"
|
||||
collisionDetection={safariSafeClosestCenter}
|
||||
collisionDetection={closestCenter}
|
||||
modifiers={[restrictToHorizontalAxis]}
|
||||
onDragEnd={handleDragEnd}
|
||||
sensors={sensors}>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
type CollisionDetection,
|
||||
DndContext,
|
||||
type DragEndEvent,
|
||||
KeyboardSensor,
|
||||
@@ -34,42 +33,6 @@ import { deleteContactAttributeKeyAction } from "../actions";
|
||||
import { generateAttributeTableColumns } from "./attribute-table-column";
|
||||
import { EditAttributeModal } from "./edit-attribute-modal";
|
||||
|
||||
/**
|
||||
* Safari-safe collision detection that validates getBoundingClientRect() properties
|
||||
* before using them. Safari can sometimes return DOMRect objects with undefined
|
||||
* properties (particularly 'top'), which causes dnd-kit to throw TypeErrors.
|
||||
*/
|
||||
const safariSafeClosestCenter: CollisionDetection = (args) => {
|
||||
const { droppableContainers } = args;
|
||||
|
||||
// Filter droppable containers to only include those with valid bounding rects
|
||||
const validDroppableContainers = droppableContainers.filter((container) => {
|
||||
const rect = container.rect.current;
|
||||
if (!rect) return false;
|
||||
|
||||
// Check if all required properties exist and are numbers
|
||||
return (
|
||||
typeof rect.top === "number" &&
|
||||
typeof rect.left === "number" &&
|
||||
typeof rect.right === "number" &&
|
||||
typeof rect.bottom === "number" &&
|
||||
typeof rect.width === "number" &&
|
||||
typeof rect.height === "number"
|
||||
);
|
||||
});
|
||||
|
||||
// If all containers were filtered out, return empty array (no collision)
|
||||
if (validDroppableContainers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Call the original closestCenter with validated containers
|
||||
return closestCenter({
|
||||
...args,
|
||||
droppableContainers: validDroppableContainers,
|
||||
});
|
||||
};
|
||||
|
||||
interface AttributesTableProps {
|
||||
contactAttributeKeys: TContactAttributeKey[];
|
||||
isReadOnly: boolean;
|
||||
@@ -267,7 +230,7 @@ export const AttributesTable = ({
|
||||
return (
|
||||
<div className="w-full">
|
||||
<DndContext
|
||||
collisionDetection={safariSafeClosestCenter}
|
||||
collisionDetection={closestCenter}
|
||||
modifiers={[restrictToHorizontalAxis]}
|
||||
onDragEnd={handleDragEnd}
|
||||
sensors={sensors}>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
type CollisionDetection,
|
||||
DndContext,
|
||||
type DragEndEvent,
|
||||
KeyboardSensor,
|
||||
@@ -33,42 +32,6 @@ import { Table, TableBody, TableCell, TableHeader, TableRow } from "@/modules/ui
|
||||
import { TContactTableData } from "../types/contact";
|
||||
import { generateContactTableColumns } from "./contact-table-column";
|
||||
|
||||
/**
|
||||
* Safari-safe collision detection that validates getBoundingClientRect() properties
|
||||
* before using them. Safari can sometimes return DOMRect objects with undefined
|
||||
* properties (particularly 'top'), which causes dnd-kit to throw TypeErrors.
|
||||
*/
|
||||
const safariSafeClosestCenter: CollisionDetection = (args) => {
|
||||
const { droppableContainers } = args;
|
||||
|
||||
// Filter droppable containers to only include those with valid bounding rects
|
||||
const validDroppableContainers = droppableContainers.filter((container) => {
|
||||
const rect = container.rect.current;
|
||||
if (!rect) return false;
|
||||
|
||||
// Check if all required properties exist and are numbers
|
||||
return (
|
||||
typeof rect.top === "number" &&
|
||||
typeof rect.left === "number" &&
|
||||
typeof rect.right === "number" &&
|
||||
typeof rect.bottom === "number" &&
|
||||
typeof rect.width === "number" &&
|
||||
typeof rect.height === "number"
|
||||
);
|
||||
});
|
||||
|
||||
// If all containers were filtered out, return empty array (no collision)
|
||||
if (validDroppableContainers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Call the original closestCenter with validated containers
|
||||
return closestCenter({
|
||||
...args,
|
||||
droppableContainers: validDroppableContainers,
|
||||
});
|
||||
};
|
||||
|
||||
interface ContactsTableProps {
|
||||
data: TContactTableData[];
|
||||
fetchNextPage: () => void;
|
||||
@@ -261,7 +224,7 @@ export const ContactsTable = ({
|
||||
return (
|
||||
<div className="w-full">
|
||||
<DndContext
|
||||
collisionDetection={safariSafeClosestCenter}
|
||||
collisionDetection={closestCenter}
|
||||
modifiers={[restrictToHorizontalAxis]}
|
||||
onDragEnd={handleDragEnd}
|
||||
sensors={sensors}>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
type CollisionDetection,
|
||||
DndContext,
|
||||
DragEndEvent,
|
||||
PointerSensor,
|
||||
@@ -57,42 +56,6 @@ import { MultiLanguageCard } from "@/modules/survey/multi-language-surveys/compo
|
||||
import { ConfirmationModal } from "@/modules/ui/components/confirmation-modal";
|
||||
import { isEndingCardValid, isWelcomeCardValid, validateElement } from "../lib/validation";
|
||||
|
||||
/**
|
||||
* Safari-safe collision detection that validates getBoundingClientRect() properties
|
||||
* before using them. Safari can sometimes return DOMRect objects with undefined
|
||||
* properties (particularly 'top'), which causes dnd-kit to throw TypeErrors.
|
||||
*/
|
||||
const safariSafeClosestCorners: CollisionDetection = (args) => {
|
||||
const { droppableContainers } = args;
|
||||
|
||||
// Filter droppable containers to only include those with valid bounding rects
|
||||
const validDroppableContainers = droppableContainers.filter((container) => {
|
||||
const rect = container.rect.current;
|
||||
if (!rect) return false;
|
||||
|
||||
// Check if all required properties exist and are numbers
|
||||
return (
|
||||
typeof rect.top === "number" &&
|
||||
typeof rect.left === "number" &&
|
||||
typeof rect.right === "number" &&
|
||||
typeof rect.bottom === "number" &&
|
||||
typeof rect.width === "number" &&
|
||||
typeof rect.height === "number"
|
||||
);
|
||||
});
|
||||
|
||||
// If all containers were filtered out, return empty array (no collision)
|
||||
if (validDroppableContainers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Call the original closestCorners with validated containers
|
||||
return closestCorners({
|
||||
...args,
|
||||
droppableContainers: validDroppableContainers,
|
||||
});
|
||||
};
|
||||
|
||||
interface ElementsViewProps {
|
||||
localSurvey: TSurvey;
|
||||
setLocalSurvey: React.Dispatch<SetStateAction<TSurvey>>;
|
||||
@@ -900,7 +863,7 @@ export const ElementsView = ({
|
||||
id="blocks"
|
||||
sensors={sensors}
|
||||
onDragEnd={onBlockCardDragEnd}
|
||||
collisionDetection={safariSafeClosestCorners}>
|
||||
collisionDetection={closestCorners}>
|
||||
<BlocksDroppable
|
||||
localSurvey={localSurvey}
|
||||
setLocalSurvey={setLocalSurvey}
|
||||
@@ -940,7 +903,7 @@ export const ElementsView = ({
|
||||
id="endings"
|
||||
sensors={sensors}
|
||||
onDragEnd={onEndingCardDragEnd}
|
||||
collisionDetection={safariSafeClosestCorners}>
|
||||
collisionDetection={closestCorners}>
|
||||
<SortableContext items={localSurvey.endings} strategy={verticalListSortingStrategy}>
|
||||
{localSurvey.endings.map((ending, index) => {
|
||||
return (
|
||||
|
||||
@@ -163,9 +163,6 @@ export const MultiLanguageCard: FC<MultiLanguageCardProps> = ({
|
||||
}
|
||||
} else {
|
||||
setIsMultiLanguageActivated(true);
|
||||
if (!open) {
|
||||
setOpen(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
type CollisionDetection,
|
||||
DndContext,
|
||||
DragEndEvent,
|
||||
PointerSensor,
|
||||
@@ -25,42 +24,6 @@ import {
|
||||
} from "@/modules/ui/components/dialog";
|
||||
import { DataTableSettingsModalItem } from "./data-table-settings-modal-item";
|
||||
|
||||
/**
|
||||
* Safari-safe collision detection that validates getBoundingClientRect() properties
|
||||
* before using them. Safari can sometimes return DOMRect objects with undefined
|
||||
* properties (particularly 'top'), which causes dnd-kit to throw TypeErrors.
|
||||
*/
|
||||
const safariSafeClosestCorners: CollisionDetection = (args) => {
|
||||
const { droppableContainers } = args;
|
||||
|
||||
// Filter droppable containers to only include those with valid bounding rects
|
||||
const validDroppableContainers = droppableContainers.filter((container) => {
|
||||
const rect = container.rect.current;
|
||||
if (!rect) return false;
|
||||
|
||||
// Check if all required properties exist and are numbers
|
||||
return (
|
||||
typeof rect.top === "number" &&
|
||||
typeof rect.left === "number" &&
|
||||
typeof rect.right === "number" &&
|
||||
typeof rect.bottom === "number" &&
|
||||
typeof rect.width === "number" &&
|
||||
typeof rect.height === "number"
|
||||
);
|
||||
});
|
||||
|
||||
// If all containers were filtered out, return empty array (no collision)
|
||||
if (validDroppableContainers.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Call the original closestCorners with validated containers
|
||||
return closestCorners({
|
||||
...args,
|
||||
droppableContainers: validDroppableContainers,
|
||||
});
|
||||
};
|
||||
|
||||
interface DataTableSettingsModalProps<T> {
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
@@ -103,7 +66,7 @@ export const DataTableSettingsModal = <T,>({
|
||||
id="table-settings"
|
||||
sensors={sensors}
|
||||
onDragEnd={handleDragEnd}
|
||||
collisionDetection={safariSafeClosestCorners}>
|
||||
collisionDetection={closestCorners}>
|
||||
<SortableContext items={columnOrder} strategy={verticalListSortingStrategy}>
|
||||
{columnOrder.map((columnId) => {
|
||||
if (columnId === "select" || columnId === "createdAt") return;
|
||||
|
||||
@@ -40,21 +40,29 @@ export const SurveyInline = (props: Omit<SurveyContainerProps, "containerId">) =
|
||||
isLoadingScript = true;
|
||||
try {
|
||||
const scriptUrl = props.appUrl ? `${props.appUrl}/js/surveys.umd.cjs` : "/js/surveys.umd.cjs";
|
||||
const response = await fetch(
|
||||
scriptUrl,
|
||||
process.env.NODE_ENV === "development" ? { cache: "no-store" } : {}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to load the surveys package");
|
||||
}
|
||||
// Load the script directly via src to ensure proper execution
|
||||
// This approach works with CSP and doesn't require blob URLs or eval
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const scriptElement = document.createElement("script");
|
||||
scriptElement.src = scriptUrl;
|
||||
scriptElement.type = "text/javascript";
|
||||
|
||||
const scriptContent = await response.text();
|
||||
const scriptElement = document.createElement("script");
|
||||
// Add cache-busting in development to ensure fresh script loads
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
scriptElement.src += `?t=${Date.now()}`;
|
||||
}
|
||||
|
||||
scriptElement.textContent = scriptContent;
|
||||
scriptElement.onload = () => {
|
||||
resolve();
|
||||
};
|
||||
scriptElement.onerror = () => {
|
||||
reject(new Error("Failed to load the surveys package"));
|
||||
};
|
||||
|
||||
document.head.appendChild(scriptElement);
|
||||
});
|
||||
|
||||
document.head.appendChild(scriptElement);
|
||||
setIsScriptLoaded(true);
|
||||
hasLoadedRef.current = true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -269,6 +269,7 @@ test.describe("Multi Language Survey Create", async () => {
|
||||
await page.getByText("Start from scratch").click();
|
||||
await page.getByRole("button", { name: "Create survey", exact: true }).click();
|
||||
await page.locator("#multi-lang-toggle").click();
|
||||
await page.getByText("Multiple languages").click();
|
||||
await page.getByRole("combobox").click();
|
||||
await page.getByLabel("English (en)").click();
|
||||
await page.getByRole("button", { name: "Confirm" }).click();
|
||||
|
||||
Reference in New Issue
Block a user