- Remove unused Google Fonts links from index.html (no external CDN) - Add Privacy & Data settings section with: - Privacy posture indicator (data local, no analytics, no cloud sync) - Connection details panel (API, auth, DB, sandbox) - Data export button - Account deletion with confirmation - Add ShieldCheck icon to settings nav - Fix: DataTrustPanel import removed (was not used)
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
/**
|
|
* Sortable wrapper for a project (space) sidebar group card.
|
|
* Accepts an optional `handleSlot` so the parent can render a grip handle
|
|
* inside its own title row — this keeps the handle positioned correctly
|
|
* relative to the label.
|
|
*/
|
|
import { CSS } from "@dnd-kit/utilities";
|
|
import { useSortable } from "@dnd-kit/sortable";
|
|
import { memo, useMemo } from "react";
|
|
|
|
interface SortableGroupProps {
|
|
group: { spaceId: string; key: string; title?: string | null };
|
|
/** When provided, rendered alongside children inside the drag node. */
|
|
handleSlot?: React.ReactNode;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export const SortableGroup = memo(function SortableGroup({
|
|
group,
|
|
handleSlot,
|
|
children,
|
|
}: SortableGroupProps) {
|
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
id: group.spaceId,
|
|
});
|
|
|
|
const style: React.CSSProperties = useMemo(
|
|
() => ({
|
|
transform: CSS.Translate.toString(transform),
|
|
transition,
|
|
opacity: isDragging ? 0.5 : undefined,
|
|
zIndex: isDragging ? 1000 : undefined,
|
|
}),
|
|
[transform, transition, isDragging],
|
|
);
|
|
|
|
return (
|
|
<div ref={setNodeRef} style={style} data-drag-id={group.spaceId} {...attributes} {...listeners}>
|
|
{handleSlot}
|
|
{children}
|
|
</div>
|
|
);
|
|
});
|