Initial commit: Plane
Some checks failed
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Admin Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Sync Repositories / sync_changes (push) Has been cancelled

Synced from upstream: 8853637e981ed7d8a6cff32bd98e7afe20f54362
This commit is contained in:
chuan
2025-11-07 00:00:52 +08:00
commit 8ebde8aa05
4886 changed files with 462270 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
import { useEffect, useRef, useState } from "react";
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
interface UseGroupDropTargetProps {
groupId: string;
enableDragDrop?: boolean;
onDrop?: (itemId: string, targetId: string | null, sourceGroupId: string, targetGroupId: string) => void;
}
interface DragSourceData {
id: string;
groupId: string;
type: "ITEM" | "GROUP";
}
/**
* A hook that turns an element into a valid drop target for group drag-and-drop.
*
* @returns groupRef (attach to the droppable container) and isDraggingOver (for visual feedback)
*/
export const useGroupDropTarget = ({ groupId, enableDragDrop = false, onDrop }: UseGroupDropTargetProps) => {
const groupRef = useRef<HTMLDivElement | null>(null);
const [isDraggingOver, setIsDraggingOver] = useState(false);
useEffect(() => {
const element = groupRef.current;
if (!element || !enableDragDrop || !onDrop) return;
const cleanup = dropTargetForElements({
element,
getData: () => ({ groupId, type: "GROUP" }),
canDrop: ({ source }) => {
const data = (source?.data || {}) as Partial<DragSourceData>;
return data.type === "ITEM" && !!data.groupId && data.groupId !== groupId;
},
onDragEnter: () => setIsDraggingOver(true),
onDragLeave: () => setIsDraggingOver(false),
onDrop: ({ source }) => {
setIsDraggingOver(false);
const data = (source?.data || {}) as Partial<DragSourceData>;
if (data.type !== "ITEM" || !data.id || !data.groupId) return;
if (data.groupId !== groupId) {
onDrop(data.id, null, data.groupId, groupId);
}
},
});
return cleanup;
}, [groupId, enableDragDrop, onDrop]);
return { groupRef, isDraggingOver };
};

View File

@@ -0,0 +1,58 @@
import { useEffect, useRef, useState, useCallback } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
type UseLayoutStateProps =
| {
mode: "external";
externalCollapsedGroups: string[];
externalOnToggleGroup: (groupId: string) => void;
enableAutoScroll?: boolean;
}
| {
mode?: "internal";
enableAutoScroll?: boolean;
};
/**
* Hook for managing layout state including:
* - Collapsed/expanded group tracking (internal or external)
* - Auto-scroll setup for drag-and-drop
*/
export const useLayoutState = (props: UseLayoutStateProps = { mode: "internal" }) => {
const containerRef = useRef<HTMLDivElement | null>(null);
// Internal fallback state
const [internalCollapsedGroups, setInternalCollapsedGroups] = useState<string[]>([]);
// Stable internal toggle function
const internalToggleGroup = useCallback((groupId: string) => {
setInternalCollapsedGroups((prev) =>
prev.includes(groupId) ? prev.filter((id) => id !== groupId) : [...prev, groupId]
);
}, []);
const useExternal = props.mode === "external";
const collapsedGroups = useExternal ? props.externalCollapsedGroups : internalCollapsedGroups;
const onToggleGroup = useExternal ? props.externalOnToggleGroup : internalToggleGroup;
// Enable auto-scroll for DnD
useEffect(() => {
const element = containerRef.current;
if (!element || !props.enableAutoScroll) return;
const cleanup = combine(
autoScrollForElements({
element,
})
);
return cleanup;
}, [props.enableAutoScroll]);
return {
containerRef,
collapsedGroups,
onToggleGroup,
};
};