@libs-ui/services-grid-layout 0.2.357-25 → 0.2.357-27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"libs-ui-services-grid-layout.mjs","sources":["../../../../../libs-ui/services/grid-layout/src/defines/gridster-config.define.ts","../../../../../libs-ui/services/grid-layout/src/defines/collision.define.ts","../../../../../libs-ui/services/grid-layout/src/tree.service.ts","../../../../../libs-ui/services/grid-layout/src/grid-layout.service.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.html","../../../../../libs-ui/services/grid-layout/src/drag-controller.ts","../../../../../libs-ui/services/grid-layout/src/index.ts","../../../../../libs-ui/services/grid-layout/src/libs-ui-services-grid-layout.ts"],"sourcesContent":["import { CompactType, DisplayGrid, GridsterConfig, GridType } from 'gridster18';\nimport { T_gridLayout_node } from '../interfaces/grid-layout.interface';\n\n/**\n * Cấu hình gridster cho lưới CẤP TRANG.\n *\n * Mọi giá trị dưới đây đều đến từ một lỗi đã đo được trên sản phẩm thật, không phải chọn theo cảm\n * tính. Đổi bất kỳ dòng nào có dấu 🔴 sẽ làm sống lại đúng lỗi ghi trong comment.\n */\nexport const gridLayoutRootConfig = (): GridsterConfig => ({\n // 🔴 VerticalFixed — CẤM đổi sang Fit hay ScrollVertical.\n // `Fit` chia đều chiều cao khung cho số hàng đang dùng, nên card khai `rows: 2` phình từ 124px lên\n // 247px. `ScrollVertical` KHÔNG đọc `fixedRowHeight` (mã lib: chỉ `Fixed` và `VerticalFixed` đọc).\n gridType: GridType.VerticalFixed,\n\n // 🔴 None — CẤM quay lại CompactUp.\n // `CompactUp` hút mọi khối lên sát nhau NGAY sau mỗi thao tác, nên:\n // · kéo mép dưới cho khối cao thêm → chỗ khối dưới vừa nhường bị hút lấp lại tức thì, cú kéo bị\n // `checkGridCollision` báo va chạm rồi HOÀN NGUYÊN (khối đứng im dù kéo);\n // · kéo thả đổi vị trí → khối vừa nhường chỗ bị hút về ngay, khối đang kéo không có chỗ đặt và\n // treo lơ lửng giữa hai khối.\n // Muốn dồn khít thì gọi `sapGon()` của service.\n compactType: CompactType.None,\n displayGrid: DisplayGrid.OnDragAndResize,\n\n // 🔴 pushItems: true — CẤM để false.\n // `swap` của lib CHỈ hoán vị được HAI KHỐI CÙNG KÍCH THƯỚC (mã lib `checkSwap`: tính diffX/diffY\n // rồi hoán vị, lệch kích thước thì `checkCollision` báo va chạm và hoàn nguyên). Khối 3x2 gặp\n // container 7x5 nên không swap được, mà `pushItems: false` cũng không cho container nhường đường\n // → BẾ TẮC: khối đang kéo không đặt được ở đâu.\n pushItems: true,\n // chỉ đẩy XUỐNG: đẩy ngang làm xô lệch bố cục cột người dùng vừa đặt\n pushDirections: { north: false, east: false, south: true, west: false },\n pushResizeItems: true,\n swap: true,\n swapWhileDragging: true,\n\n draggable: {\n enabled: true,\n // delayStart: 0 vì kéo qua tay cầm chuyên dụng (dragHandleClass) và ignoreContent: true.\n // Khi người dùng bấm vào thanh tay cầm là chủ động kéo, không cần trễ 160ms tránh huỷ kéo.\n delayStart: 0,\n // 🔴 `checkDragHandleClass` duyệt DOM từ chỗ bấm NGƯỢC LÊN CHA, và trên MỖI node nó kiểm\n // `dragHandleClass` TRƯỚC `ignoreContentClass`. Vì vậy một phần tử KHÔNG được mang cả hai class\n // cùng lúc — mang cả hai thì lib gặp tay cầm trước, trả `true`, class chặn không tới lượt.\n ignoreContentClass: 'libs-ui-grid-layout-block-parent-drag',\n ignoreContent: true,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle',\n },\n\n resizable: {\n enabled: true,\n // đủ 8 hướng như cửa sổ thường; chỉ có góc dưới-phải thì quá khó trúng\n handles: { s: true, e: true, n: true, w: true, se: true, ne: true, sw: true, nw: true },\n },\n\n margin: 12,\n outerMargin: true,\n outerMarginBottom: 40,\n minCols: 12,\n maxCols: 12,\n minRows: 2,\n\n // 🔴 KHÔNG giới hạn chiều cao khối. Lib có BA trần mặc định phải vô hiệu hoá CÙNG LÚC, thiếu một\n // cái là vẫn bị chặn: `maxItemRows: 50` · `maxItemCols: 50` · `maxItemArea: 2500` (trần DIỆN TÍCH\n // cols × rows — khó thấy nhất: khối 12 cột chỉ cần 209 hàng là đụng trần dù hai trần kia còn dư).\n // `maxRows` là trần của CẢ LƯỚI, cũng phải nới theo.\n maxRows: 5000,\n maxItemRows: 5000,\n maxItemCols: 12,\n maxItemArea: 60000,\n\n // 🔴 Trần LỚP CHỒNG. Mặc định của lib là 2 — quá thấp: khi bật chồng khối, thư viện gán mỗi khối\n // một lớp riêng để chúng khác nhau, nên chỉ 3 khối là đã đụng trần và các khối sau lại rơi về\n // cùng lớp, tức chồng nhau bị chặn trở lại.\n maxLayerIndex: 5000,\n\n setGridSize: true,\n fixedRowHeight: 56,\n defaultItemCols: 3,\n defaultItemRows: 2,\n minItemRows: 1,\n mobileBreakpoint: -1,\n});\n\n/**\n * Cấu hình cho lưới LỒNG (ruột một container).\n *\n * Kế thừa lưới trang rồi ghi đè phần khác biệt. Ba điểm quan trọng nhất: `setGridSize` phải TẮT,\n * tay cầm phải mang TÊN RIÊNG, và tự-cuộn-khi-kéo phải TẮT.\n */\nexport const gridLayoutNestedConfig = (): GridsterConfig => ({\n ...gridLayoutRootConfig(),\n\n // 🔴 PHẢI tắt cho lưới lồng. `setGridSize` làm gridster tự ghi style width/height lên CHÍNH nó,\n // sinh vòng lặp đo-rồi-ghi với ResizeObserver của khung ngoài (khung đổi → onResize xoá style →\n // setGridSize ghi lại) → lưới con co dần về 64x64px trong khung 868px.\n setGridSize: false,\n\n // khe 2px: khối con là các dòng thông tin của CÙNG một card, khe rộng làm chúng trông như card rời\n margin: 2,\n // Lưới lồng KHÔNG tự chừa lề — lề là của VỎ container (`containerPadding`), không phải của lưới.\n // Đặt ở vỏ thì ruột co lại đúng bằng phần còn lại, tay cầm resize của khối con luôn nằm trong tầm\n // chuột (người dùng chốt 28/08/2026: \"lưới cha có padding chứ ko phải con\").\n outerMargin: false,\n outerMarginBottom: 0,\n\n // hàng 16px cho bước kéo mịn, và sàn 1 hàng = 16px nên khối co được nhỏ hơn nhiều\n fixedRowHeight: 16,\n minRows: 1,\n minItemRows: 1,\n defaultItemCols: 2,\n defaultItemRows: 2,\n\n // 🔴 Tay cầm RIÊNG — CẤM dùng chung tên với lưới trang.\n // `checkDragHandleClass` trả `true` ở node ĐẦU TIÊN có `dragHandleClass`. Dùng chung một tên thì\n // lưới CHA cũng nhận ra tay cầm của khối con và nhấc luôn container.\n draggable: {\n ...gridLayoutRootConfig().draggable,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle-child',\n },\n\n // 🔴 KÉO MÉP thì khối dưới ĐỨNG YÊN, chỉ khoảng trống giữa hai khối co giãn. Bật (kế thừa từ lưới\n // trang) thì mỗi cú kéo đẩy dồn cả cột xuống — người dùng chỉ muốn một khối to hơn một chút mà cả\n // card dài ra. `pushItems` vẫn giữ: nó lo việc KÉO THẢ đổi chỗ, khác việc đổi kích thước.\n pushResizeItems: false,\n\n // 🔴 Tắt tự cuộn khi kéo tới sát mép. Lib thấy chuột gần biên là cuộn lưới theo\n // (`scrollSensitivity`), nhưng lưới con nằm trong card có `overflow: hidden` — cuộn ở đây đẩy khối\n // con ra NGOÀI khung container rồi kẹt luôn ở đó.\n disableScrollHorizontal: true,\n disableScrollVertical: true,\n});\n\n/**\n * Cây rỗng dùng khi chưa có dữ liệu — mặt phẳng vẽ ra một lưới trống thay vì vỡ.\n * Xảy ra trong nhịp giữa lúc component dựng và lúc `init()` chạy.\n */\nexport const emptyRootNode = (): T_gridLayout_node => ({ id: 'root', x: 0, y: 0, cols: 12, rows: 0, children: [] });\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n} from '../interfaces/grid-layout.interface';\nimport { uuid } from '@libs-ui/utils';\n\n/**\n * Checks whether the rectangular region [x, x + cols) x [y, y + rows)\n * is completely vacant among existing items.\n */\nexport const isRegionFree = (\n children: Array<T_gridLayout_node>,\n x: number,\n y: number,\n cols: number,\n rows: number,\n ignoredId?: string,\n): boolean => {\n for (const child of children) {\n if (ignoredId && child.id === ignoredId) {\n continue;\n }\n const hOverlap = !(child.x + child.cols <= x || child.x >= x + cols);\n const vOverlap = !(child.y + child.rows <= y || child.y >= y + rows);\n\n if (hOverlap && vOverlap) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Computes optimal (col, row) inside a group container.\n * Snaps flush to adjacent card right edge if slot is vacant.\n */\nexport const findSnapPositionInsideGroup = (\n children: Array<T_gridLayout_node>,\n rawCol: number,\n rawRow: number,\n innerCols: number,\n innerRows: number,\n totalCols = 24,\n): { col: number; row: number } => {\n let bestCandidate: { col: number; row: number; dist: number } | undefined;\n\n for (const child of children) {\n const rightEdge = child.x + child.cols;\n const canFit = rightEdge + innerCols <= totalCols;\n const isFree = canFit && isRegionFree(children, rightEdge, child.y, innerCols, innerRows);\n\n if (!isFree) {\n continue;\n }\n\n const nearX = Math.abs(rawCol - rightEdge) <= 2 || (rawCol >= child.x + Math.floor(child.cols / 2) && rawCol <= rightEdge + 1);\n const nearY = Math.abs(rawRow - child.y) <= 2;\n\n if (nearX && nearY) {\n const dist = Math.abs(rawCol - rightEdge) + Math.abs(rawRow - child.y);\n\n if (!bestCandidate || dist < bestCandidate.dist) {\n bestCandidate = { col: rightEdge, row: child.y, dist };\n }\n }\n }\n\n if (bestCandidate) {\n return { col: bestCandidate.col, row: bestCandidate.row };\n }\n\n const clampedCol = Math.max(0, Math.min(totalCols - innerCols, rawCol));\n const clampedRow = Math.max(0, rawRow);\n\n return { col: clampedCol, row: clampedRow };\n};\n\n/**\n * Adjusts position of pair if horizontal overlap occurs.\n */\nconst adjustItemPair = (a: T_gridLayout_node, b: T_gridLayout_node): boolean => {\n const hOverlap = !(a.x + a.cols <= b.x || a.x >= b.x + b.cols);\n\n if (hOverlap && b.y < a.y + a.rows) {\n b.y = a.y + a.rows;\n\n return true;\n }\n\n return false;\n};\n\n/**\n * Resolves vertical collisions when inserting a new card at (newNode.x, newNode.y).\n * Any existing card that horizontally overlaps and whose vertical span overlaps\n * or is below the insertion point is pushed down so there is no overlap.\n */\nexport const resolveCollisionsAndInsert = (\n children: Array<T_gridLayout_node>,\n newNode: T_gridLayout_node,\n): void => {\n const items = [...children];\n\n for (const item of items) {\n const hOverlap = !(item.x + item.cols <= newNode.x || item.x >= newNode.x + newNode.cols);\n const vOverlap = !(item.y + item.rows <= newNode.y || item.y >= newNode.y + newNode.rows);\n\n if (hOverlap && vOverlap) {\n item.y = newNode.y + newNode.rows;\n }\n }\n\n items.sort((a, b) => a.y - b.y);\n let changed = true;\n\n while (changed) {\n changed = false;\n for (let i = 0; i < items.length; i++) {\n for (let j = i + 1; j < items.length; j++) {\n changed = adjustItemPair(items[i], items[j]) || changed;\n }\n }\n }\n\n children.push(newNode);\n};\n\nexport function parseDropPayload<T>(activePayload: T | undefined, dataTransfer: DataTransfer | null): T | undefined {\n if (activePayload) {\n return activePayload;\n }\n if (dataTransfer) {\n try {\n const raw = dataTransfer.getData('application/json');\n\n if (raw) {\n return JSON.parse(raw) as T;\n }\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n}\n\ninterface I_hoveredGroup {\n groupNode: T_gridLayout_node;\n groupGridster: HTMLElement;\n}\n\nexport const findHoveredGroup = (\n elements: Element[],\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n): I_hoveredGroup | undefined => {\n const rootGridster = canvasContainer.querySelector('gridster');\n\n for (const el of elements) {\n const gridsterEl = (el.tagName.toLowerCase() === 'gridster' ? el : el.closest('gridster')) as HTMLElement | null;\n\n if (gridsterEl && gridsterEl !== rootGridster) {\n const outerItem = gridsterEl.closest('gridster-item');\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = outerItem ? rootItems.indexOf(outerItem) : -1;\n\n if (idx >= 0 && root.children?.[idx]) {\n return { groupNode: root.children[idx], groupGridster: gridsterEl };\n }\n }\n }\n\n for (const el of elements) {\n const itemEl = el.tagName.toLowerCase() === 'gridster-item' ? el : el.closest('gridster-item');\n if (!itemEl) {\n continue;\n }\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = rootItems.indexOf(itemEl);\n if (idx >= 0 && root.children?.[idx]) {\n const node = root.children[idx];\n if ((node.children?.length ?? 0) > 0) {\n return { groupNode: node, groupGridster: (itemEl.querySelector('gridster') as HTMLElement | null) ?? (itemEl as HTMLElement) };\n }\n }\n }\n\n return undefined;\n};\n\n/**\n * Calculates snapped spatial coordinates and pixel dimensions for drop ghost preview box.\n */\nexport const calculateDropGhost = (\n event: DragEvent,\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n payload: T_gridLayout_externalDragPayload,\n totalCols = 24,\n // 🔴 Chiều cao một hàng lưới, tính bằng pixel. Trước đây đóng cứng 68 nên khung xem trước vẽ sai cỡ\n // ở mặt phẳng có hàng thấp, nơi dùng phải ẩn khung của thư viện rồi tự vẽ lại.\n rowStep = 68,\n): T_gridLayout_dropGhost | undefined => {\n if (typeof document === 'undefined' || !canvasContainer) {\n return undefined;\n }\n\n const cardTitle = payload.title || 'Thẻ';\n const cardIconClass = payload.iconClass;\n const cardIconText = payload.iconText;\n const payloadAny = payload as Record<string, unknown>;\n let defaultCols = typeof payload.cols === 'number'\n ? payload.cols\n : (typeof payloadAny['defaultCols'] === 'number' ? (payloadAny['defaultCols'] as number) : (totalCols >= 24 ? 12 : 6));\n let defaultRows = typeof payload.rows === 'number'\n ? payload.rows\n : (typeof payloadAny['defaultRows'] === 'number' ? (payloadAny['defaultRows'] as number) : 4);\n\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sample = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(false);\n if (sample) {\n if (typeof sample.cols === 'number') { defaultCols = sample.cols; }\n if (typeof sample.rows === 'number') { defaultRows = sample.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n\n const stageEl = (canvasContainer.querySelector('#bi-canvas-stage') as HTMLElement | null) ?? canvasContainer;\n const stageRect = stageEl.getBoundingClientRect();\n\n const rootGridster = stageEl.querySelector('gridster') as HTMLElement | null;\n const gridsterEl = rootGridster ?? stageEl;\n const gridsterRect = gridsterEl.getBoundingClientRect();\n const unscaledWidth = gridsterEl.offsetWidth || gridsterEl.clientWidth || 0;\n const zoom = (gridsterRect.width && unscaledWidth > 0)\n ? Math.max(0.2, Math.min(3, gridsterRect.width / unscaledWidth))\n : 1;\n\n const elements = typeof document.elementsFromPoint === 'function'\n ? document.elementsFromPoint(event.clientX, event.clientY)\n : [];\n const hovered = findHoveredGroup(elements, canvasContainer, root);\n\n const stageMouseX = (event.clientX - stageRect.left) / zoom;\n const stageMouseY = (event.clientY - stageRect.top) / zoom;\n\n if (hovered) {\n const { groupNode, groupGridster } = hovered;\n const groupGridsterRect = groupGridster.getBoundingClientRect();\n const groupStageLeft = (groupGridsterRect.left - stageRect.left) / zoom;\n const groupStageTop = (groupGridsterRect.top - stageRect.top) / zoom;\n\n let innerCols = defaultCols;\n let innerRows = defaultRows;\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sampleInside = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(true);\n if (sampleInside) {\n if (typeof sampleInside.cols === 'number') { innerCols = sampleInside.cols; }\n if (typeof sampleInside.rows === 'number') { innerRows = sampleInside.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n innerCols = Math.min(innerCols, totalCols);\n\n const groupWidth = groupGridster.clientWidth || (groupGridsterRect.width / zoom) || 400;\n const colStep = (groupWidth + 2) / totalCols;\n const rowStep = 18;\n const relX = (event.clientX - groupGridsterRect.left) / zoom + groupGridster.scrollLeft;\n const relY = (event.clientY - groupGridsterRect.top) / zoom + groupGridster.scrollTop;\n const rawCol = Math.floor(relX / colStep);\n const rawRow = Math.floor(relY / rowStep);\n const snap = findSnapPositionInsideGroup(\n groupNode.children ?? [],\n rawCol,\n rawRow,\n innerCols,\n innerRows,\n totalCols,\n );\n\n return {\n col: snap.col,\n row: snap.row,\n cols: innerCols,\n rows: innerRows,\n pixelLeft: groupStageLeft + snap.col * colStep,\n pixelTop: groupStageTop + snap.row * rowStep,\n pixelWidth: Math.max(30, innerCols * colStep - 2),\n pixelHeight: Math.max(20, innerRows * rowStep - 2),\n isInsideGroup: true,\n targetParentId: groupNode.id,\n groupTitle: 'Khối ghép',\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: groupGridster as HTMLElement,\n };\n }\n\n const margin = 12;\n const gridsterWidth = unscaledWidth || gridsterEl.clientWidth || 1200;\n const colStep = Math.max(20, (gridsterWidth - margin) / totalCols);\n const gridsterStageLeft = (gridsterRect.left - stageRect.left) / zoom;\n const gridsterStageTop = (gridsterRect.top - stageRect.top) / zoom;\n const relX = stageMouseX - gridsterStageLeft + gridsterEl.scrollLeft - margin;\n const relY = stageMouseY - gridsterStageTop + gridsterEl.scrollTop - margin;\n const itemCols = Math.min(defaultCols, totalCols);\n const col = Math.max(0, Math.min(totalCols - itemCols, Math.floor(relX / colStep)));\n const row = Math.max(0, Math.floor(relY / rowStep));\n\n return {\n col,\n row,\n cols: itemCols,\n rows: defaultRows,\n pixelLeft: gridsterStageLeft + margin + col * colStep,\n pixelTop: gridsterStageTop + margin + row * rowStep,\n pixelWidth: itemCols * colStep - margin,\n pixelHeight: defaultRows * rowStep - margin,\n isInsideGroup: false,\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: (rootGridster as HTMLElement) ?? undefined,\n };\n};\n\n\n/** Tìm khối theo id trong cây, đi sâu vào mọi container. */\nexport const findNodeRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n if (root.id === id) {\n return root;\n }\n\n for (const child of root.children ?? []) {\n const found = findNodeRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/** Tìm khối CHA trực tiếp của một khối, đi sâu vào mọi container. */\nexport const findParentRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n for (const child of root.children ?? []) {\n if (child.id === id) {\n return root;\n }\n\n const found = findParentRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/**\n * Thả khối vào đúng ô mà ghost đang chỉ, đẩy các khối va chạm xuống dưới.\n *\n * Ghost đang nằm trong một container (`isInsideGroup`) thì thả vào ruột container đó; không tìm thấy\n * container thì trả `false` chứ KHÔNG rơi về lưới gốc — thả nhầm cấp khó nhận ra hơn là không thả.\n */\nexport const dropNodeAtCoordinates = (\n root: T_gridLayout_node,\n ghost: T_gridLayout_dropGhost,\n newNode: T_gridLayout_newNode\n): boolean => {\n const nodeToAdd: T_gridLayout_node = {\n ...newNode,\n id: newNode.id ?? uuid(),\n x: ghost.col,\n y: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n };\n\n if (ghost.isInsideGroup && ghost.targetParentId) {\n const parentNode = findNodeRecursive(root, ghost.targetParentId);\n\n if (!parentNode) {\n return false;\n }\n parentNode.children = parentNode.children ?? [];\n resolveCollisionsAndInsert(parentNode.children, nodeToAdd);\n\n return true;\n }\n\n root.children = root.children ?? [];\n resolveCollisionsAndInsert(root.children, nodeToAdd);\n\n return true;\n};\n\n\n/** Khối có phải CONTAINER không — tức có khối con bên trong. */\nexport const isContainerNode = (node: T_gridLayout_node): boolean => (node.children?.length ?? 0) > 0;\n\n/** Khối có nằm LỒNG bên trong một container không (không phải con trực tiếp của gốc). */\nexport const isNodeNestedInside = (root: T_gridLayout_node | undefined, nodeId: string): boolean => {\n if (!root?.children) {\n return false;\n }\n\n return !root.children.some((child) => child.id === nodeId);\n};\n\n/**\n * Có được đổi khối đơn ↔ container không.\n *\n * 🔴 Ba hàm cờ này PHẢI là nguồn duy nhất cho cả thanh công cụ của thư viện lẫn menu do nơi dùng tự\n * dựng. Trước đây nơi dùng phải chép lại quy tắc để dựng menu trước lúc render, và hai bản lệch nhau\n * mỗi khi thư viện đổi trần lồng cấp mà không có gì báo.\n */\nexport const canToggleTypeNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) || !isNodeNestedInside(root, node.id);\n\n/** Có được thêm khối vào BÊN TRONG khối này không. */\nexport const canAddInsideNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) && !isNodeNestedInside(root, node.id);\n","import { Injectable } from '@angular/core';\nimport { uuid } from '@libs-ui/utils';\nimport { T_gridLayout_newNode, T_gridLayout_node } from './interfaces/grid-layout.interface';\nimport { resolveCollisionsAndInsert } from './defines/collision.define';\n\n/**\n * Thao tác trên cây khối: tìm, thêm, xoá, dồn khít, chặn lồng cấp quá sâu.\n *\n * 🔴 NỘI BỘ thư viện — không xuất ra ngoài. Nơi dùng đi qua `LibsUiGridLayoutService`, ở đó mỗi\n * thao tác sửa bố cục vừa vẽ lại vừa bắn `outChange` đúng MỘT lần. Các hàm ở đây cố tình KHÔNG tự\n * vẽ lại: để chúng tự gọi thì mỗi thao tác vẽ hai lượt và bắn hai sự kiện (người dùng chốt\n * 28/08/2026: \"đặt đúng các điểm mà làm cho layout có thể thay đổi thôi\").\n */\n@Injectable()\nexport class LibsUiGridLayoutTreeService {\n findById(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n if (node.id === id) {\n return node;\n }\n\n for (const child of node.children ?? []) {\n const found = this.findById(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n findParent(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n for (const child of node.children ?? []) {\n if (child.id === id) {\n return node;\n }\n\n const found = this.findParent(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n /**\n * Thêm khối vào cuối một container. Thư viện tự sinh `id` và tự đặt `x` · `y` xuống hàng trống.\n *\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addChild(root: T_gridLayout_node, parentId: string, item: T_gridLayout_newNode): T_gridLayout_node | undefined {\n const parent = this.findById(root, parentId);\n\n if (!parent) {\n return undefined;\n }\n\n parent.children = parent.children ?? [];\n // 🔴 Thư viện tự sinh `id`. Đây là mã máy dùng để tra cứu, không phải thứ người dùng nghĩ ra —\n // bắt họ tự đặt là mời họ tạo trùng, mà trùng id thì `findById` trả nhầm khối và cả cây hỏng\n // im lặng (người dùng chốt 28/08/2026).\n // 🔴 Mặc định VẪN tự xếp xuống hàng trống kế tiếp — giữ nguyên hành vi cũ.\n //\n // Chỉ khi nơi dùng bật `keepPosition` mới giữ `x`/`y` truyền vào. CẤM suy ra ý định từ chính giá\n // trị toạ độ (kiểu `item.y ?? ...`): `y: 0` là giá trị hợp lệ và cũng là thứ mọi hàm dựng node\n // điền sẵn, nên không tài nào phân biệt \"người ta muốn đặt ở hàng 0\" với \"người ta không quan\n // tâm\" — đoán sai là khối mới ĐÈ lên khối đang có.\n const node: T_gridLayout_node = {\n ...item,\n id: item.id ?? uuid(),\n x: item.keepPosition ? (item.x ?? 0) : 0,\n y: item.keepPosition ? (item.y ?? 0) : this.nextFreeRow(parent.children),\n };\n\n // Cờ điều khiển, không phải dữ liệu của khối — không để nó nằm lại trong cây.\n delete (node as Partial<T_gridLayout_newNode>).keepPosition;\n\n parent.children.push(node);\n\n // Trả về khối vừa tạo để nơi dùng biết `id` thư viện vừa sinh.\n return node;\n }\n\n /**\n * Thêm khối vào vị trí (x, y) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertWithCollision(\n root: T_gridLayout_node,\n parentId: string | undefined,\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n ): T_gridLayout_node | undefined {\n const targetParent = parentId ? this.findById(root, parentId) : root;\n\n if (!targetParent) {\n return undefined;\n }\n\n targetParent.children = targetParent.children ?? [];\n const node: T_gridLayout_node = {\n ...item,\n id: item.id ?? uuid(),\n x: targetCol,\n y: targetRow,\n };\n\n resolveCollisionsAndInsert(targetParent.children, node);\n\n return node;\n }\n\n /** Xoá một khối khỏi cây. Không cho xoá gốc. */\n removeById(root: T_gridLayout_node, id: string): boolean {\n if (root.id === id) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n if (!parent?.children) {\n return false;\n }\n\n parent.children = parent.children.filter((item) => item.id !== id);\n\n return true;\n }\n\n /**\n * Chuyển một khối đơn thành CONTAINER: nội dung cũ trở thành khối con đầu tiên.\n *\n * Không mất dữ liệu — `data` của khối được mang theo xuống khối con.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối đã là container rồi.\n */\n toContainer(root: T_gridLayout_node, id: string, colCount: number): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) > 0) {\n return false;\n }\n\n node.children = [{ ...node, id: uuid(), x: 0, y: 0, cols: colCount, rows: 4, children: [] }];\n\n return true;\n }\n\n /**\n * Chuyển một CONTAINER về khối đơn: các khối con được NÂNG lên cấp trên, không bị xoá.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối vốn không phải container.\n */\n toSingle(root: T_gridLayout_node, id: string): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) === 0) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n for (const child of node.children ?? []) {\n parent?.children?.push({ ...child, cols: node.cols, rows: 2 });\n }\n\n node.children = [];\n\n return true;\n }\n\n /**\n * Làm phẳng mọi container lồng vượt trần.\n *\n * 🔴 Cần thiết vì bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện. Một bản lưu cũ — sinh\n * trước khi có trần, hoặc do thao tác lỗi — vẫn nạp thẳng vào và hiện container lồng container.\n * Container vượt trần bị hạ thành khối thường, con của nó nâng lên cấp trên: KHÔNG mất dữ liệu.\n *\n * @returns số container đã làm phẳng\n */\n flattenOverDepthContainers(node: T_gridLayout_node, maxDepth: number): number {\n return this.walkFlatten(node, 0, maxDepth);\n }\n\n /**\n * Dồn khối khít lên trên theo thứ tự đọc, lấp hết chỗ trống.\n *\n * 🔴 KHÔNG sửa `node.rows` của container. Chiều cao container tính theo đơn vị hàng của lưới CHA,\n * còn `currentRow` đếm theo đơn vị hàng của lưới CON — trộn hai thang đo là container phình lên\n * gấp mấy lần.\n */\n compact(node: T_gridLayout_node, colCount: number): void {\n this.walkCompact(node, colCount);\n }\n\n private walkCompact(node: T_gridLayout_node, colCount: number): void {\n const children = node.children;\n\n if (!children?.length) {\n return;\n }\n\n const inReadingOrder = [...children].sort((a, b) => a.y - b.y || a.x - b.x);\n let currentRow = 0;\n let usedCols = 0;\n let tallestInRow = 0;\n\n for (const item of inReadingOrder) {\n const width = Math.min(item.cols, colCount);\n\n if (usedCols > 0 && usedCols + width > colCount) {\n currentRow += tallestInRow;\n usedCols = 0;\n tallestInRow = 0;\n }\n\n item.x = usedCols;\n item.y = currentRow;\n item.cols = width;\n usedCols += width;\n tallestInRow = Math.max(tallestInRow, item.rows);\n\n if ((item.children?.length ?? 0) > 0) {\n this.walkCompact(item, colCount);\n }\n }\n }\n\n private walkFlatten(node: T_gridLayout_node, containerDepth: number, maxDepth: number): number {\n const children = node.children;\n\n if (!children?.length) {\n return 0;\n }\n\n let fixedCount = 0;\n const result: Array<T_gridLayout_node> = [];\n\n for (const child of children) {\n const isContainer = (child.children?.length ?? 0) > 0;\n\n if (isContainer && containerDepth >= maxDepth) {\n fixedCount += 1;\n\n for (const item of child.children ?? []) {\n fixedCount += this.walkFlatten(item, containerDepth, maxDepth);\n result.push(item);\n }\n\n continue;\n }\n\n fixedCount += this.walkFlatten(child, isContainer ? containerDepth + 1 : containerDepth, maxDepth);\n result.push(child);\n }\n\n node.children = result;\n\n return fixedCount;\n }\n\n private nextFreeRow(children: Array<T_gridLayout_node>): number {\n return children.reduce((max, child) => Math.max(max, child.y + child.rows), 0);\n }\n}\n","import { ComponentRef, DestroyRef, Injectable, TemplateRef, ViewContainerRef, inject, signal } from '@angular/core';\nimport { GridsterComponentInterface, GridsterConfig, GridsterItem } from 'gridster18';\nimport { cloneDeep } from '@libs-ui/utils';\nimport { Subscription, take } from 'rxjs';\nimport { gridLayoutNestedConfig, gridLayoutRootConfig } from './defines/gridster-config.define';\nimport { findNodeRecursive, findParentRecursive } from './defines/collision.define';\nimport { LibsUiGridLayoutTreeService } from './tree.service';\nimport {\n E_gridLayout_mode_string,\n T_gridLayout_changeEvent,\n T_gridLayout_newNode,\n T_gridLayout_config,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\n\n/**\n * Dựng một mặt phẳng kéo thả và tự gắn component của nơi dùng lên từng khối.\n *\n * Nơi dùng chỉ cần đưa vào: loại component muốn dựng\n * (`nodeComponentType`) và cây dữ liệu (`data`). Toàn bộ việc vẽ lưới, kéo thả, đổi kích thước,\n * lồng container và dọn dẹp do thư viện lo.\n *\n * 🔴 Đây là service theo TỪNG mặt phẳng, KHÔNG `providedIn: 'root'`. Khai trong `providers` của\n * component dùng nó; hai mặt phẳng trên cùng một màn phải là hai thực thể riêng, dùng chung thì\n * `componentRefs` của mặt phẳng này bị mặt phẳng kia dọn mất.\n */\n@Injectable()\nexport class LibsUiGridLayoutService {\n // 🔴 TỰ TẠO, không `inject`. Nơi dùng chỉ phải viết `providers: [LibsUiGridLayoutService]` —\n // không phải biết bên trong thư viện còn service nào khác (người dùng chốt 28/08/2026).\n // `TreeService` không giữ trạng thái dùng chung nên mỗi mặt phẳng một bản là đúng.\n private readonly treeService = new LibsUiGridLayoutTreeService();\n /** Lượt tải component đang chờ, theo id khối — để huỷ khi khối bị gỡ giữa chừng. */\n private readonly pendingLoads = new Map<string, Subscription>();\n /**\n * Bộ theo dõi bề rộng của từng lưới LỒNG, để ngắt khi service bị huỷ.\n *\n * 🔴 Giữ tham chiếu là BẮT BUỘC: `ResizeObserver` không tự tắt theo vòng đời component. Không dọn\n * thì mỗi lần nạp lại bố cục (đổi tab) lại chồng thêm một bộ, và chúng vẫn chạy trên DOM đã gỡ.\n */\n private readonly nestedResizeObservers = new Set<ResizeObserver>();\n\n constructor() {\n // 🔴 Service khai trong `providers` của component nên Angular huỷ nó cùng component — thư viện\n // tự dọn ở đây, nơi dùng KHÔNG phải gọi `destroy()` trong `ngOnDestroy` (người dùng chốt\n // 28/08/2026). Bắt nhớ một bước dọn dẹp là kiểu API dễ quên, và quên thì rò rỉ bộ nhớ im lặng.\n inject(DestroyRef).onDestroy(() => this.destroy());\n }\n\n private config?: T_gridLayout_config;\n private readonly componentRefs = new Map<string, ComponentRef<unknown>>();\n\n private readonly rootNode = signal<T_gridLayout_node | undefined>(undefined);\n private readonly editMode = signal<boolean>(false);\n /** tăng mỗi lần cây đổi — component con đọc để biết phải tính lại */\n private readonly version = signal<number>(0);\n private readonly zoomLevel = signal<number>(1);\n\n /**\n * Signal chỉ đọc để nơi dùng theo dõi.\n *\n * 🔴 Là THUỘC TÍNH, không phải getter. Getter trả signal thì chỗ đọc phải viết `Version()()` —\n * quên cặp ngoặc thứ hai là computed KHÔNG phụ thuộc vào nó, cây đổi mà lưới đứng im, và\n * TypeScript không hề báo lỗi (đo 28/08/2026: thêm khối không hiện, sắp gọn không nhúc nhích).\n */\n readonly Root = this.rootNode.asReadonly();\n readonly IsEditMode = this.editMode.asReadonly();\n /** tăng mỗi lần cây hoặc cấu hình đổi */\n readonly Version = this.version.asReadonly();\n readonly Zoom = this.zoomLevel.asReadonly();\n\n /**\n * trần số cấp container lồng nhau — canvas đọc để biết có cho chuyển thành container không */\n private maxContainerDepth(): number {\n return this.config?.maxContainerDepth ?? 1;\n }\n\n /**\n * lề trong của container, px — canvas đọc để đặt padding lên vỏ container */\n private containerPadding(): number {\n return this.config?.containerPadding ?? 12;\n }\n\n /** Khởi tạo mặt phẳng. Gọi lại sẽ dọn sạch component cũ rồi dựng lại từ đầu. */\n init(config: T_gridLayout_config): void {\n this.destroy();\n this.config = config;\n // 🔴 Bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện: bản lưu cũ (sinh trước khi có trần,\n // hoặc do thao tác lỗi) vẫn mang container lồng container. Trần `maxContainerDepth` chỉ ẩn NÚT\n // trên canvas — nó không sửa dữ liệu, nên thiếu dòng này là vẽ ra đúng cây quá sâu đó.\n // Nơi dùng KHÔNG tự gọi được: `LibsUiGridLayoutTreeService` cố ý không xuất.\n this.treeService.flattenOverDepthContainers(config.data, this.maxContainerDepth());\n this.assignOverlapLayers(config.data);\n // 🔴 Nhân bản như `refresh()`: `init()` lại (đổi chế độ, bật/tắt chồng khối) trên CÙNG object cây\n // thì `@for` không dựng lại `gridster-item`, nên `layerIndex` vừa gán không tới `$item` và khối\n // vẫn không đè nhau được (đo 28/08/2026: `item.layerIndex` = 1|2|3|4|7 mà `$item.layerIndex`\n // toàn `undefined`).\n this.rootNode.set(this.shallowCloneTree(config.data));\n this.editMode.set(config.isEditMode ?? false);\n\n let initialZoom = config.initialZoom ?? 1;\n if (config.storageKey && typeof localStorage !== 'undefined') {\n try {\n const saved = localStorage.getItem(config.storageKey);\n if (saved) {\n const parsed = parseFloat(saved);\n const min = config.zoomMin ?? 0.4;\n const max = config.zoomMax ?? 1.5;\n if (!isNaN(parsed) && parsed >= min && parsed <= max) {\n initialZoom = parsed;\n }\n }\n } catch {\n // ignore localStorage access error\n }\n }\n this.zoomLevel.set(initialZoom);\n\n this.version.update((v) => v + 1);\n }\n\n setEditMode(value: boolean): void {\n this.editMode.set(value);\n // 🔴 PHẢI bơm `version`: `gridsterOptions()` đọc `editMode` để bật/tắt kéo–thả, mà computed\n // `gridOptions` bên canvas chỉ chạy lại khi `Version` đổi. Thiếu dòng này thì đổi chế độ xong\n // gridster vẫn giữ options cũ — chuyển sang XEM mà khối vẫn kéo được.\n this.version.update((v) => v + 1);\n }\n\n /**\n * Bật/tắt cho khối chồng lên nhau — KHÔNG dựng lại mặt phẳng.\n *\n * Trước đây nơi dùng phải gọi `init()` lại để đổi cờ này, mà `init()` huỷ sạch rồi dựng lại mọi\n * component nội dung — lãng phí, và người dùng thấy màn chớp (người dùng chốt 28/08/2026).\n */\n setAllowOverlap(value: boolean): void {\n if (!this.config) {\n return;\n }\n\n this.config = { ...this.config, allowOverlap: value };\n\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n // 🔴 Gán lớp vào CÂY ĐANG VẼ (`rootNode`), KHÔNG phải `config.data`.\n // `init()` đã clone `config.data` sang `rootNode` nên hai object KHÁC nhau; gán vào `config.data`\n // thì `refresh()` clone lại từ `rootNode` — lớp vừa gán không tới `gridster-item` nào, `z-index`\n // của mọi khối đứng ở `1` và khối nào vẽ sau thì nằm trên: chồng khối \"lúc được lúc không\"\n // (đo 04/09/2026: `item.layerIndex` undefined, `getLayerIndex()` = 0 cho cả 8 khối).\n this.assignOverlapLayers(root);\n // Thay tham chiếu cây để `layerIndex` vừa gán tới được `$item` của gridster; component nội dung\n // KHÔNG bị dựng lại vì `attachNode` nhận ra id cũ và chỉ `setInput`.\n this.refresh();\n }\n\n /**\n *\n * Cấu hình gridster cho một cấp lưới.\n *\n * @param depth 0 = lưới cấp trang, ≥ 1 = lưới lồng trong container\n */\n private buildGridsterOptions(depth: number, itemChangeCallback?: () => void): GridsterConfig {\n const base = depth === 0 ? gridLayoutRootConfig() : gridLayoutNestedConfig();\n const config = this.config;\n\n if (!config) {\n return base;\n }\n\n const isFreeMode = config.mode === E_gridLayout_mode_string.free;\n const canEdit = this.editMode();\n const canOverlap = isFreeMode || (config.allowOverlap ?? false);\n\n return {\n ...base,\n scale: this.zoomLevel(),\n ...(config.cols ? { minCols: config.cols, maxCols: config.cols, maxItemCols: config.cols } : {}),\n ...(config.rowHeight && depth === 0 ? { fixedRowHeight: config.rowHeight } : {}),\n ...(depth === 0 && config.minRows !== undefined ? { minRows: config.minRows } : {}),\n ...(depth > 0 && config.nestedMinRows !== undefined ? { minRows: config.nestedMinRows } : {}),\n // Khe và chiều cao hàng khác nhau theo cấp: lưới trang thoáng, lưới lồng khít.\n ...(depth === 0 && config.margin !== undefined ? { margin: config.margin } : {}),\n ...(depth > 0 && config.nestedMargin !== undefined ? { margin: config.nestedMargin } : {}),\n ...(depth > 0 && config.nestedRowHeight !== undefined ? { fixedRowHeight: config.nestedRowHeight } : {}),\n ...(depth === 0 && config.outerMargin !== undefined ? { outerMargin: config.outerMargin } : {}),\n ...(depth === 0 && config.outerMarginBottom !== undefined ? { outerMarginBottom: config.outerMarginBottom } : {}),\n ...(config.minItemRows !== undefined ? { minItemRows: config.minItemRows } : {}),\n ...(config.defaultItemCols !== undefined ? { defaultItemCols: config.defaultItemCols } : {}),\n ...(config.defaultItemRows !== undefined ? { defaultItemRows: config.defaultItemRows } : {}),\n\n // 🔴 Chế độ XEM phải TẮT hẳn kéo và đổi kích thước.\n // `base` luôn để `enabled: true`; không ghi đè theo `editMode` thì người xem vẫn kéo được khối\n // và đổi bố cục của người khác (người dùng báo 28/08/2026: \"đang xem mà vẫn kéo thả thay đổi\n // vị trí và thêm khối được\").\n draggable: { ...base.draggable, enabled: canEdit },\n resizable: { ...base.resizable, enabled: canEdit },\n\n // Chế độ tự do LUÔN cho chồng; chế độ lưới thì theo cờ của nơi dùng.\n allowMultiLayer: canOverlap,\n // 🔴 Bật `allowMultiLayer` MỘT MÌNH không đủ. Mã lib so `layerIndex` của hai khối: KHÁC nhau\n // thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n // `defaultLayerIndex` — tức cùng lớp, và vẫn bị đẩy nhau như lưới thường (người dùng báo\n // 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n // Cho chồng thì phải TẮT đẩy khối, nếu không khối bị dạt đi trước khi kịp đè lên nhau.\n ...(canOverlap ? { pushItems: false, pushResizeItems: false, swap: false, swapWhileDragging: false } : {}),\n\n ...this.buildNestedResizeHooks(base, depth),\n\n itemChangeCallback: (item: GridsterItem) => {\n // 🔴 Khối vừa thao tác phải lên LỚP TRÊN CÙNG.\n // `layerIndex` gán một lần theo thứ tự cây lúc khởi tạo, nên khối kéo lên chỉ nổi TRONG LÚC\n // kéo (nhờ `z-index: 30` của lớp `gridster-item-moving`); thả tay ra là về lớp cũ và bị khối\n // đứng sau trong cây đè ngược lên (người dùng báo 28/08/2026, đo được: kéo z=30, thả về\n // z=10 trong khi hai khối kế bên đang z=11 và z=12).\n if (canOverlap) {\n this.raiseToTopLayer(item);\n }\n\n this.version.update((v) => v + 1);\n itemChangeCallback?.();\n },\n };\n }\n\n /**\n * Bắt lưới LỒNG đo lại NGAY khi khung chứa nó đổi bề rộng — dùng lúc người dùng kéo mép khối cha.\n *\n * Gridster có sẵn đường tự đo (`resize$`), nhưng luồng đó là `switchMap(() => timer(100))`: mỗi\n * lần phát lại huỷ timer trước, mà kéo chuột bắn dày hơn 100ms nên timer không bao giờ tới đích.\n * Đo được (11/09/2026): kéo mép nhóm thì lưới con co theo cha từng khung hình (234 → 384 px) còn\n * THẺ con đứng im ở 106 px suốt cú kéo, chỉ nhảy đúng sau khi thả tay.\n *\n * Giữ CẢ HAI đường: `itemResizeCallback` bắn đồng bộ ngay khi gridster ghi bề rộng mới lên khối\n * (sớm hơn `ResizeObserver` một khung hình) lo độ tức thì; `ResizeObserver` lo những lần khung đổi\n * vì lý do khác — đổi zoom, thu gọn cột bên trái.\n *\n * Tắt bằng `config.autoResizeNestedGrids: false`.\n */\n private buildNestedResizeHooks(base: GridsterConfig, depth: number): Partial<GridsterConfig> {\n if (this.config?.autoResizeNestedGrids === false) {\n return {};\n }\n const gocItemResize = base.itemResizeCallback;\n const gocInit = base.initCallback;\n\n return {\n itemResizeCallback: (item, itemComponent) => {\n gocItemResize?.(item, itemComponent);\n const el = (itemComponent as { el?: HTMLElement } | undefined)?.el;\n\n el?.querySelectorAll('gridster').forEach((nested) => this.resizeGridsterElement(nested as HTMLElement));\n },\n ...(depth > 0\n ? { initCallback: (gridster: GridsterComponentInterface) => this.registerNestedGrid(gridster, gocInit) }\n : {}),\n };\n }\n\n /** Gọi `resize()` của một thẻ `<gridster>` qua chính instance mà nó tự gắn lên phần tử. */\n private resizeGridsterElement(nested: HTMLElement): void {\n const giuInstance = nested as unknown as { __gridsterInstance?: { options?: { api?: { resize?: () => void } } } };\n\n giuInstance.__gridsterInstance?.options?.api?.resize?.();\n }\n\n /**\n * Gắn instance lên chính phần tử `<gridster>` rồi theo dõi bề rộng của nó.\n *\n * Phải gắn ngược lên DOM vì `itemResizeCallback` của khối CHA chỉ cầm được `HTMLElement`, không có\n * đường nào khác đi từ đó về instance của lưới lồng bên trong.\n */\n private registerNestedGrid(\n gridster: GridsterComponentInterface,\n goc?: (gridster: GridsterComponentInterface) => void\n ): void {\n goc?.(gridster);\n const instance = gridster as unknown as { el?: HTMLElement; options?: { api?: { resize?: () => void } } } | undefined;\n const el = instance?.el;\n\n if (!el || typeof ResizeObserver === 'undefined') {\n return;\n }\n (el as unknown as { __gridsterInstance?: unknown }).__gridsterInstance = instance;\n\n const theoDoi = new ResizeObserver(() => instance?.options?.api?.resize?.());\n\n theoDoi.observe(el);\n this.nestedResizeObservers.add(theoDoi);\n }\n\n /**\n *\n * Gắn component của nơi dùng lên một khối.\n *\n * @param host chỗ gắn RIÊNG của ô đó — mỗi khối một `ViewContainerRef`, dùng chung một cái thì\n * mọi component bị dồn hết vào một ô.\n * @param childCanvas khuôn mặt phẳng LỒNG của khối, chỉ có với khối container tự khai\n * `getComponentOutlet`. Component vỏ nhận nó qua input `childCanvas` và tự đặt vào giữa tiêu đề\n * với phần thân của mình. Không truyền xuống thì vỏ chiếm trọn chiều cao khối và đẩy toàn bộ thẻ\n * con ra ngoài vùng nhìn thấy.\n */\n private attachNode(\n node: T_gridLayout_node,\n depth: number,\n host: ViewContainerRef,\n childCanvas?: TemplateRef<unknown>\n ): void {\n const config = this.config;\n\n if (!config) {\n return;\n }\n\n const existing = this.componentRefs.get(node.id);\n\n if (existing) {\n this.applyInputs(existing, node, depth, childCanvas);\n\n return;\n }\n\n // Khối tự khai thì hỏi nó; không thì hỏi hàm phân giải chung. Cả hai đều nhận `node` để đọc\n // được `data.type` mà quyết định trả component nào.\n const stream = (node.getComponentOutlet ?? config.getComponentOutlet)?.(node);\n\n if (!stream) {\n return;\n }\n\n // 🔴 Huỷ lượt tải CŨ của đúng khối này trước khi mở lượt mới.\n // Khối bị gỡ rồi gắn lại (đổi bố cục, sắp gọn) trong lúc `import()` chưa xong thì lượt cũ vẫn\n // chạy tiếp và dựng component vào một `ViewContainerRef` đã chết.\n this.pendingLoads.get(node.id)?.unsubscribe();\n\n const sub = stream.pipe(take(1)).subscribe((componentType) => {\n this.pendingLoads.delete(node.id);\n\n // Khối có thể đã bị xoá trong lúc chờ tải — dựng vào đây là rò rỉ.\n if (!this.treeService.findById(this.rootNode() ?? node, node.id)) {\n return;\n }\n\n const ref = host.createComponent(componentType);\n\n this.applyInputs(ref, node, depth, childCanvas);\n this.componentRefs.set(node.id, ref);\n });\n\n this.pendingLoads.set(node.id, sub);\n }\n\n /**\n * Gỡ component của một khối và huỷ nó. */\n private detachNode(nodeId: string): void {\n // Khối bị gỡ khi component của nó còn đang tải — phải huỷ lượt tải, không thì nó dựng vào một\n // `ViewContainerRef` đã chết.\n this.pendingLoads.get(nodeId)?.unsubscribe();\n this.pendingLoads.delete(nodeId);\n\n const ref = this.componentRefs.get(nodeId);\n\n if (!ref) {\n return;\n }\n\n ref.destroy();\n this.componentRefs.delete(nodeId);\n }\n\n private destroy(): void {\n for (const sub of this.pendingLoads.values()) {\n sub.unsubscribe();\n }\n\n for (const ref of this.componentRefs.values()) {\n ref.destroy();\n }\n\n for (const observer of this.nestedResizeObservers) {\n observer.disconnect();\n }\n\n this.pendingLoads.clear();\n this.componentRefs.clear();\n this.nestedResizeObservers.clear();\n this.config = undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // Nhóm hàm cho nơi dùng CHỦ ĐỘNG gọi — không phải chờ người dùng bấm nút trên khối.\n // Sửa cây thì dùng thẳng `TreeService` rồi gọi `refresh()` — xem demo trong core-ui.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Báo cho service biết cây vừa đổi từ bên ngoài (thêm/xoá khối, sắp gọn, nạp bố cục khác).\n *\n * 🔴 PHẢI thay THAM CHIẾU của node gốc, không chỉ bơm `version`.\n * `@for … track item.id` giữ nguyên object khi id không đổi, nên `<gridster-item [item]=\"…\">` vẫn\n * nhận đúng object cũ và gridster không hề biết `x/y/cols/rows/layerIndex` vừa bị sửa. Bơm mỗi\n * `version` thì computed chạy lại nhưng trả về CÙNG mảng cũ — lưới đứng im (đo 28/08/2026: bấm\n * \"Sắp gọn\" cây đã dồn khít mà màn hình không nhúc nhích; bật chồng khối mà `$item.layerIndex`\n * vẫn trống).\n *\n * Nhân bản NÔNG cả node gốc và danh sách con là đủ: mảng mới → `@for` dựng lại item, object con\n * mới → gridster đọc lại toàn bộ toạ độ.\n */\n refresh(event?: T_gridLayout_changeEvent): void {\n const root = event?.root ?? this.rootNode();\n\n if (!root) {\n this.version.update((v) => v + 1);\n\n return;\n }\n\n if (this.config) {\n this.config = { ...this.config, data: root };\n }\n\n this.rootNode.set(this.shallowCloneTree(root));\n this.version.update((v) => v + 1);\n }\n\n /** Nhân bản nông theo cả chiều sâu: mỗi node và mảng `children` thành tham chiếu mới. */\n /**\n * Nhân bản SÂU cả cây — dùng cho `exportLayout()`.\n *\n * 🔴 BỎ `getComponentOutlet` khỏi bản sao: nó là một HÀM, không tuần tự hoá được nên gửi xuống\n * backend là hỏng (`JSON.stringify` nuốt mất, `structuredClone` ném lỗi). Nạp lại thì hàm phân\n * giải chung của cấu hình lo — component suy ra từ `data.type`, không cần lưu.\n */\n private deepCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n const copy: T_gridLayout_node = { ...node };\n\n // Cắt hàm phân giải — xem chú thích trên.\n delete copy.getComponentOutlet;\n\n const { children, data, ...rest } = copy;\n\n return {\n ...rest,\n ...(data === undefined ? {} : { data: cloneDeep(data) }),\n ...(children ? { children: children.map((child) => this.deepCloneTree(child)) } : {}),\n };\n }\n\n private shallowCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n if (!node.children?.length) {\n return { ...node };\n }\n\n return { ...node, children: node.children.map((child) => this.shallowCloneTree(child)) };\n }\n\n /**\n * Gán `layerIndex` khác nhau cho từng khối khi bật chồng khối.\n *\n * 🔴 `allowMultiLayer: true` MỘT MÌNH không cho khối đè nhau. Mã lib so `layerIndex` của hai khối:\n * KHÁC nhau thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n * `defaultLayerIndex` — tức CÙNG lớp, nên kéo vào nhau là bị chặn y như lưới thường (người dùng\n * báo 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n *\n * Nơi dùng tự khai `layerIndex` thì giữ nguyên; ai không khai thì thư viện xếp mỗi khối một lớp\n * theo thứ tự, đủ để mọi cặp đều khác lớp.\n */\n private assignOverlapLayers(root: T_gridLayout_node): void {\n const config = this.config;\n const canOverlap = config?.mode === E_gridLayout_mode_string.free || (config?.allowOverlap ?? false);\n\n if (!canOverlap) {\n return;\n }\n\n let layer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n if (child.layerIndex === undefined) {\n layer += 1;\n child.layerIndex = layer;\n }\n\n walk(child);\n }\n };\n\n walk(root);\n\n }\n\n /** Đưa một khối lên trên tất cả: lớp của nó = lớp lớn nhất đang có + 1. */\n private raiseToTopLayer(item: GridsterItem): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n let topLayer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n topLayer = Math.max(topLayer, child.layerIndex ?? 0);\n walk(child);\n }\n };\n\n walk(root);\n\n // `item` gridster trả về CHÍNH là object node của cây (truyền thẳng qua `[item]`), nên gán vào\n // đây là cây cũng đổi theo.\n const node = item as unknown as T_gridLayout_node;\n\n if (node.layerIndex === topLayer) {\n\n return;\n }\n\n node.layerIndex = topLayer + 1;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // SỬA CÂY — thư viện đã giữ cây nên bạn KHÔNG phải truyền nó vào.\n // Mọi hàm dưới đây tự vẽ lại; không cần gọi `refresh()`.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Thêm một khối.\n *\n * @param item khối mới — KHÔNG cần `id` (thư viện sinh) và `x`/`y` (tự đặt xuống hàng trống).\n * @param parentId container muốn thêm vào; bỏ trống thì thêm vào mặt phẳng gốc.\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addBlock(item: T_gridLayout_newNode, parentId?: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root ? this.treeService.addChild(root, parentId ?? root.id, item) : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n /**\n * Thêm một khối tại toạ độ (col, row) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertBlockWithCollision(\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n parentId?: string,\n ): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root\n ? this.treeService.insertWithCollision(root, parentId ?? root.id, item, targetCol, targetRow)\n : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n private readonly activeDragPayload = signal<unknown | undefined>(undefined);\n\n /** Đặt payload khi bắt đầu kéo từ bên ngoài vào (ví dụ: palette, drawer) */\n setDragPayload(payload: unknown): void {\n this.activeDragPayload.set(payload);\n }\n\n /** Lấy payload đang kéo */\n getDragPayload(): unknown {\n return this.activeDragPayload();\n }\n\n /** Xoá payload khi kết thúc kéo */\n clearDragPayload(): void {\n this.activeDragPayload.set(undefined);\n }\n\n /** Xoá một khối. Xoá container là xoá cả ruột. Trả `false` khi không xoá được (vd khối gốc). */\n removeBlock(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.removeById(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /**\n * Số cột thật của lưới cấp trang.\n *\n * 🔴 Mặc định phải TRÙNG `minCols/maxCols` của `gridLayoutRootConfig()`. Trước đây chỗ này trả 24\n * trong khi lưới vẽ 12: nơi dùng không truyền `cols` thì va chạm, `toContainer` và `compact` tính\n * theo 24 cột còn màn hình chỉ có 12 — khối rơi ra ngoài mép phải mà không ai hiểu vì sao.\n */\n get totalColumns(): number {\n return this.config?.cols ?? gridLayoutRootConfig().maxCols ?? 12;\n }\n\n /**\n * Chiều cao một hàng lưới (pixel) dùng để tính khung xem trước lúc kéo thả.\n *\n * 🔴 Phải đọc từ `config.rowHeight` của nơi dùng. Trước đây `calculateDropGhost` đóng cứng 68, nên\n * mặt phẳng khai hàng thấp thì khung xem trước cao gấp nhiều lần khối thật — nơi dùng phải ẩn khung\n * của thư viện đi rồi tự vẽ lại.\n */\n get rowStepPx(): number {\n return this.config?.rowHeight ?? gridLayoutRootConfig().fixedRowHeight ?? 68;\n }\n\n /**\n * Khe NHÌN THẤY giữa hai khối cấp gốc (px). `0` = không áp, giữ đúng hành vi cũ.\n */\n get visualGapPx(): number {\n return this.config?.visualGap ?? 0;\n }\n\n /**\n * Đổi số cột / số hàng của một khối rồi vẽ lại.\n *\n * Kéo `cols` rộng quá mép phải thì dịch khối sang trái cho vừa, thay vì để nó tràn ra ngoài lưới.\n */\n resizeBlock(id: string, size: { cols?: number; rows?: number }): boolean {\n const node = this.findBlock(id);\n\n if (!node) {\n return false;\n }\n\n if (size.cols !== undefined) {\n node.cols = size.cols;\n if (node.x + size.cols > this.totalColumns) {\n node.x = Math.max(0, this.totalColumns - size.cols);\n }\n }\n\n if (size.rows !== undefined) {\n node.rows = size.rows;\n }\n this.refresh();\n\n return true;\n }\n\n /**\n * Nhân bản một khối — đặt kế bên phải nếu còn chỗ, không thì xuống dòng dưới.\n *\n * `transformData` để nơi dùng đổi phần dữ liệu riêng của mình (vd nối thêm \"(Bản sao)\" vào tiêu\n * đề); thư viện không tự đoán trường nào là tiêu đề.\n */\n duplicateBlock(id: string, transformData?: (data: unknown) => unknown): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const node = root ? findNodeRecursive(root, id) : undefined;\n\n if (!root || !node) {\n return undefined;\n }\n const parent = findParentRecursive(root, id);\n const isNested = Boolean(parent && parent.id !== root.id);\n const clonedData = cloneDeep(node.data);\n\n let targetX = node.x + node.cols;\n let targetY = node.y;\n\n if (targetX + node.cols > this.totalColumns) {\n targetX = 0;\n targetY = node.y + node.rows;\n }\n\n return this.addBlock(\n {\n x: targetX,\n y: targetY,\n cols: node.cols,\n rows: node.rows,\n data: transformData ? transformData(clonedData) : clonedData,\n getComponentOutlet: node.getComponentOutlet,\n },\n isNested ? parent?.id : undefined\n );\n }\n\n /** Biến khối đơn thành CONTAINER — nội dung cũ thành khối con đầu tiên, không mất dữ liệu. */\n toContainer(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toContainer(root, id, this.totalColumns) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Đưa CONTAINER về khối đơn — khối con được nâng lên cấp trên, không bị xoá. */\n toSingle(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toSingle(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Dồn khối khít lên trên, lấp hết chỗ trống. Đệ quy vào container. */\n compact(): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n this.treeService.compact(root, this.totalColumns);\n this.refresh();\n }\n\n /**\n * Bố cục HIỆN TẠI, đã cắt mọi tham chiếu — gửi thẳng xuống backend được.\n *\n * Dùng khi bấm nút Lưu. Khác `Root()` ở chỗ đây là bản SAO: nơi dùng có sửa gì trên kết quả cũng\n * không đụng tới cây mà thư viện đang vẽ.\n *\n * @returns `undefined` khi mặt phẳng chưa `init()`.\n */\n exportLayout(): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.deepCloneTree(root) : undefined;\n }\n\n /** Tìm một khối theo id. */\n findBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findById(root, id) : undefined;\n }\n\n /** Tìm khối cha trực tiếp của một khối. */\n findParentBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findParent(root, id) : undefined;\n }\n\n /**\n * Đặt tỷ lệ thu phóng của canvas (kẹp giữa min và max).\n *\n * @param value Tỷ lệ (0.4 = 40%, 1.0 = 100%, 1.5 = 150%)\n * @param persistKey Khóa localStorage để lưu lại (bỏ trống thì lấy từ config)\n */\n setZoom(value: number, persistKey?: string): void {\n const min = this.config?.zoomMin ?? 0.4;\n const max = this.config?.zoomMax ?? 1.5;\n const clamped = Math.min(max, Math.max(min, Math.round(value * 100) / 100));\n this.zoomLevel.set(clamped);\n\n const storageKey = persistKey ?? this.config?.storageKey;\n if (storageKey && typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(storageKey, String(clamped));\n } catch {\n // ignore localStorage access error\n }\n }\n\n this.version.update((v) => v + 1);\n }\n\n /** Phóng to thêm một bước (mặc định 0.05 tức 5%) */\n zoomIn(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() + s, persistKey);\n }\n\n /** Thu nhỏ bớt một bước (mặc định 0.05 tức 5%) */\n zoomOut(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() - s, persistKey);\n }\n\n /** Đặt lại tỷ lệ thu phóng gốc 100% (1.0) */\n resetZoom(persistKey?: string): void {\n this.setZoom(1.0, persistKey);\n }\n\n /**\n * Tự động tính toán và đặt tỷ lệ thu phóng để canvas vừa vặn với chiều rộng container.\n *\n * @param containerWidth Chiều rộng container đo được (px)\n * @param stageWidth Chiều rộng chuẩn của canvas (mặc định 1668px)\n * @param padding Khoảng cách lề hai bên (mặc định 48px)\n * @param persistKey Khóa localStorage\n * @returns Tỷ lệ thu phóng vừa tính\n */\n fitToScreen(containerWidth: number, stageWidth?: number, padding = 48, persistKey?: string): number {\n const targetWidth = stageWidth ?? this.config?.stageWidth ?? 1668;\n const min = this.config?.zoomMin ?? 0.4;\n const max = 1.25;\n const ratio = Math.min(max, Math.max(min, Math.round(((containerWidth - padding) / targetWidth) * 100) / 100));\n this.setZoom(ratio, persistKey);\n return ratio;\n }\n\n /** Kiểm tra tính năng thu phóng có được cấu hình bật không */\n isZoomConfigured(): boolean {\n return Boolean(this.config?.enableZoom);\n }\n\n /**\n * Cổng DUY NHẤT cho canvas của thư viện. Nơi dùng KHÔNG gọi tới đây.\n *\n * Mọi thứ canvas cần đều là `private` để không lọt ra API công khai; gom vào một getter theo đúng\n * khuôn `FunctionsControl` của bộ quy ước, thay vì để rải rác hàm public mà người ngoài tưởng\n * mình phải gọi (người dùng chốt 28/08/2026).\n */\n get FunctionsControl() {\n return {\n maxContainerDepth: () => this.maxContainerDepth(),\n containerPadding: () => this.containerPadding(),\n isZoomEnabled: () => this.isZoomConfigured(),\n zoom: () => this.zoomLevel(),\n setZoom: (v: number, key?: string) => this.setZoom(v, key),\n zoomIn: (step?: number, key?: string) => this.zoomIn(step, key),\n zoomOut: (step?: number, key?: string) => this.zoomOut(step, key),\n resetZoom: (key?: string) => this.resetZoom(key),\n fitToScreen: (cW: number, sW?: number, pad?: number, key?: string) => this.fitToScreen(cW, sW, pad, key),\n gridsterOptions: (depth: number, cb?: () => void) => this.buildGridsterOptions(depth, cb),\n attachNode: (node: T_gridLayout_node, depth: number, host: ViewContainerRef, childCanvas?: TemplateRef<unknown>) =>\n this.attachNode(node, depth, host, childCanvas),\n detachNode: (nodeId: string) => this.detachNode(nodeId),\n getNodeElement: (nodeId: string, scope?: ParentNode) => this.getNodeElement(nodeId, scope),\n getNodeCanvasElement: (nodeId: string, scope?: ParentNode) => this.getNodeCanvasElement(nodeId, scope),\n };\n }\n\n /**\n * Trả về vỏ DOM của một khối theo `id`.\n *\n * 🔴 Nơi dùng cần chạm vào DOM của khối (đo kích thước, gắn lớp phủ riêng) BẮT BUỘC đi qua đây.\n * Trước khi có hàm này, nơi dùng phải tự viết `querySelector('.libs-ui-grid-layout-block-shell[...]')`\n * — tức bám vào tên class NỘI BỘ của thư viện: đổi tên class là màn bên kia vỡ IM LẶNG, biên dịch\n * vẫn xanh vì chuỗi selector không ai kiểm.\n *\n * `scope` giới hạn phạm vi tìm (mặc định cả tài liệu) — cần khi nhiều mặt phẳng cùng nằm trên màn.\n */\n getNodeElement(nodeId: string, scope?: ParentNode): HTMLElement | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n const root = scope ?? document;\n\n return (root.querySelector(`.libs-ui-grid-layout-block-shell[data-node-id=\"${nodeId}\"]`) as HTMLElement | null) ?? undefined;\n }\n\n /**\n * Trả về mặt phẳng LỒNG nằm trong một khối container (khối có con), nếu có.\n *\n * Tách riêng khỏi `getNodeElement` vì nơi dùng thường cần chèn phần tử của mình vào TRƯỚC mặt phẳng\n * lồng này (ví dụ hàng tiêu đề của khối ghép), nên phải cầm đúng nó chứ không phải cả vỏ.\n */\n getNodeCanvasElement(nodeId: string, scope?: ParentNode): HTMLElement | undefined {\n const shell = this.getNodeElement(nodeId, scope);\n\n if (!shell) {\n return undefined;\n }\n\n return (shell.querySelector(':scope > libs_ui-services-grid_layout-canvas') as HTMLElement | null) ?? undefined;\n }\n\n private applyInputs(\n ref: ComponentRef<unknown>,\n node: T_gridLayout_node,\n depth: number,\n childCanvas?: TemplateRef<unknown>\n ): void {\n ref.setInput('data', node.data);\n ref.setInput('node', node);\n ref.setInput('isEditMode', this.editMode());\n ref.setInput('depth', depth);\n // 🔴 CHỈ đặt khi có khuôn: `setInput` với một input component không khai là lỗi lúc chạy, mà\n // component nội dung của khối LÁ thì không cần biết đến mặt phẳng lồng.\n if (childCanvas) {\n ref.setInput('childCanvas', childCanvas);\n }\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n OnDestroy,\n TemplateRef,\n ViewContainerRef,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { GridsterComponent, GridsterModule } from 'gridster18';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { emptyRootNode } from '../defines/gridster-config.define';\nimport { LibsUiGridLayoutService } from '../grid-layout.service';\nimport {\n T_gridLayout_actionEvent,\n T_gridLayout_addEvent,\n T_gridLayout_changeEvent,\n T_gridLayout_dropEvent,\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n T_gridLayout_toolbarContext,\n T_gridLayout_zoomPreset,\n} from '../interfaces/grid-layout.interface';\nimport { calculateDropGhost, parseDropPayload } from '../defines/collision.define';\n\n/**\n * Mặt phẳng kéo thả. Đệ quy: khối có `children` thì ruột nó lại là một mặt phẳng nữa.\n *\n * Nơi dùng KHÔNG dựng component này trực tiếp cho từng khối — chỉ đặt MỘT thẻ ở gốc và truyền\n * `nodeComponentType` qua `LibsUiGridLayoutService.init()`. Thư viện tự gắn component cho mọi khối.\n */\n@Component({\n selector: 'libs_ui-services-grid_layout-canvas',\n standalone: true,\n imports: [GridsterModule, LibsUiComponentsButtonsButtonComponent, NgTemplateOutlet, TranslateModule],\n templateUrl: './grid-layout-canvas.component.html',\n styleUrl: './grid-layout-canvas.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiGridLayoutCanvasComponent implements AfterViewInit, OnDestroy {\n /**\n * @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền khi vẽ ruột container.\n *\n * Nơi dùng KHÔNG truyền: mặt phẳng gốc đọc cây từ service (đã đưa vào qua `init()`), truyền thêm\n * ở đây là khai hai lần cùng một thứ (người dùng chốt 28/08/2026).\n */\n readonly node = input<T_gridLayout_node>();\n /** @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền. */\n readonly depth = input<number>(0);\n\n /**\n * Ẩn hẳn thanh công cụ mặc định (thêm-vào-trong · gộp/tách · xoá) của MỌI khối.\n *\n * Dùng khi sản phẩm gom các hành động đó vào chỗ khác — vd một nút ⋮ nằm trong chính nội dung\n * khối. Ẩn rồi thì `outRemoveNode` · `outAddBlockInside` · `outToggleType` không còn nguồn phát\n * từ thư viện; nơi dùng tự gọi `removeBlock` · `addBlock` · `toggleType` của service.\n */\n readonly hiddenToolbar = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /**\n * Template tự vẽ thanh công cụ, thay cho bộ nút mặc định.\n *\n * Nhận context `{ $implicit: node, isContainer, canAddInside, canToggleType }` để nơi dùng vẽ đúng\n * nút cho từng khối, rồi gọi ngược qua `outRemoveNode` · `outAddBlockInside` · `outToggleType`\n * bằng chính các hàm trong context. Truyền cả `hiddenToolbar` và `templateToolbar` thì\n * `hiddenToolbar` thắng — không vẽ gì.\n */\n readonly templateToolbar = input<TemplateRef<T_gridLayout_toolbarContext> | undefined>(undefined);\n\n /**\n * Bố cục vừa đổi do NGƯỜI DÙNG kéo hoặc đổi kích thước khối.\n *\n * Nơi dùng tự gọi `addBlock` · `removeBlock` · `compact` thì KHÔNG bắn — họ vừa gọi thì đã biết,\n * bắn ngược lại là thừa (người dùng chốt 28/08/2026).\n */\n readonly outChange = output<T_gridLayout_changeEvent>();\n /**\n * Người dùng bấm nút XOÁ trên một khối. Thư viện CHƯA xoá — gọi `event.confirm()` để xoá thật.\n * Cần hỏi trước thì hỏi xong mới gọi; không cho phép thì đừng gọi.\n */\n readonly outRemoveNode = output<T_gridLayout_actionEvent>();\n /**\n * Người dùng bấm nút THÊM trên một container. Thư viện KHÔNG tự thêm — nó không biết bạn có\n * những loại khối nào. Mở menu chọn loại rồi gọi `event.confirm(item)` với khối bạn muốn thêm.\n */\n readonly outAddBlockInside = output<T_gridLayout_addEvent>();\n /** Người dùng bấm nút GỘP/TÁCH. Thư viện chưa làm gì — gọi `event.confirm()` để thực hiện. */\n readonly outToggleType = output<T_gridLayout_actionEvent>();\n\n /** Bật tính năng thu phóng (zoom) canvas. Chỉ áp dụng cho canvas gốc (depth 0). */\n readonly enableZoom = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Tỷ lệ thu phóng hiện tại (hỗ trợ two-way binding [(zoom)]=\"myZoom\"). */\n readonly zoom = model<number | undefined>(undefined);\n\n /** Giới hạn thu phóng tối thiểu. Mặc định 0.4 (40%). */\n readonly zoomMin = input<number>(0.4);\n\n /** Giới hạn thu phóng tối đa. Mặc định 1.5 (150%). */\n readonly zoomMax = input<number>(1.5);\n\n /** Bước nhảy thu phóng mỗi lần bấm +/- hoặc lăn chuột. Mặc định 0.05 (5%). */\n readonly zoomStep = input<number>(0.05);\n\n /** Chiều rộng chuẩn của canvas stage tính bằng px. Mặc định 1668. */\n readonly stageWidth = input<number>(1668);\n\n /** Chiều cao tối thiểu của canvas stage tính bằng px. Mặc định 937. */\n readonly stageMinHeight = input<number>(937);\n\n /** Khóa lưu tỷ lệ thu phóng vào localStorage. Mặc định 'ocb_bi_canvas_zoom'. */\n readonly storageKey = input<string | undefined>('ocb_bi_canvas_zoom');\n\n /** Hiển thị thanh dock điều khiển thu phóng nổi ở góc dưới phải. Mặc định true. */\n readonly showZoomDock = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Tự động vừa màn hình khi tải trang lần đầu nếu khung nhìn nhỏ hơn stageWidth. Mặc định true. */\n readonly autoFitOnLoad = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Phát ra khi tỷ lệ thu phóng thay đổi. */\n readonly outZoomChange = output<number>();\n\n /** Bật tính năng kéo thả thẻ từ bên ngoài vào canvas (mặc định true) */\n readonly enableExternalDrop = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Luôn hiển thị đường kẻ lưới 24 cột */\n readonly showGridLines = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Mã id của khối đang được chọn */\n readonly selectedNodeId = model<string | null | undefined>(undefined);\n\n /** Phát ra khi thả một thẻ mới từ bên ngoài vào canvas */\n readonly outDropNode = output<T_gridLayout_dropEvent>();\n\n /** Phát ra khi người dùng click chọn một khối */\n readonly outSelectNode = output<T_gridLayout_node>();\n\n /** Phát ra khi người dùng bấm nút cấu hình trên thanh công cụ của khối */\n readonly outConfigNode = output<T_gridLayout_actionEvent>();\n\n private readonly gridsterRef = viewChild(GridsterComponent);\n private readonly scrollAreaRef = viewChild<ElementRef<HTMLElement>>('scrollArea');\n private readonly zoomDockRef = viewChild<ElementRef<HTMLElement>>('zoomDock');\n /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */\n private readonly itemHosts = viewChildren('itemHost', { read: ViewContainerRef });\n /**\n * Khuôn mặt phẳng LỒNG của từng khối container, để đưa vào component vỏ khi khối đó tự khai\n * `getComponentOutlet`.\n *\n * 🔴 Danh sách này KHÔNG cùng thứ tự với `children()`: `ng-template #childCanvasTpl` chỉ tồn tại\n * cho khối CÓ CON. Ghép theo index là gán nhầm khuôn của khối này cho khối khác — phải lọc lại\n * đúng cùng điều kiện mà template dùng (xem `childCanvasTemplateOf`).\n */\n private readonly childCanvasTemplates = viewChildren<TemplateRef<unknown>>('childCanvasTpl');\n\n /** Khung xem trước vị trí thả thẻ từ bên ngoài (snapped ghost preview) */\n protected readonly dropGhost = signal<T_gridLayout_dropGhost | undefined>(undefined);\n\n private activeHoveredEl?: HTMLElement;\n private rootGridsterEl?: HTMLElement;\n\n /** Menu chọn preset thu phóng đang mở hay đóng */\n protected readonly isMenuOpen = signal<boolean>(false);\n\n /** Các mốc thu phóng định sẵn */\n protected readonly zoomPresets: Array<T_gridLayout_zoomPreset> = [\n { label: 'i18n_zoom_preset_overview', value: 0.5 },\n { label: 'i18n_zoom_preset_small_laptop', value: 0.67 },\n { label: 'i18n_zoom_preset_laptop_1080p', value: 0.75 },\n { label: 'i18n_zoom_preset_screen_1080p', value: 0.85 },\n { label: 'i18n_zoom_preset_standard', value: 0.9 },\n { label: 'i18n_zoom_preset_original_size', value: 1 },\n { label: 'i18n_zoom_preset_large_screen', value: 1.1 },\n { label: 'i18n_zoom_preset_high_dpi_2k', value: 1.25 },\n ];\n\n /** Sáu chấm của tay cầm kéo — chỉ để `@for` dựng đủ 6 thẻ, giá trị không dùng tới. */\n protected readonly dragBarDots = [0, 1, 2, 3, 4, 5];\n\n private readonly service = inject(LibsUiGridLayoutService);\n\n /** Chế độ thu phóng có đang hoạt động trên canvas này không (chỉ root canvas depth 0) */\n protected readonly isZoomActive = computed(() => {\n return this.depth() === 0 && (this.enableZoom() || this.service.FunctionsControl.isZoomEnabled());\n });\n\n protected readonly currentZoom = computed(() => this.service.Zoom());\n protected readonly zoomPercent = computed(() => Math.round(this.currentZoom() * 100));\n\n /**\n * Node THẬT của mặt phẳng này.\n *\n * 🔴 Mặt phẳng GỐC (depth 0) đọc cây từ SERVICE, không dùng input.\n * Nơi dùng thường sửa cây TẠI CHỖ (`treeService.compact(tree)`) rồi gọi `refresh()`, nên signal\n * `root()` của họ giữ nguyên tham chiếu và input `node` không hề đổi — `@for` không dựng lại\n * `gridster-item`, lưới đứng im dù dữ liệu đã khác (đo 28/08/2026: bấm \"Sắp gọn\" không tác dụng).\n * `refresh()` của service thay tham chiếu cây, nên đọc từ đó mới thấy thay đổi.\n *\n * Mặt phẳng LỒNG vẫn dùng input: nó nhận node con từ mặt phẳng cha, vốn đã là object mới.\n */\n protected readonly currentNode = computed(() => {\n this.service.Version();\n\n if (this.depth() > 0) {\n return this.node() ?? emptyRootNode();\n }\n\n return this.service.Root() ?? emptyRootNode();\n });\n\n protected readonly children = computed(() => this.currentNode().children ?? []);\n\n /**\n * Bối cảnh cho `templateToolbar`, dựng sẵn theo từng khối.\n *\n * Dựng ở `computed` chứ không gọi hàm trên template: gọi hàm trong template chạy lại mỗi vòng\n * dò thay đổi (rule `fe-coding-convention-templates` mục 6).\n */\n protected readonly toolbarContexts = computed<Array<T_gridLayout_toolbarContext>>(() =>\n this.children().map((item) => ({\n $implicit: item,\n isContainer: this.isContainer(item),\n canAddInside: this.canAddInside(item),\n canToggleType: this.canToggleType(item),\n remove: () => this.outRemoveNode.emit({ nodeId: item.id, node: item, confirm: () => this.service.removeBlock(item.id) }),\n addInside: () => this.emitAddInside(item),\n toggleType: () => this.emitToggleType(item),\n }))\n );\n\n protected readonly isNestedCanvas = computed(() => this.depth() > 0);\n\n /**\n * Khe nhìn thấy giữa các khối CẤP GỐC. Mặt phẳng lồng trả 0 — khối con là các dòng của cùng một\n * thẻ, tách chúng ra làm chúng trông như thẻ rời.\n */\n protected readonly visualGap = computed(() => (this.depth() === 0 ? this.service.visualGapPx : 0));\n\n /** trần lồng container — khối đã chạm trần thì không cho chuyển thành container */\n protected readonly maxContainerDepth = computed(() => this.service.FunctionsControl.maxContainerDepth());\n\n /**\n * Lề trong của container, px.\n *\n * 🔴 Đặt trên VỎ container, không đặt vào lưới con. Lưới con giữ nguyên `margin: 2` như cũ; lề\n * này chỉ co ruột lại khỏi biên vỏ, nhờ đó tay cầm đổi kích thước của khối con luôn nằm trong tầm\n * chuột (người dùng chốt 28/08/2026).\n */\n protected readonly containerPadding = computed(() => `${this.service.FunctionsControl.containerPadding()}px`);\n\n /** Dải kéo chỉ hiện ở chế độ sửa — chế độ xem không kéo được nên hiện dải là gây nhầm. */\n protected readonly isEditMode = computed(() => this.service.IsEditMode());\n\n protected readonly gridOptions = computed(() => {\n // Đọc `Version` để `init()` lại (đổi chế độ, bật/tắt chồng khối) sinh ra options MỚI —\n // gridster chỉ áp dụng cấu hình khi tham chiếu `options` đổi.\n this.service.Version();\n\n return this.service.FunctionsControl.gridsterOptions(this.depth(), () => this.outChange.emit({ root: this.currentNode() }));\n });\n\n constructor() {\n // Gắn component của nơi dùng vào từng ô, và gắn LẠI mỗi khi cây đổi.\n // Dùng effect vì `itemHosts()` chỉ có giá trị sau khi Angular dựng xong @for.\n effect(() => {\n const hosts = this.itemHosts();\n const items = this.children();\n const canvasTemplates = this.childCanvasTemplates();\n\n items.forEach((item, i) => {\n const host = hosts[i];\n\n if (!host) {\n return;\n }\n\n // Khối có con là CONTAINER: RUỘT nó do mặt phẳng lồng vẽ.\n //\n // 🔴 Nhưng container VẪN được gắn component nếu nơi dùng chủ động khai `getComponentOutlet`\n // cho chính khối đó — đó là VỎ của khối ghép: hàng tiêu đề, nút thu gọn, nền. Vỏ KHÔNG thay\n // thế mặt phẳng lồng; nó NHẬN mặt phẳng đó vào trong qua input `childCanvas` và tự đặt vào\n // đúng chỗ giữa tiêu đề và phần thân của mình.\n //\n // Container KHÔNG khai outlet riêng thì vẫn bỏ qua y như cũ — `config.getComponentOutlet`\n // dùng chung là để vẽ NỘI DUNG khối lá, đem áp cho container sẽ đè mất mặt phẳng lồng.\n const isContainerNode = (item.children?.length ?? 0) > 0;\n\n if (isContainerNode && !item.getComponentOutlet) {\n return;\n }\n\n this.service.FunctionsControl.attachNode(\n item,\n this.depth() + 1,\n host,\n isContainerNode ? this.childCanvasTemplateOf(item, canvasTemplates) : undefined\n );\n });\n });\n\n // Đồng bộ nếu model zoom bên ngoài thay đổi\n effect(() => {\n const z = this.zoom();\n if (z !== undefined && Math.abs(z - this.service.Zoom()) > 0.001) {\n this.service.FunctionsControl.setZoom(z, this.storageKey());\n }\n });\n }\n\n ngAfterViewInit(): void {\n if (!this.isZoomActive() || !this.autoFitOnLoad()) {\n return;\n }\n\n const key = this.storageKey();\n let hasSaved = false;\n if (key && typeof localStorage !== 'undefined') {\n try {\n hasSaved = Boolean(localStorage.getItem(key));\n } catch {\n // ignore localStorage access error\n }\n }\n\n if (!hasSaved) {\n setTimeout(() => {\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n if (scrollEl && scrollEl.clientWidth > 0 && scrollEl.clientWidth < this.stageWidth() + 64) {\n this.handlerFitScreen();\n }\n }, 50);\n }\n }\n\n ngOnDestroy(): void {\n this.cleanupDragGrid();\n for (const item of this.children()) {\n this.service.FunctionsControl.detachNode(item.id);\n }\n }\n\n /** Vẽ lại lưới — gọi khi khung ngoài đổi kích thước hoặc cây vừa đổi diện rộng. */\n get FunctionControl() {\n return {\n veLaiLuoi: () => this.gridsterRef()?.optionsChanged(),\n zoomIn: () => this.handlerZoomIn(),\n zoomOut: () => this.handlerZoomOut(),\n resetZoom: () => this.handlerResetZoom(),\n fitToScreen: () => this.handlerFitScreen(),\n setZoom: (val: number) => {\n this.service.FunctionsControl.setZoom(val, this.storageKey());\n this.syncZoomOut();\n },\n // Vùng cuộn của mặt phẳng — nơi dùng cần nó để tự cuộn tới một khối, hoặc đo toạ độ khi kéo.\n // Không mở ở đây thì nơi dùng phải dò bằng tên lớp CSS nội bộ, và tên đó đổi lúc nào không hay.\n scrollArea: (): HTMLElement | undefined => this.scrollAreaRef()?.nativeElement,\n };\n }\n\n protected handlerZoomIn(): void {\n this.service.FunctionsControl.zoomIn(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerZoomOut(): void {\n this.service.FunctionsControl.zoomOut(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerResetZoom(): void {\n this.service.FunctionsControl.resetZoom(this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerFitScreen(): void {\n this.isMenuOpen.set(false);\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n const containerWidth = scrollEl?.clientWidth || (typeof window !== 'undefined' ? window.innerWidth - 300 : 1200);\n this.service.FunctionsControl.fitToScreen(containerWidth, this.stageWidth(), 48, this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerToggleMenu(): void {\n this.isMenuOpen.update((open) => !open);\n }\n\n protected handlerSelectPreset(value: number): void {\n this.isMenuOpen.set(false);\n this.service.FunctionsControl.setZoom(value, this.storageKey());\n this.syncZoomOut();\n }\n\n protected isCurrentPreset(value: number): boolean {\n return Math.abs(this.currentZoom() - value) < 0.01;\n }\n\n private syncZoomOut(): void {\n const val = this.service.Zoom();\n this.outZoomChange.emit(val);\n if (this.zoom() !== val) {\n this.zoom.set(val);\n }\n }\n\n protected handlerWheel(event: WheelEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n if (event.deltaY < 0) {\n this.handlerZoomIn();\n } else if (event.deltaY > 0) {\n this.handlerZoomOut();\n }\n }\n }\n\n @HostListener('document:keydown', ['$event'])\n protected handlerDocumentKeyDown(event: KeyboardEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n if (event.key === '=' || event.key === '+') {\n event.preventDefault();\n this.handlerZoomIn();\n } else if (event.key === '-' || event.key === '_') {\n event.preventDefault();\n this.handlerZoomOut();\n } else if (event.key === '0') {\n event.preventDefault();\n this.handlerResetZoom();\n }\n }\n }\n\n @HostListener('document:click', ['$event'])\n protected handlerDocumentClick(event: MouseEvent): void {\n if (!this.isMenuOpen()) {\n return;\n }\n\n const dockEl = this.zoomDockRef()?.nativeElement;\n if (dockEl && !dockEl.contains(event.target as Node)) {\n this.isMenuOpen.set(false);\n }\n }\n\n protected handlerTrackNode(_index: number, item: T_gridLayout_node): string {\n return item.id;\n }\n\n /**\n * 🔴 Chặn `mousedown` nổi lên lưới CHA khi thao tác trong lưới con.\n * Không chặn thì cả hai lưới cùng nhận một cú bấm: kéo khối con là nhấc luôn container.\n */\n /**\n * Chặn `mousedown` của khối trong lưới LỒNG nổi lên lưới cha.\n *\n * Chỉ chặn ở lưới lồng: lưới cấp trang không có cha nào để chặn, và chặn ở đó sẽ nuốt luôn thao\n * tác của chính nó.\n */\n /**\n * 🔴 Ba handler dưới đây PHẢI `stopPropagation`.\n * Nút nằm trong vùng mang `dragHandleClass`, không chặn thì cú bấm bị gridster hiểu là bắt đầu kéo\n * và `delayStart: 160` nuốt luôn `click` — người dùng thấy như nút chết.\n */\n protected handlerRemove(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outRemoveNode.emit({ nodeId: node.id, node, confirm: () => this.service.removeBlock(node.id) });\n }\n\n protected handlerAddInside(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitAddInside(node);\n }\n\n protected handlerToggleType(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitToggleType(node);\n }\n\n /**\n * Chặn cú bấm trong thanh công cụ nổi lên gridster.\n *\n * Chỉ `stopPropagation`, KHÔNG `preventDefault`: nút bên trong template của nơi dùng vẫn cần\n * hành vi mặc định của mình (mở dropdown, focus…).\n */\n protected handlerStopEvent(event: Event): void {\n event.stopPropagation();\n }\n\n /** Phát `outAddBlockInside` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitAddInside(node: T_gridLayout_node): void {\n this.outAddBlockInside.emit({\n nodeId: node.id,\n node,\n confirm: (item: T_gridLayout_newNode) => this.service.addBlock(item, node.id),\n });\n }\n\n /** Phát `outToggleType` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitToggleType(node: T_gridLayout_node): void {\n this.outToggleType.emit({\n nodeId: node.id,\n node,\n // Gộp hay tách suy ra từ chính khối: đang là container thì tách, không thì gộp.\n confirm: () => (this.isContainer(node) ? this.service.toSingle(node.id) : this.service.toContainer(node.id)),\n });\n }\n\n /** khối này có phải container không (có khối con) */\n protected isContainer(item: T_gridLayout_node): boolean {\n return (item.children?.length ?? 0) > 0;\n }\n\n /**\n * Lấy đúng khuôn mặt phẳng lồng của MỘT khối.\n *\n * 🔴 `viewChildren('childCanvasTpl')` chỉ chứa khuôn của khối CÓ CON, còn `children()` chứa mọi\n * khối — hai danh sách lệch nhau. Phải lọc `children()` theo cùng điều kiện mà template dùng rồi\n * mới tra theo vị trí trong danh sách đã lọc; ghép thẳng theo index của `children()` là gán khuôn\n * của khối này cho khối khác, và thẻ con hiện sai chỗ.\n */\n private childCanvasTemplateOf(\n item: T_gridLayout_node,\n templates: readonly TemplateRef<unknown>[]\n ): TemplateRef<unknown> | undefined {\n const index = this.children()\n .filter((node) => (node.children?.length ?? 0) > 0)\n .findIndex((node) => node.id === item.id);\n\n return index >= 0 ? templates[index] : undefined;\n }\n\n /** container đã chạm trần lồng thì không cho thêm khối vào trong nữa */\n protected canAddInside(item: T_gridLayout_node): boolean {\n return this.isContainer(item) && this.depth() < this.maxContainerDepth();\n }\n\n /** khối đơn ở cấp chưa chạm trần mới được chuyển thành container */\n protected canToggleType(item: T_gridLayout_node): boolean {\n if (this.isContainer(item)) {\n return true;\n }\n\n return this.depth() < this.maxContainerDepth();\n }\n\n protected handlerBlockParentDrag(event: Event): void {\n if (!this.isNestedCanvas()) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerMouseDownTrongLuoi(event: Event): void {\n if (this.depth() === 0) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerSelectNode(node: T_gridLayout_node, event?: MouseEvent): void {\n if (event) {\n // 🔴 CHỈ bỏ qua khi đích thực sự là nút bấm. Trước đây bỏ qua cả vùng\n // `.libs-ui-grid-layout-toolbar`: thanh này phủ gần kín khối nhỏ nên bấm vào khối không bao giờ\n // chọn được, nơi dùng phải tắt `pointer-events` của cả thanh để cứu.\n const target = event.target as HTMLElement;\n if (target.closest('button') || target.closest('[data-grid-layout-action]')) {\n return;\n }\n }\n this.selectedNodeId.set(node.id);\n this.outSelectNode.emit(node);\n }\n\n protected handlerConfig(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n const actionEvent: T_gridLayout_actionEvent = {\n nodeId: node.id,\n node,\n confirm: () => true,\n };\n this.outConfigNode.emit(actionEvent);\n }\n\n protected handlerDragOver(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n const container = this.scrollAreaRef()?.nativeElement;\n const root = this.service.Root();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n if (!container || !root || !payload) {\n return;\n }\n\n const rootGridster = container.querySelector('gridster') as HTMLElement | null;\n if (rootGridster) {\n if (!rootGridster.classList.contains('display-grid')) {\n rootGridster.classList.add('display-grid');\n }\n this.rootGridsterEl = rootGridster;\n }\n\n const ghost = calculateDropGhost(event, container, root, payload, this.service.totalColumns, this.service.rowStepPx);\n\n if (ghost?.isInsideGroup && ghost.hoveredGridster) {\n if (this.activeHoveredEl !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add('display-grid');\n this.activeHoveredEl = ghost.hoveredGridster;\n }\n } else {\n this.cleanupHoveredGroup();\n }\n\n this.dropGhost.set(ghost);\n }\n\n protected handlerDragLeave(event: DragEvent): void {\n if (this.depth() > 0) {\n return;\n }\n if (event.relatedTarget) {\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && container.contains(event.relatedTarget as Node)) {\n return;\n }\n }\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n }\n\n protected handlerDrop(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n const ghost = this.dropGhost();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n this.service.clearDragPayload();\n\n if (!ghost || !payload) {\n return;\n }\n\n const targetParentId = ghost.isInsideGroup ? ghost.targetParentId : undefined;\n const isInside = Boolean(targetParentId);\n\n let itemToAdd: T_gridLayout_newNode;\n const payloadAny = payload as Record<string, unknown>;\n if (typeof payloadAny['resolveNode'] === 'function') {\n const resolved = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(isInside);\n itemToAdd = resolved ?? {\n cols: ghost.cols,\n rows: ghost.rows,\n data: payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined),\n };\n } else {\n const newNodeData = payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined);\n itemToAdd = {\n cols: ghost.cols,\n rows: ghost.rows,\n data: newNodeData,\n };\n }\n\n const addedNode = this.service.insertBlockWithCollision(\n itemToAdd,\n ghost.col,\n ghost.row,\n targetParentId,\n );\n\n if (addedNode) {\n this.selectedNodeId.set(addedNode.id);\n this.outDropNode.emit({\n node: addedNode,\n parentId: targetParentId,\n col: ghost.col,\n row: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n rawEvent: event,\n payload,\n });\n const root = this.service.Root();\n if (root) {\n this.outChange.emit({\n root,\n nodeId: addedNode.id,\n });\n }\n }\n }\n\n private cleanupHoveredGroup(): void {\n if (this.activeHoveredEl) {\n this.activeHoveredEl.classList.remove('display-grid');\n this.activeHoveredEl = undefined;\n }\n }\n\n private cleanupDragGrid(): void {\n this.cleanupHoveredGroup();\n if (this.rootGridsterEl && !this.showGridLines()) {\n this.rootGridsterEl.classList.remove('display-grid');\n this.rootGridsterEl = undefined;\n }\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && !this.showGridLines()) {\n container.querySelectorAll('gridster.display-grid').forEach((el) => {\n el.classList.remove('display-grid');\n });\n }\n }\n}\n","@if (isZoomActive()) {\n <!-- Khu vực cuộn chứa canvas stage thu phóng -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0 overflow-auto p-6 flex justify-start items-start\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (wheel)=\"handlerWheel($event)\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <div\n #canvasStage\n id=\"bi-canvas-stage\"\n class=\"libs-ui-grid-layout-stage relative flex flex-col transition-[zoom] duration-150 origin-top shrink-0 mx-auto bg-white/80 border border-slate-200/80 rounded-2xl shadow-sm p-4\"\n [style.zoom]=\"currentZoom()\"\n [style.width.px]=\"stageWidth()\"\n [style.min-width.px]=\"stageWidth()\"\n [style.min-height.px]=\"stageMinHeight()\"\n [style.--libs-ui-grid-layout-visual-gap.px]=\"visualGap()\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster class=\"h-full w-full\" [class.display-grid]=\"showGridLines()\" [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [attr.data-node-id]=\"item.id\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n @if (isEditMode()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <!-- 🔴 Container CÓ `getComponentOutlet`: khung này là VỎ, và canvas con được đưa VÀO TRONG\n component vỏ qua input `childCanvas` (một `TemplateRef`) — xem `ng-template #childCanvasTpl`\n bên dưới. Vỏ tự quyết đặt canvas ở đâu giữa tiêu đề và phần thân của nó.\n Trước đây canvas con là ANH EM của khung này, nên vỏ chiếm trọn chiều cao rồi đẩy toàn bộ\n thẻ con ra ngoài vùng nhìn thấy (đo 14/09/2026: mọi khối ghép chỉ còn nhãn và ruột trắng). -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item) && !item.getComponentOutlet\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px.\n\n 🔴 Khuôn đặt trong `ng-template` để đi được HAI đường:\n - Container KHÔNG có vỏ riêng → vẽ thẳng tại đây, y như trước.\n - Container CÓ `getComponentOutlet` → thư viện truyền khuôn này xuống component vỏ qua\n input `childCanvas`, vỏ tự đặt nó vào giữa tiêu đề và phần thân của mình. Vẽ thêm ở\n đây nữa là hai mặt phẳng lồng chồng nhau. -->\n <ng-template #childCanvasTpl>\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n </ng-template>\n\n @if (!item.getComponentOutlet) {\n <ng-container [ngTemplateOutlet]=\"childCanvasTpl\" />\n }\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n </div>\n\n <!-- Thanh dock điều khiển thu phóng nổi ở góc dưới trái -->\n @if (showZoomDock()) {\n <div\n #zoomDock\n id=\"canvas-zoom-dock\"\n role=\"toolbar\"\n tabindex=\"0\"\n class=\"absolute bottom-4 left-6 z-30 flex items-center bg-white rounded-full shadow-2xl border-2 border-slate-400 p-1 space-x-1 select-none\"\n (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\">\n <!-- Thu nhỏ (-) -->\n <button\n type=\"button\"\n class=\"w-[28px] h-[28px] flex items-center justify-center rounded-full text-slate-700 hover:text-slate-900 hover:bg-slate-200 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() <= zoomMin()\"\n [title]=\"'i18n_zoom_out' | translate\"\n (click)=\"handlerZoomOut()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Tỷ lệ % và menu preset -->\n <div class=\"relative\">\n <button\n type=\"button\"\n class=\"h-[28px] px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-slate-700 hover:bg-slate-200 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_options' | translate\"\n (click)=\"handlerToggleMenu()\">\n <span>{{ zoomPercent() }}%</span>\n <svg class=\"w-[12px] h-[12px] text-slate-400 transition-transform duration-150\" [class.rotate-180]=\"isMenuOpen()\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n\n <!-- Menu dropdown các mốc thu phóng -->\n @if (isMenuOpen()) {\n <div class=\"absolute bottom-full mb-2 left-0 w-[256px] bg-white rounded-xl shadow-xl border border-slate-200 py-1.5 z-40 text-xs select-none\">\n <div class=\"px-3 py-1 text-[11px] font-semibold text-slate-400 uppercase tracking-wider\">\n {{ 'i18n_zoom_canvas_width' | translate: { width: stageWidth() } }}\n </div>\n <button\n type=\"button\"\n class=\"w-full px-3 py-2 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n (click)=\"handlerFitScreen()\">\n <span class=\"flex items-center gap-2 text-slate-700 font-medium\">\n <svg class=\"w-3.5 h-3.5 text-slate-600\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n {{ 'i18n_zoom_fit_screen' | translate }}\n </span>\n <span class=\"text-[10px] bg-blue-50 text-blue-600 px-1.5 py-0.5 rounded font-medium\">{{ 'i18n_auto' | translate }}</span>\n </button>\n <div class=\"h-px bg-slate-100 my-1\"></div>\n @for (preset of zoomPresets; track preset.value) {\n <button\n type=\"button\"\n class=\"w-full px-3 py-1.5 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n [class.text-blue-600]=\"isCurrentPreset(preset.value)\"\n [class.font-semibold]=\"isCurrentPreset(preset.value)\"\n [class.bg-blue-50]=\"isCurrentPreset(preset.value)\"\n (click)=\"handlerSelectPreset(preset.value)\">\n <span class=\"text-slate-700\" [class.text-blue-600]=\"isCurrentPreset(preset.value)\">\n {{ preset.label | translate }}\n </span>\n @if (isCurrentPreset(preset.value)) {\n <svg class=\"w-3.5 h-3.5 text-blue-600\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n }\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Phóng to (+) -->\n <button\n type=\"button\"\n class=\"w-[28px] h-[28px] flex items-center justify-center rounded-full text-slate-700 hover:text-slate-900 hover:bg-slate-200 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() >= zoomMax()\"\n [title]=\"'i18n_zoom_in' | translate\"\n (click)=\"handlerZoomIn()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Phân cách -->\n <div class=\"h-[16px] w-px bg-slate-200\"></div>\n\n <!-- Nút Vừa màn hình nhanh -->\n <button\n type=\"button\"\n class=\"h-[28px] shrink-0 px-2.5 flex items-center gap-1 rounded-full text-xs text-slate-700 hover:text-slate-900 hover:bg-slate-200 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_fit_screen_tooltip' | translate\"\n (click)=\"handlerFitScreen()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n <span class=\"whitespace-nowrap font-medium\">{{ 'i18n_zoom_fit_screen' | translate }}</span>\n </button>\n\n <!-- Nút Đặt lại 100% (chỉ hiện khi khác 100%) -->\n @if (zoomPercent() !== 100) {\n <button\n type=\"button\"\n class=\"h-[28px] px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-blue-600 hover:bg-blue-50 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_reset_tooltip' | translate: { width: stageWidth(), height: stageMinHeight() }\"\n (click)=\"handlerResetZoom()\">\n <svg class=\"w-[12px] h-[12px]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>\n <span>100%</span>\n </button>\n }\n </div>\n }\n} @else {\n <!-- 🔴 `relative` là BẮT BUỘC, CẤM bỏ.\n gridster đổi vị trí chuột thành ô lưới bằng `e.clientY + (el.scrollTop - el.offsetTop)` — công\n thức đó chỉ đúng khi `offsetParent` của <gridster> CHÍNH LÀ khối cuộn này. Thiếu `relative` thì\n `offsetParent` nhảy lên khối bao ngoài: `offsetTop` trả 16 trong khi lệch thật là 65 → gridster\n tính ô sai 49px, ô chờ đặt hiện lệch khỏi con trỏ nên kéo thả không đổi được vị trí, và kéo mép\n cũng tính sai điểm dừng. -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0\"\n [class.overflow-y-auto]=\"!isNestedCanvas()\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster class=\"h-full w-full\" [class.display-grid]=\"showGridLines()\" [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [attr.data-node-id]=\"item.id\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n @if (isEditMode()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <!-- 🔴 Container CÓ `getComponentOutlet`: khung này là VỎ, và canvas con được đưa VÀO TRONG\n component vỏ qua input `childCanvas` (một `TemplateRef`) — xem `ng-template #childCanvasTpl`\n bên dưới. Vỏ tự quyết đặt canvas ở đâu giữa tiêu đề và phần thân của nó.\n Trước đây canvas con là ANH EM của khung này, nên vỏ chiếm trọn chiều cao rồi đẩy toàn bộ\n thẻ con ra ngoài vùng nhìn thấy (đo 14/09/2026: mọi khối ghép chỉ còn nhãn và ruột trắng). -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item) && !item.getComponentOutlet\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px.\n\n 🔴 Khuôn đặt trong `ng-template` để đi được HAI đường:\n - Container KHÔNG có vỏ riêng → vẽ thẳng tại đây, y như trước.\n - Container CÓ `getComponentOutlet` → thư viện truyền khuôn này xuống component vỏ qua\n input `childCanvas`, vỏ tự đặt nó vào giữa tiêu đề và phần thân của mình. Vẽ thêm ở\n đây nữa là hai mặt phẳng lồng chồng nhau. -->\n <ng-template #childCanvasTpl>\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n </ng-template>\n\n @if (!item.getComponentOutlet) {\n <ng-container [ngTemplateOutlet]=\"childCanvasTpl\" />\n }\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n}\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\nimport { calculateDropGhost } from './defines/collision.define';\n\n/** Lớp CSS bật ô li của một lưới trong lúc người dùng đang kéo khối vào. */\nconst LOP_HIEN_O_LI = 'display-grid';\n\n/**\n * Giữ trạng thái một lượt kéo khối từ palette bên ngoài vào mặt phẳng.\n *\n * Việc nó lo: bật ô li của lưới đang được kéo tới (lưới gốc, và lưới của container khi con trỏ đi\n * vào trong), tắt đúng lúc, và trả về ghost để nơi dùng vẽ khung xem trước.\n *\n * 🔴 Tự bật/tắt ô li bằng tay ở nơi dùng là chỗ rất dễ sót: kéo ra khỏi container rồi mà quên tắt\n * thì ô li của nó nằm lại trên màn, kéo sang lưới khác lại chồng thêm một lớp nữa.\n */\nexport class LibsUiGridLayoutDragController {\n private payload?: T_gridLayout_externalDragPayload;\n private hoveredElement?: HTMLElement;\n private rootGridsterElement?: HTMLElement;\n\n /** Payload của khối đang được kéo; `undefined` khi không có lượt kéo nào. */\n get ActivePayload(): T_gridLayout_externalDragPayload | undefined {\n return this.payload;\n }\n\n /** Gọi ở `dragstart` của thẻ trong palette. */\n onDragStart(payload: T_gridLayout_externalDragPayload): void {\n this.payload = payload;\n }\n\n /** Gọi ở `dragend` — dọn sạch mọi ô li đang bật. */\n onDragEnd(container?: HTMLElement): void {\n this.payload = undefined;\n this.cleanupAll(container);\n }\n\n /** Tắt ô li của container đang hover. */\n cleanupHoveredGroup(): void {\n if (!this.hoveredElement) {\n return;\n }\n this.hoveredElement.classList.remove(LOP_HIEN_O_LI);\n this.hoveredElement = undefined;\n }\n\n /** Tắt ô li của lưới gốc, và quét sạch lớp còn sót trong khung chứa. */\n cleanupRootGrid(container?: HTMLElement): void {\n if (this.rootGridsterElement) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n this.rootGridsterElement = undefined;\n }\n container?.querySelectorAll(`gridster.${LOP_HIEN_O_LI}`).forEach((el) => el.classList.remove(LOP_HIEN_O_LI));\n }\n\n /** Tắt toàn bộ ô li đang bật. */\n cleanupAll(container?: HTMLElement): void {\n this.cleanupHoveredGroup();\n this.cleanupRootGrid(container);\n }\n\n /**\n * Gọi ở `dragover` của khung chứa mặt phẳng. Trả ghost để nơi dùng vẽ khung xem trước, đồng thời\n * tự bật ô li của lưới đang được kéo tới.\n */\n onDragOver(\n event: DragEvent,\n container: HTMLElement | undefined,\n root: T_gridLayout_node | undefined,\n totalCols?: number,\n // Chiều cao một hàng lưới (pixel) để khung xem trước đúng cỡ; không truyền thì giữ mặc định cũ.\n rowStep?: number\n ): T_gridLayout_dropGhost | undefined {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n if (!container || !root || !this.payload) {\n return undefined;\n }\n this.showRootGrid(container);\n\n const ghost = calculateDropGhost(event, container, root, this.payload, totalCols, rowStep);\n\n if (!ghost?.isInsideGroup || !ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n\n return ghost;\n }\n\n if (this.hoveredElement !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add(LOP_HIEN_O_LI);\n this.hoveredElement = ghost.hoveredGridster;\n }\n\n return ghost;\n }\n\n /** Bật ô li của lưới CẤP TRANG trong suốt lượt kéo, tắt lưới cũ nếu khung chứa đã đổi. */\n private showRootGrid(container: HTMLElement): void {\n const rootGridster = (container.querySelector('gridster') as HTMLElement | null) ?? undefined;\n\n if (!rootGridster) {\n return;\n }\n\n if (this.rootGridsterElement && this.rootGridsterElement !== rootGridster) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n }\n rootGridster.classList.add(LOP_HIEN_O_LI);\n this.rootGridsterElement = rootGridster;\n }\n}\n","// Bề mặt CÔNG KHAI — chỉ những gì nơi dùng thật sự cần.\n//\n// `LibsUiGridLayoutTreeService` CỐ Ý không xuất: mọi thao tác trên cây đã có mặt trên\n// `LibsUiGridLayoutService` với chữ ký gọn hơn (không phải truyền `root` — thư viện đang giữ nó).\n// Cấu hình gridster cũng không xuất: nó đã được vá theo hàng chục lỗi đo trên sản phẩm thật, để nơi\n// dùng sửa lại là mở đường cho chính những lỗi đó quay về.\nexport * from './grid-layout.service';\nexport * from './canvas/grid-layout-canvas.component';\nexport * from './interfaces/grid-layout.interface';\nexport * from './defines/collision.define';\nexport * from './drag-controller';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libs-ui-services-grid-layout.mjs","sources":["../../../../../libs-ui/services/grid-layout/src/defines/gridster-config.define.ts","../../../../../libs-ui/services/grid-layout/src/defines/collision.define.ts","../../../../../libs-ui/services/grid-layout/src/tree.service.ts","../../../../../libs-ui/services/grid-layout/src/grid-layout.service.ts","../../../../../libs-ui/services/grid-layout/src/defines/scroll-bridge.define.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.html","../../../../../libs-ui/services/grid-layout/src/drag-controller.ts","../../../../../libs-ui/services/grid-layout/src/index.ts","../../../../../libs-ui/services/grid-layout/src/libs-ui-services-grid-layout.ts"],"sourcesContent":["import { CompactType, DisplayGrid, GridsterConfig, GridType } from 'gridster18';\nimport { T_gridLayout_node } from '../interfaces/grid-layout.interface';\n\n/**\n * Cấu hình gridster cho lưới CẤP TRANG.\n *\n * Mọi giá trị dưới đây đều đến từ một lỗi đã đo được trên sản phẩm thật, không phải chọn theo cảm\n * tính. Đổi bất kỳ dòng nào có dấu 🔴 sẽ làm sống lại đúng lỗi ghi trong comment.\n */\nexport const gridLayoutRootConfig = (): GridsterConfig => ({\n // 🔴 VerticalFixed — CẤM đổi sang Fit hay ScrollVertical.\n // `Fit` chia đều chiều cao khung cho số hàng đang dùng, nên card khai `rows: 2` phình từ 124px lên\n // 247px. `ScrollVertical` KHÔNG đọc `fixedRowHeight` (mã lib: chỉ `Fixed` và `VerticalFixed` đọc).\n gridType: GridType.VerticalFixed,\n\n // 🔴 None — CẤM quay lại CompactUp.\n // `CompactUp` hút mọi khối lên sát nhau NGAY sau mỗi thao tác, nên:\n // · kéo mép dưới cho khối cao thêm → chỗ khối dưới vừa nhường bị hút lấp lại tức thì, cú kéo bị\n // `checkGridCollision` báo va chạm rồi HOÀN NGUYÊN (khối đứng im dù kéo);\n // · kéo thả đổi vị trí → khối vừa nhường chỗ bị hút về ngay, khối đang kéo không có chỗ đặt và\n // treo lơ lửng giữa hai khối.\n // Muốn dồn khít thì gọi `sapGon()` của service.\n compactType: CompactType.None,\n displayGrid: DisplayGrid.OnDragAndResize,\n\n // 🔴 pushItems: true — CẤM để false.\n // `swap` của lib CHỈ hoán vị được HAI KHỐI CÙNG KÍCH THƯỚC (mã lib `checkSwap`: tính diffX/diffY\n // rồi hoán vị, lệch kích thước thì `checkCollision` báo va chạm và hoàn nguyên). Khối 3x2 gặp\n // container 7x5 nên không swap được, mà `pushItems: false` cũng không cho container nhường đường\n // → BẾ TẮC: khối đang kéo không đặt được ở đâu.\n pushItems: true,\n // chỉ đẩy XUỐNG: đẩy ngang làm xô lệch bố cục cột người dùng vừa đặt\n pushDirections: { north: false, east: false, south: true, west: false },\n pushResizeItems: true,\n swap: true,\n swapWhileDragging: true,\n\n draggable: {\n enabled: true,\n // delayStart: 0 vì kéo qua tay cầm chuyên dụng (dragHandleClass) và ignoreContent: true.\n // Khi người dùng bấm vào thanh tay cầm là chủ động kéo, không cần trễ 160ms tránh huỷ kéo.\n delayStart: 0,\n // 🔴 `checkDragHandleClass` duyệt DOM từ chỗ bấm NGƯỢC LÊN CHA, và trên MỖI node nó kiểm\n // `dragHandleClass` TRƯỚC `ignoreContentClass`. Vì vậy một phần tử KHÔNG được mang cả hai class\n // cùng lúc — mang cả hai thì lib gặp tay cầm trước, trả `true`, class chặn không tới lượt.\n ignoreContentClass: 'libs-ui-grid-layout-block-parent-drag',\n ignoreContent: true,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle',\n },\n\n resizable: {\n enabled: true,\n // đủ 8 hướng như cửa sổ thường; chỉ có góc dưới-phải thì quá khó trúng\n handles: { s: true, e: true, n: true, w: true, se: true, ne: true, sw: true, nw: true },\n },\n\n margin: 12,\n outerMargin: true,\n outerMarginBottom: 40,\n minCols: 12,\n maxCols: 12,\n minRows: 2,\n\n // 🔴 KHÔNG giới hạn chiều cao khối. Lib có BA trần mặc định phải vô hiệu hoá CÙNG LÚC, thiếu một\n // cái là vẫn bị chặn: `maxItemRows: 50` · `maxItemCols: 50` · `maxItemArea: 2500` (trần DIỆN TÍCH\n // cols × rows — khó thấy nhất: khối 12 cột chỉ cần 209 hàng là đụng trần dù hai trần kia còn dư).\n // `maxRows` là trần của CẢ LƯỚI, cũng phải nới theo.\n maxRows: 5000,\n maxItemRows: 5000,\n maxItemCols: 12,\n maxItemArea: 60000,\n\n // 🔴 Trần LỚP CHỒNG. Mặc định của lib là 2 — quá thấp: khi bật chồng khối, thư viện gán mỗi khối\n // một lớp riêng để chúng khác nhau, nên chỉ 3 khối là đã đụng trần và các khối sau lại rơi về\n // cùng lớp, tức chồng nhau bị chặn trở lại.\n maxLayerIndex: 5000,\n\n setGridSize: true,\n fixedRowHeight: 56,\n defaultItemCols: 3,\n defaultItemRows: 2,\n minItemRows: 1,\n mobileBreakpoint: -1,\n});\n\n/**\n * Cấu hình cho lưới LỒNG (ruột một container).\n *\n * Kế thừa lưới trang rồi ghi đè phần khác biệt. Ba điểm quan trọng nhất: `setGridSize` phải TẮT,\n * tay cầm phải mang TÊN RIÊNG, và tự-cuộn-khi-kéo phải TẮT.\n */\nexport const gridLayoutNestedConfig = (): GridsterConfig => ({\n ...gridLayoutRootConfig(),\n\n // 🔴 PHẢI tắt cho lưới lồng. `setGridSize` làm gridster tự ghi style width/height lên CHÍNH nó,\n // sinh vòng lặp đo-rồi-ghi với ResizeObserver của khung ngoài (khung đổi → onResize xoá style →\n // setGridSize ghi lại) → lưới con co dần về 64x64px trong khung 868px.\n setGridSize: false,\n\n // khe 2px: khối con là các dòng thông tin của CÙNG một card, khe rộng làm chúng trông như card rời\n margin: 2,\n // Lưới lồng KHÔNG tự chừa lề — lề là của VỎ container (`containerPadding`), không phải của lưới.\n // Đặt ở vỏ thì ruột co lại đúng bằng phần còn lại, tay cầm resize của khối con luôn nằm trong tầm\n // chuột (người dùng chốt 28/08/2026: \"lưới cha có padding chứ ko phải con\").\n outerMargin: false,\n outerMarginBottom: 0,\n\n // hàng 16px cho bước kéo mịn, và sàn 1 hàng = 16px nên khối co được nhỏ hơn nhiều\n fixedRowHeight: 16,\n minRows: 1,\n minItemRows: 1,\n defaultItemCols: 2,\n defaultItemRows: 2,\n\n // 🔴 Tay cầm RIÊNG — CẤM dùng chung tên với lưới trang.\n // `checkDragHandleClass` trả `true` ở node ĐẦU TIÊN có `dragHandleClass`. Dùng chung một tên thì\n // lưới CHA cũng nhận ra tay cầm của khối con và nhấc luôn container.\n draggable: {\n ...gridLayoutRootConfig().draggable,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle-child',\n },\n\n // 🔴 KÉO MÉP thì khối dưới ĐỨNG YÊN, chỉ khoảng trống giữa hai khối co giãn. Bật (kế thừa từ lưới\n // trang) thì mỗi cú kéo đẩy dồn cả cột xuống — người dùng chỉ muốn một khối to hơn một chút mà cả\n // card dài ra. `pushItems` vẫn giữ: nó lo việc KÉO THẢ đổi chỗ, khác việc đổi kích thước.\n pushResizeItems: false,\n\n // 🔴 Tắt tự cuộn khi kéo tới sát mép. Lib thấy chuột gần biên là cuộn lưới theo\n // (`scrollSensitivity`), nhưng lưới con nằm trong card có `overflow: hidden` — cuộn ở đây đẩy khối\n // con ra NGOÀI khung container rồi kẹt luôn ở đó.\n disableScrollHorizontal: true,\n disableScrollVertical: true,\n});\n\n/**\n * Cây rỗng dùng khi chưa có dữ liệu — mặt phẳng vẽ ra một lưới trống thay vì vỡ.\n * Xảy ra trong nhịp giữa lúc component dựng và lúc `init()` chạy.\n */\nexport const emptyRootNode = (): T_gridLayout_node => ({ id: 'root', x: 0, y: 0, cols: 12, rows: 0, children: [] });\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n} from '../interfaces/grid-layout.interface';\nimport { uuid } from '@libs-ui/utils';\n\n/**\n * Checks whether the rectangular region [x, x + cols) x [y, y + rows)\n * is completely vacant among existing items.\n */\nexport const isRegionFree = (\n children: Array<T_gridLayout_node>,\n x: number,\n y: number,\n cols: number,\n rows: number,\n ignoredId?: string,\n): boolean => {\n for (const child of children) {\n if (ignoredId && child.id === ignoredId) {\n continue;\n }\n const hOverlap = !(child.x + child.cols <= x || child.x >= x + cols);\n const vOverlap = !(child.y + child.rows <= y || child.y >= y + rows);\n\n if (hOverlap && vOverlap) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Computes optimal (col, row) inside a group container.\n * Snaps flush to adjacent card right edge if slot is vacant.\n */\nexport const findSnapPositionInsideGroup = (\n children: Array<T_gridLayout_node>,\n rawCol: number,\n rawRow: number,\n innerCols: number,\n innerRows: number,\n totalCols = 24,\n): { col: number; row: number } => {\n let bestCandidate: { col: number; row: number; dist: number } | undefined;\n\n for (const child of children) {\n const rightEdge = child.x + child.cols;\n const canFit = rightEdge + innerCols <= totalCols;\n const isFree = canFit && isRegionFree(children, rightEdge, child.y, innerCols, innerRows);\n\n if (!isFree) {\n continue;\n }\n\n const nearX = Math.abs(rawCol - rightEdge) <= 2 || (rawCol >= child.x + Math.floor(child.cols / 2) && rawCol <= rightEdge + 1);\n const nearY = Math.abs(rawRow - child.y) <= 2;\n\n if (nearX && nearY) {\n const dist = Math.abs(rawCol - rightEdge) + Math.abs(rawRow - child.y);\n\n if (!bestCandidate || dist < bestCandidate.dist) {\n bestCandidate = { col: rightEdge, row: child.y, dist };\n }\n }\n }\n\n if (bestCandidate) {\n return { col: bestCandidate.col, row: bestCandidate.row };\n }\n\n const clampedCol = Math.max(0, Math.min(totalCols - innerCols, rawCol));\n const clampedRow = Math.max(0, rawRow);\n\n return { col: clampedCol, row: clampedRow };\n};\n\n/**\n * Adjusts position of pair if horizontal overlap occurs.\n */\nconst adjustItemPair = (a: T_gridLayout_node, b: T_gridLayout_node): boolean => {\n const hOverlap = !(a.x + a.cols <= b.x || a.x >= b.x + b.cols);\n\n if (hOverlap && b.y < a.y + a.rows) {\n b.y = a.y + a.rows;\n\n return true;\n }\n\n return false;\n};\n\n/**\n * Resolves vertical collisions when inserting a new card at (newNode.x, newNode.y).\n * Any existing card that horizontally overlaps and whose vertical span overlaps\n * or is below the insertion point is pushed down so there is no overlap.\n */\nexport const resolveCollisionsAndInsert = (\n children: Array<T_gridLayout_node>,\n newNode: T_gridLayout_node,\n): void => {\n const items = [...children];\n\n for (const item of items) {\n const hOverlap = !(item.x + item.cols <= newNode.x || item.x >= newNode.x + newNode.cols);\n const vOverlap = !(item.y + item.rows <= newNode.y || item.y >= newNode.y + newNode.rows);\n\n if (hOverlap && vOverlap) {\n item.y = newNode.y + newNode.rows;\n }\n }\n\n items.sort((a, b) => a.y - b.y);\n let changed = true;\n\n while (changed) {\n changed = false;\n for (let i = 0; i < items.length; i++) {\n for (let j = i + 1; j < items.length; j++) {\n changed = adjustItemPair(items[i], items[j]) || changed;\n }\n }\n }\n\n children.push(newNode);\n};\n\nexport function parseDropPayload<T>(activePayload: T | undefined, dataTransfer: DataTransfer | null): T | undefined {\n if (activePayload) {\n return activePayload;\n }\n if (dataTransfer) {\n try {\n const raw = dataTransfer.getData('application/json');\n\n if (raw) {\n return JSON.parse(raw) as T;\n }\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n}\n\ninterface I_hoveredGroup {\n groupNode: T_gridLayout_node;\n groupGridster: HTMLElement;\n}\n\nexport const findHoveredGroup = (\n elements: Element[],\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n): I_hoveredGroup | undefined => {\n const rootGridster = canvasContainer.querySelector('gridster');\n\n for (const el of elements) {\n const gridsterEl = (el.tagName.toLowerCase() === 'gridster' ? el : el.closest('gridster')) as HTMLElement | null;\n\n if (gridsterEl && gridsterEl !== rootGridster) {\n const outerItem = gridsterEl.closest('gridster-item');\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = outerItem ? rootItems.indexOf(outerItem) : -1;\n\n if (idx >= 0 && root.children?.[idx]) {\n return { groupNode: root.children[idx], groupGridster: gridsterEl };\n }\n }\n }\n\n for (const el of elements) {\n const itemEl = el.tagName.toLowerCase() === 'gridster-item' ? el : el.closest('gridster-item');\n if (!itemEl) {\n continue;\n }\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = rootItems.indexOf(itemEl);\n if (idx >= 0 && root.children?.[idx]) {\n const node = root.children[idx];\n if ((node.children?.length ?? 0) > 0) {\n return { groupNode: node, groupGridster: (itemEl.querySelector('gridster') as HTMLElement | null) ?? (itemEl as HTMLElement) };\n }\n }\n }\n\n return undefined;\n};\n\n/**\n * Calculates snapped spatial coordinates and pixel dimensions for drop ghost preview box.\n */\nexport const calculateDropGhost = (\n event: DragEvent,\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n payload: T_gridLayout_externalDragPayload,\n totalCols = 24,\n // 🔴 Chiều cao một hàng lưới, tính bằng pixel. Trước đây đóng cứng 68 nên khung xem trước vẽ sai cỡ\n // ở mặt phẳng có hàng thấp, nơi dùng phải ẩn khung của thư viện rồi tự vẽ lại.\n rowStep = 68,\n): T_gridLayout_dropGhost | undefined => {\n if (typeof document === 'undefined' || !canvasContainer) {\n return undefined;\n }\n\n const cardTitle = payload.title || 'Thẻ';\n const cardIconClass = payload.iconClass;\n const cardIconText = payload.iconText;\n const payloadAny = payload as Record<string, unknown>;\n let defaultCols = typeof payload.cols === 'number'\n ? payload.cols\n : (typeof payloadAny['defaultCols'] === 'number' ? (payloadAny['defaultCols'] as number) : (totalCols >= 24 ? 12 : 6));\n let defaultRows = typeof payload.rows === 'number'\n ? payload.rows\n : (typeof payloadAny['defaultRows'] === 'number' ? (payloadAny['defaultRows'] as number) : 4);\n\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sample = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(false);\n if (sample) {\n if (typeof sample.cols === 'number') { defaultCols = sample.cols; }\n if (typeof sample.rows === 'number') { defaultRows = sample.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n\n const stageEl = (canvasContainer.querySelector('#bi-canvas-stage') as HTMLElement | null) ?? canvasContainer;\n const stageRect = stageEl.getBoundingClientRect();\n\n const rootGridster = stageEl.querySelector('gridster') as HTMLElement | null;\n const gridsterEl = rootGridster ?? stageEl;\n const gridsterRect = gridsterEl.getBoundingClientRect();\n const unscaledWidth = gridsterEl.offsetWidth || gridsterEl.clientWidth || 0;\n const zoom = (gridsterRect.width && unscaledWidth > 0)\n ? Math.max(0.2, Math.min(3, gridsterRect.width / unscaledWidth))\n : 1;\n\n const elements = typeof document.elementsFromPoint === 'function'\n ? document.elementsFromPoint(event.clientX, event.clientY)\n : [];\n // Nơi dùng khai `canDropInsideContainer: false` thì coi như KHÔNG rê qua khối ghép nào: không tô\n // ô li lên khối ghép, và bóng thả rơi về toạ độ cấp mặt phẳng — đúng chỗ khối sẽ nằm khi thả.\n const hovered = payload.canDropInsideContainer === false\n ? undefined\n : findHoveredGroup(elements, canvasContainer, root);\n\n const stageMouseX = (event.clientX - stageRect.left) / zoom;\n const stageMouseY = (event.clientY - stageRect.top) / zoom;\n\n if (hovered) {\n const { groupNode, groupGridster } = hovered;\n const groupGridsterRect = groupGridster.getBoundingClientRect();\n const groupStageLeft = (groupGridsterRect.left - stageRect.left) / zoom;\n const groupStageTop = (groupGridsterRect.top - stageRect.top) / zoom;\n\n let innerCols = defaultCols;\n let innerRows = defaultRows;\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sampleInside = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(true);\n if (sampleInside) {\n if (typeof sampleInside.cols === 'number') { innerCols = sampleInside.cols; }\n if (typeof sampleInside.rows === 'number') { innerRows = sampleInside.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n innerCols = Math.min(innerCols, totalCols);\n\n const groupWidth = groupGridster.clientWidth || (groupGridsterRect.width / zoom) || 400;\n const colStep = (groupWidth + 2) / totalCols;\n const rowStep = 18;\n const relX = (event.clientX - groupGridsterRect.left) / zoom + groupGridster.scrollLeft;\n const relY = (event.clientY - groupGridsterRect.top) / zoom + groupGridster.scrollTop;\n const rawCol = Math.floor(relX / colStep);\n const rawRow = Math.floor(relY / rowStep);\n const snap = findSnapPositionInsideGroup(\n groupNode.children ?? [],\n rawCol,\n rawRow,\n innerCols,\n innerRows,\n totalCols,\n );\n\n return {\n col: snap.col,\n row: snap.row,\n cols: innerCols,\n rows: innerRows,\n pixelLeft: groupStageLeft + snap.col * colStep,\n pixelTop: groupStageTop + snap.row * rowStep,\n pixelWidth: Math.max(30, innerCols * colStep - 2),\n pixelHeight: Math.max(20, innerRows * rowStep - 2),\n isInsideGroup: true,\n targetParentId: groupNode.id,\n groupTitle: 'Khối ghép',\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: groupGridster as HTMLElement,\n };\n }\n\n const margin = 12;\n const gridsterWidth = unscaledWidth || gridsterEl.clientWidth || 1200;\n const colStep = Math.max(20, (gridsterWidth - margin) / totalCols);\n const gridsterStageLeft = (gridsterRect.left - stageRect.left) / zoom;\n const gridsterStageTop = (gridsterRect.top - stageRect.top) / zoom;\n const relX = stageMouseX - gridsterStageLeft + gridsterEl.scrollLeft - margin;\n const relY = stageMouseY - gridsterStageTop + gridsterEl.scrollTop - margin;\n const itemCols = Math.min(defaultCols, totalCols);\n const col = Math.max(0, Math.min(totalCols - itemCols, Math.floor(relX / colStep)));\n const row = Math.max(0, Math.floor(relY / rowStep));\n\n return {\n col,\n row,\n cols: itemCols,\n rows: defaultRows,\n pixelLeft: gridsterStageLeft + margin + col * colStep,\n pixelTop: gridsterStageTop + margin + row * rowStep,\n pixelWidth: itemCols * colStep - margin,\n pixelHeight: defaultRows * rowStep - margin,\n isInsideGroup: false,\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: (rootGridster as HTMLElement) ?? undefined,\n };\n};\n\n\n/** Tìm khối theo id trong cây, đi sâu vào mọi container. */\nexport const findNodeRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n if (root.id === id) {\n return root;\n }\n\n for (const child of root.children ?? []) {\n const found = findNodeRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/** Tìm khối CHA trực tiếp của một khối, đi sâu vào mọi container. */\nexport const findParentRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n for (const child of root.children ?? []) {\n if (child.id === id) {\n return root;\n }\n\n const found = findParentRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/**\n * Thả khối vào đúng ô mà ghost đang chỉ, đẩy các khối va chạm xuống dưới.\n *\n * Ghost đang nằm trong một container (`isInsideGroup`) thì thả vào ruột container đó; không tìm thấy\n * container thì trả `false` chứ KHÔNG rơi về lưới gốc — thả nhầm cấp khó nhận ra hơn là không thả.\n */\nexport const dropNodeAtCoordinates = (\n root: T_gridLayout_node,\n ghost: T_gridLayout_dropGhost,\n newNode: T_gridLayout_newNode\n): boolean => {\n const nodeToAdd: T_gridLayout_node = {\n ...newNode,\n id: newNode.id ?? uuid(),\n x: ghost.col,\n y: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n };\n\n if (ghost.isInsideGroup && ghost.targetParentId) {\n const parentNode = findNodeRecursive(root, ghost.targetParentId);\n\n if (!parentNode) {\n return false;\n }\n parentNode.children = parentNode.children ?? [];\n resolveCollisionsAndInsert(parentNode.children, nodeToAdd);\n\n return true;\n }\n\n root.children = root.children ?? [];\n resolveCollisionsAndInsert(root.children, nodeToAdd);\n\n return true;\n};\n\n\n/** Khối có phải CONTAINER không — tức có khối con bên trong. */\nexport const isContainerNode = (node: T_gridLayout_node): boolean => (node.children?.length ?? 0) > 0;\n\n/** Khối có nằm LỒNG bên trong một container không (không phải con trực tiếp của gốc). */\nexport const isNodeNestedInside = (root: T_gridLayout_node | undefined, nodeId: string): boolean => {\n if (!root?.children) {\n return false;\n }\n\n return !root.children.some((child) => child.id === nodeId);\n};\n\n/**\n * Có được đổi khối đơn ↔ container không.\n *\n * 🔴 Ba hàm cờ này PHẢI là nguồn duy nhất cho cả thanh công cụ của thư viện lẫn menu do nơi dùng tự\n * dựng. Trước đây nơi dùng phải chép lại quy tắc để dựng menu trước lúc render, và hai bản lệch nhau\n * mỗi khi thư viện đổi trần lồng cấp mà không có gì báo.\n */\nexport const canToggleTypeNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) || !isNodeNestedInside(root, node.id);\n\n/** Có được thêm khối vào BÊN TRONG khối này không. */\nexport const canAddInsideNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) && !isNodeNestedInside(root, node.id);\n","import { Injectable } from '@angular/core';\nimport { uuid } from '@libs-ui/utils';\nimport { T_gridLayout_newNode, T_gridLayout_node } from './interfaces/grid-layout.interface';\nimport { resolveCollisionsAndInsert } from './defines/collision.define';\n\n/**\n * Thao tác trên cây khối: tìm, thêm, xoá, dồn khít, chặn lồng cấp quá sâu.\n *\n * 🔴 NỘI BỘ thư viện — không xuất ra ngoài. Nơi dùng đi qua `LibsUiGridLayoutService`, ở đó mỗi\n * thao tác sửa bố cục vừa vẽ lại vừa bắn `outChange` đúng MỘT lần. Các hàm ở đây cố tình KHÔNG tự\n * vẽ lại: để chúng tự gọi thì mỗi thao tác vẽ hai lượt và bắn hai sự kiện (người dùng chốt\n * 28/08/2026: \"đặt đúng các điểm mà làm cho layout có thể thay đổi thôi\").\n */\n@Injectable()\nexport class LibsUiGridLayoutTreeService {\n findById(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n if (node.id === id) {\n return node;\n }\n\n for (const child of node.children ?? []) {\n const found = this.findById(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n findParent(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n for (const child of node.children ?? []) {\n if (child.id === id) {\n return node;\n }\n\n const found = this.findParent(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n /**\n * Thêm khối vào cuối một container. Thư viện tự sinh `id` và tự đặt `x` · `y` xuống hàng trống.\n *\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addChild(root: T_gridLayout_node, parentId: string, item: T_gridLayout_newNode): T_gridLayout_node | undefined {\n const parent = this.findById(root, parentId);\n\n if (!parent) {\n return undefined;\n }\n\n parent.children = parent.children ?? [];\n // 🔴 Thư viện tự sinh `id`. Đây là mã máy dùng để tra cứu, không phải thứ người dùng nghĩ ra —\n // bắt họ tự đặt là mời họ tạo trùng, mà trùng id thì `findById` trả nhầm khối và cả cây hỏng\n // im lặng (người dùng chốt 28/08/2026).\n // 🔴 Mặc định VẪN tự xếp xuống hàng trống kế tiếp — giữ nguyên hành vi cũ.\n //\n // Chỉ khi nơi dùng bật `keepPosition` mới giữ `x`/`y` truyền vào. CẤM suy ra ý định từ chính giá\n // trị toạ độ (kiểu `item.y ?? ...`): `y: 0` là giá trị hợp lệ và cũng là thứ mọi hàm dựng node\n // điền sẵn, nên không tài nào phân biệt \"người ta muốn đặt ở hàng 0\" với \"người ta không quan\n // tâm\" — đoán sai là khối mới ĐÈ lên khối đang có.\n const node: T_gridLayout_node = {\n ...item,\n id: item.id ?? uuid(),\n x: item.keepPosition ? (item.x ?? 0) : 0,\n y: item.keepPosition ? (item.y ?? 0) : this.nextFreeRow(parent.children),\n };\n\n // Cờ điều khiển, không phải dữ liệu của khối — không để nó nằm lại trong cây.\n delete (node as Partial<T_gridLayout_newNode>).keepPosition;\n\n parent.children.push(node);\n\n // Trả về khối vừa tạo để nơi dùng biết `id` thư viện vừa sinh.\n return node;\n }\n\n /**\n * Thêm khối vào vị trí (x, y) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertWithCollision(\n root: T_gridLayout_node,\n parentId: string | undefined,\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n ): T_gridLayout_node | undefined {\n const targetParent = parentId ? this.findById(root, parentId) : root;\n\n if (!targetParent) {\n return undefined;\n }\n\n targetParent.children = targetParent.children ?? [];\n const node: T_gridLayout_node = {\n ...item,\n id: item.id ?? uuid(),\n x: targetCol,\n y: targetRow,\n };\n\n resolveCollisionsAndInsert(targetParent.children, node);\n\n return node;\n }\n\n /** Xoá một khối khỏi cây. Không cho xoá gốc. */\n removeById(root: T_gridLayout_node, id: string): boolean {\n if (root.id === id) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n if (!parent?.children) {\n return false;\n }\n\n parent.children = parent.children.filter((item) => item.id !== id);\n\n return true;\n }\n\n /**\n * Chuyển một khối đơn thành CONTAINER: nội dung cũ trở thành khối con đầu tiên.\n *\n * Không mất dữ liệu — `data` của khối được mang theo xuống khối con.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối đã là container rồi.\n */\n toContainer(root: T_gridLayout_node, id: string, colCount: number): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) > 0) {\n return false;\n }\n\n node.children = [{ ...node, id: uuid(), x: 0, y: 0, cols: colCount, rows: 4, children: [] }];\n\n return true;\n }\n\n /**\n * Chuyển một CONTAINER về khối đơn: các khối con được NÂNG lên cấp trên, không bị xoá.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối vốn không phải container.\n */\n toSingle(root: T_gridLayout_node, id: string): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) === 0) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n for (const child of node.children ?? []) {\n parent?.children?.push({ ...child, cols: node.cols, rows: 2 });\n }\n\n node.children = [];\n\n return true;\n }\n\n /**\n * Làm phẳng mọi container lồng vượt trần.\n *\n * 🔴 Cần thiết vì bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện. Một bản lưu cũ — sinh\n * trước khi có trần, hoặc do thao tác lỗi — vẫn nạp thẳng vào và hiện container lồng container.\n * Container vượt trần bị hạ thành khối thường, con của nó nâng lên cấp trên: KHÔNG mất dữ liệu.\n *\n * @returns số container đã làm phẳng\n */\n flattenOverDepthContainers(node: T_gridLayout_node, maxDepth: number): number {\n return this.walkFlatten(node, 0, maxDepth);\n }\n\n /**\n * Dồn khối khít lên trên theo thứ tự đọc, lấp hết chỗ trống.\n *\n * 🔴 KHÔNG sửa `node.rows` của container. Chiều cao container tính theo đơn vị hàng của lưới CHA,\n * còn `currentRow` đếm theo đơn vị hàng của lưới CON — trộn hai thang đo là container phình lên\n * gấp mấy lần.\n */\n compact(node: T_gridLayout_node, colCount: number): void {\n this.walkCompact(node, colCount);\n }\n\n private walkCompact(node: T_gridLayout_node, colCount: number): void {\n const children = node.children;\n\n if (!children?.length) {\n return;\n }\n\n const inReadingOrder = [...children].sort((a, b) => a.y - b.y || a.x - b.x);\n let currentRow = 0;\n let usedCols = 0;\n let tallestInRow = 0;\n\n for (const item of inReadingOrder) {\n const width = Math.min(item.cols, colCount);\n\n if (usedCols > 0 && usedCols + width > colCount) {\n currentRow += tallestInRow;\n usedCols = 0;\n tallestInRow = 0;\n }\n\n item.x = usedCols;\n item.y = currentRow;\n item.cols = width;\n usedCols += width;\n tallestInRow = Math.max(tallestInRow, item.rows);\n\n if ((item.children?.length ?? 0) > 0) {\n this.walkCompact(item, colCount);\n }\n }\n }\n\n private walkFlatten(node: T_gridLayout_node, containerDepth: number, maxDepth: number): number {\n const children = node.children;\n\n if (!children?.length) {\n return 0;\n }\n\n let fixedCount = 0;\n const result: Array<T_gridLayout_node> = [];\n\n for (const child of children) {\n const isContainer = (child.children?.length ?? 0) > 0;\n\n if (isContainer && containerDepth >= maxDepth) {\n fixedCount += 1;\n\n for (const item of child.children ?? []) {\n fixedCount += this.walkFlatten(item, containerDepth, maxDepth);\n result.push(item);\n }\n\n continue;\n }\n\n fixedCount += this.walkFlatten(child, isContainer ? containerDepth + 1 : containerDepth, maxDepth);\n result.push(child);\n }\n\n node.children = result;\n\n return fixedCount;\n }\n\n private nextFreeRow(children: Array<T_gridLayout_node>): number {\n return children.reduce((max, child) => Math.max(max, child.y + child.rows), 0);\n }\n}\n","import { ComponentRef, DestroyRef, Injectable, TemplateRef, ViewContainerRef, inject, signal } from '@angular/core';\nimport { GridsterComponentInterface, GridsterConfig, GridsterItem } from 'gridster18';\nimport { cloneDeep } from '@libs-ui/utils';\nimport { Subscription, take } from 'rxjs';\nimport { gridLayoutNestedConfig, gridLayoutRootConfig } from './defines/gridster-config.define';\nimport { findNodeRecursive, findParentRecursive } from './defines/collision.define';\nimport { LibsUiGridLayoutTreeService } from './tree.service';\nimport {\n E_gridLayout_mode_string,\n T_gridLayout_changeEvent,\n T_gridLayout_newNode,\n T_gridLayout_config,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\n\n/**\n * Dựng một mặt phẳng kéo thả và tự gắn component của nơi dùng lên từng khối.\n *\n * Nơi dùng chỉ cần đưa vào: loại component muốn dựng\n * (`nodeComponentType`) và cây dữ liệu (`data`). Toàn bộ việc vẽ lưới, kéo thả, đổi kích thước,\n * lồng container và dọn dẹp do thư viện lo.\n *\n * 🔴 Đây là service theo TỪNG mặt phẳng, KHÔNG `providedIn: 'root'`. Khai trong `providers` của\n * component dùng nó; hai mặt phẳng trên cùng một màn phải là hai thực thể riêng, dùng chung thì\n * `componentRefs` của mặt phẳng này bị mặt phẳng kia dọn mất.\n */\n@Injectable()\nexport class LibsUiGridLayoutService {\n // 🔴 TỰ TẠO, không `inject`. Nơi dùng chỉ phải viết `providers: [LibsUiGridLayoutService]` —\n // không phải biết bên trong thư viện còn service nào khác (người dùng chốt 28/08/2026).\n // `TreeService` không giữ trạng thái dùng chung nên mỗi mặt phẳng một bản là đúng.\n private readonly treeService = new LibsUiGridLayoutTreeService();\n /** Lượt tải component đang chờ, theo id khối — để huỷ khi khối bị gỡ giữa chừng. */\n private readonly pendingLoads = new Map<string, Subscription>();\n /**\n * Bộ theo dõi bề rộng của từng lưới LỒNG, để ngắt khi service bị huỷ.\n *\n * 🔴 Giữ tham chiếu là BẮT BUỘC: `ResizeObserver` không tự tắt theo vòng đời component. Không dọn\n * thì mỗi lần nạp lại bố cục (đổi tab) lại chồng thêm một bộ, và chúng vẫn chạy trên DOM đã gỡ.\n */\n private readonly nestedResizeObservers = new Set<ResizeObserver>();\n\n constructor() {\n // 🔴 Service khai trong `providers` của component nên Angular huỷ nó cùng component — thư viện\n // tự dọn ở đây, nơi dùng KHÔNG phải gọi `destroy()` trong `ngOnDestroy` (người dùng chốt\n // 28/08/2026). Bắt nhớ một bước dọn dẹp là kiểu API dễ quên, và quên thì rò rỉ bộ nhớ im lặng.\n inject(DestroyRef).onDestroy(() => this.destroy());\n }\n\n private config?: T_gridLayout_config;\n private readonly componentRefs = new Map<string, ComponentRef<unknown>>();\n\n private readonly rootNode = signal<T_gridLayout_node | undefined>(undefined);\n private readonly editMode = signal<boolean>(false);\n /** tăng mỗi lần cây đổi — component con đọc để biết phải tính lại */\n private readonly version = signal<number>(0);\n private readonly zoomLevel = signal<number>(1);\n\n /**\n * Signal chỉ đọc để nơi dùng theo dõi.\n *\n * 🔴 Là THUỘC TÍNH, không phải getter. Getter trả signal thì chỗ đọc phải viết `Version()()` —\n * quên cặp ngoặc thứ hai là computed KHÔNG phụ thuộc vào nó, cây đổi mà lưới đứng im, và\n * TypeScript không hề báo lỗi (đo 28/08/2026: thêm khối không hiện, sắp gọn không nhúc nhích).\n */\n readonly Root = this.rootNode.asReadonly();\n readonly IsEditMode = this.editMode.asReadonly();\n /** tăng mỗi lần cây hoặc cấu hình đổi */\n readonly Version = this.version.asReadonly();\n readonly Zoom = this.zoomLevel.asReadonly();\n\n /**\n * trần số cấp container lồng nhau — canvas đọc để biết có cho chuyển thành container không */\n private maxContainerDepth(): number {\n return this.config?.maxContainerDepth ?? 1;\n }\n\n /**\n * lề trong của container, px — canvas đọc để đặt padding lên vỏ container */\n private containerPadding(): number {\n return this.config?.containerPadding ?? 12;\n }\n\n /** Khởi tạo mặt phẳng. Gọi lại sẽ dọn sạch component cũ rồi dựng lại từ đầu. */\n init(config: T_gridLayout_config): void {\n this.destroy();\n this.config = config;\n // 🔴 Bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện: bản lưu cũ (sinh trước khi có trần,\n // hoặc do thao tác lỗi) vẫn mang container lồng container. Trần `maxContainerDepth` chỉ ẩn NÚT\n // trên canvas — nó không sửa dữ liệu, nên thiếu dòng này là vẽ ra đúng cây quá sâu đó.\n // Nơi dùng KHÔNG tự gọi được: `LibsUiGridLayoutTreeService` cố ý không xuất.\n this.treeService.flattenOverDepthContainers(config.data, this.maxContainerDepth());\n this.assignOverlapLayers(config.data);\n // 🔴 Nhân bản như `refresh()`: `init()` lại (đổi chế độ, bật/tắt chồng khối) trên CÙNG object cây\n // thì `@for` không dựng lại `gridster-item`, nên `layerIndex` vừa gán không tới `$item` và khối\n // vẫn không đè nhau được (đo 28/08/2026: `item.layerIndex` = 1|2|3|4|7 mà `$item.layerIndex`\n // toàn `undefined`).\n this.rootNode.set(this.shallowCloneTree(config.data));\n this.editMode.set(config.isEditMode ?? false);\n\n let initialZoom = config.initialZoom ?? 1;\n if (config.storageKey && typeof localStorage !== 'undefined') {\n try {\n const saved = localStorage.getItem(config.storageKey);\n if (saved) {\n const parsed = parseFloat(saved);\n const min = config.zoomMin ?? 0.4;\n const max = config.zoomMax ?? 1.5;\n if (!isNaN(parsed) && parsed >= min && parsed <= max) {\n initialZoom = parsed;\n }\n }\n } catch {\n // ignore localStorage access error\n }\n }\n this.zoomLevel.set(initialZoom);\n\n this.version.update((v) => v + 1);\n }\n\n setEditMode(value: boolean): void {\n this.editMode.set(value);\n // 🔴 PHẢI bơm `version`: `gridsterOptions()` đọc `editMode` để bật/tắt kéo–thả, mà computed\n // `gridOptions` bên canvas chỉ chạy lại khi `Version` đổi. Thiếu dòng này thì đổi chế độ xong\n // gridster vẫn giữ options cũ — chuyển sang XEM mà khối vẫn kéo được.\n this.version.update((v) => v + 1);\n }\n\n /**\n * Đổi số hàng TỐI THIỂU của lưới cấp trang — KHÔNG dựng lại mặt phẳng.\n *\n * 🔴 `minRows` chỉ được đọc MỘT LẦN lúc `init()`, nên nơi dùng muốn đổi nó theo chế độ (sửa thì ô\n * li phủ kín màn, xem thì đúng số hàng của bố cục) buộc phải gọi `init()` lại — mà `init()` huỷ\n * sạch rồi dựng lại mọi component nội dung. Hệ quả đo được 15/09/2026: mở ở chế độ xem rồi bấm\n * Sửa thì lưới đứng ở số hàng của bố cục (28 hàng = 448px) trong khi vùng nhìn cao hơn nhiều, nên\n * ô li ngừng ngay dưới khối cuối và phần còn lại trống trơn không có đường kẻ nào.\n */\n setMinRows(value: number): void {\n if (!this.config || !Number.isFinite(value) || value <= 0) {\n return;\n }\n\n this.config = { ...this.config, minRows: value };\n // Bơm `version` để `gridOptions` bên canvas tính lại — cùng lý do như `setEditMode`.\n this.version.update((v) => v + 1);\n }\n\n /**\n * Bật/tắt cho khối chồng lên nhau — KHÔNG dựng lại mặt phẳng.\n *\n * Trước đây nơi dùng phải gọi `init()` lại để đổi cờ này, mà `init()` huỷ sạch rồi dựng lại mọi\n * component nội dung — lãng phí, và người dùng thấy màn chớp (người dùng chốt 28/08/2026).\n */\n setAllowOverlap(value: boolean): void {\n if (!this.config) {\n return;\n }\n\n this.config = { ...this.config, allowOverlap: value };\n\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n // 🔴 Gán lớp vào CÂY ĐANG VẼ (`rootNode`), KHÔNG phải `config.data`.\n // `init()` đã clone `config.data` sang `rootNode` nên hai object KHÁC nhau; gán vào `config.data`\n // thì `refresh()` clone lại từ `rootNode` — lớp vừa gán không tới `gridster-item` nào, `z-index`\n // của mọi khối đứng ở `1` và khối nào vẽ sau thì nằm trên: chồng khối \"lúc được lúc không\"\n // (đo 04/09/2026: `item.layerIndex` undefined, `getLayerIndex()` = 0 cho cả 8 khối).\n this.assignOverlapLayers(root);\n // Thay tham chiếu cây để `layerIndex` vừa gán tới được `$item` của gridster; component nội dung\n // KHÔNG bị dựng lại vì `attachNode` nhận ra id cũ và chỉ `setInput`.\n this.refresh();\n }\n\n /**\n *\n * Cấu hình gridster cho một cấp lưới.\n *\n * @param depth 0 = lưới cấp trang, ≥ 1 = lưới lồng trong container\n */\n private buildGridsterOptions(depth: number, itemChangeCallback?: () => void): GridsterConfig {\n const base = depth === 0 ? gridLayoutRootConfig() : gridLayoutNestedConfig();\n const config = this.config;\n\n if (!config) {\n return base;\n }\n\n const isFreeMode = config.mode === E_gridLayout_mode_string.free;\n const canEdit = this.editMode();\n const canOverlap = isFreeMode || (config.allowOverlap ?? false);\n\n return {\n ...base,\n scale: this.zoomLevel(),\n ...(config.cols ? { minCols: config.cols, maxCols: config.cols, maxItemCols: config.cols } : {}),\n ...(config.rowHeight && depth === 0 ? { fixedRowHeight: config.rowHeight } : {}),\n ...(depth === 0 && config.minRows !== undefined ? { minRows: config.minRows } : {}),\n ...(depth > 0 && config.nestedMinRows !== undefined ? { minRows: config.nestedMinRows } : {}),\n // Khe và chiều cao hàng khác nhau theo cấp: lưới trang thoáng, lưới lồng khít.\n ...(depth === 0 && config.margin !== undefined ? { margin: config.margin } : {}),\n ...(depth > 0 && config.nestedMargin !== undefined ? { margin: config.nestedMargin } : {}),\n ...(depth > 0 && config.nestedRowHeight !== undefined ? { fixedRowHeight: config.nestedRowHeight } : {}),\n ...(depth === 0 && config.outerMargin !== undefined ? { outerMargin: config.outerMargin } : {}),\n ...(depth === 0 && config.outerMarginBottom !== undefined ? { outerMarginBottom: config.outerMarginBottom } : {}),\n ...(depth === 0 && config.outerMarginTop !== undefined ? { outerMarginTop: config.outerMarginTop } : {}),\n ...(config.minItemRows !== undefined ? { minItemRows: config.minItemRows } : {}),\n ...(config.defaultItemCols !== undefined ? { defaultItemCols: config.defaultItemCols } : {}),\n ...(config.defaultItemRows !== undefined ? { defaultItemRows: config.defaultItemRows } : {}),\n\n // 🔴 Chế độ XEM phải TẮT hẳn kéo và đổi kích thước.\n // `base` luôn để `enabled: true`; không ghi đè theo `editMode` thì người xem vẫn kéo được khối\n // và đổi bố cục của người khác (người dùng báo 28/08/2026: \"đang xem mà vẫn kéo thả thay đổi\n // vị trí và thêm khối được\").\n draggable: { ...base.draggable, enabled: canEdit },\n resizable: { ...base.resizable, enabled: canEdit },\n\n // Chế độ tự do LUÔN cho chồng; chế độ lưới thì theo cờ của nơi dùng.\n allowMultiLayer: canOverlap,\n // 🔴 Bật `allowMultiLayer` MỘT MÌNH không đủ. Mã lib so `layerIndex` của hai khối: KHÁC nhau\n // thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n // `defaultLayerIndex` — tức cùng lớp, và vẫn bị đẩy nhau như lưới thường (người dùng báo\n // 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n // Cho chồng thì phải TẮT đẩy khối, nếu không khối bị dạt đi trước khi kịp đè lên nhau.\n ...(canOverlap ? { pushItems: false, pushResizeItems: false, swap: false, swapWhileDragging: false } : {}),\n\n ...this.buildNestedResizeHooks(base, depth),\n\n itemChangeCallback: (item: GridsterItem) => {\n // 🔴 Khối vừa thao tác phải lên LỚP TRÊN CÙNG.\n // `layerIndex` gán một lần theo thứ tự cây lúc khởi tạo, nên khối kéo lên chỉ nổi TRONG LÚC\n // kéo (nhờ `z-index: 30` của lớp `gridster-item-moving`); thả tay ra là về lớp cũ và bị khối\n // đứng sau trong cây đè ngược lên (người dùng báo 28/08/2026, đo được: kéo z=30, thả về\n // z=10 trong khi hai khối kế bên đang z=11 và z=12).\n if (canOverlap) {\n this.raiseToTopLayer(item);\n }\n\n this.version.update((v) => v + 1);\n itemChangeCallback?.();\n },\n };\n }\n\n /**\n * Bắt lưới LỒNG đo lại NGAY khi khung chứa nó đổi bề rộng — dùng lúc người dùng kéo mép khối cha.\n *\n * Gridster có sẵn đường tự đo (`resize$`), nhưng luồng đó là `switchMap(() => timer(100))`: mỗi\n * lần phát lại huỷ timer trước, mà kéo chuột bắn dày hơn 100ms nên timer không bao giờ tới đích.\n * Đo được (11/09/2026): kéo mép nhóm thì lưới con co theo cha từng khung hình (234 → 384 px) còn\n * THẺ con đứng im ở 106 px suốt cú kéo, chỉ nhảy đúng sau khi thả tay.\n *\n * Giữ CẢ HAI đường: `itemResizeCallback` bắn đồng bộ ngay khi gridster ghi bề rộng mới lên khối\n * (sớm hơn `ResizeObserver` một khung hình) lo độ tức thì; `ResizeObserver` lo những lần khung đổi\n * vì lý do khác — đổi zoom, thu gọn cột bên trái.\n *\n * Tắt bằng `config.autoResizeNestedGrids: false`.\n */\n private buildNestedResizeHooks(base: GridsterConfig, depth: number): Partial<GridsterConfig> {\n if (this.config?.autoResizeNestedGrids === false) {\n return {};\n }\n const gocItemResize = base.itemResizeCallback;\n const gocInit = base.initCallback;\n\n return {\n itemResizeCallback: (item, itemComponent) => {\n gocItemResize?.(item, itemComponent);\n const el = (itemComponent as { el?: HTMLElement } | undefined)?.el;\n\n el?.querySelectorAll('gridster').forEach((nested) => this.resizeGridsterElement(nested as HTMLElement));\n },\n ...(depth > 0\n ? { initCallback: (gridster: GridsterComponentInterface) => this.registerNestedGrid(gridster, gocInit) }\n : {}),\n };\n }\n\n /** Gọi `resize()` của một thẻ `<gridster>` qua chính instance mà nó tự gắn lên phần tử. */\n private resizeGridsterElement(nested: HTMLElement): void {\n const giuInstance = nested as unknown as { __gridsterInstance?: { options?: { api?: { resize?: () => void } } } };\n\n giuInstance.__gridsterInstance?.options?.api?.resize?.();\n }\n\n /**\n * Gắn instance lên chính phần tử `<gridster>` rồi theo dõi bề rộng của nó.\n *\n * Phải gắn ngược lên DOM vì `itemResizeCallback` của khối CHA chỉ cầm được `HTMLElement`, không có\n * đường nào khác đi từ đó về instance của lưới lồng bên trong.\n */\n private registerNestedGrid(\n gridster: GridsterComponentInterface,\n goc?: (gridster: GridsterComponentInterface) => void\n ): void {\n goc?.(gridster);\n const instance = gridster as unknown as { el?: HTMLElement; options?: { api?: { resize?: () => void } } } | undefined;\n const el = instance?.el;\n\n if (!el || typeof ResizeObserver === 'undefined') {\n return;\n }\n (el as unknown as { __gridsterInstance?: unknown }).__gridsterInstance = instance;\n\n const theoDoi = new ResizeObserver(() => instance?.options?.api?.resize?.());\n\n theoDoi.observe(el);\n this.nestedResizeObservers.add(theoDoi);\n }\n\n /**\n *\n * Gắn component của nơi dùng lên một khối.\n *\n * @param host chỗ gắn RIÊNG của ô đó — mỗi khối một `ViewContainerRef`, dùng chung một cái thì\n * mọi component bị dồn hết vào một ô.\n * @param childCanvas khuôn mặt phẳng LỒNG của khối, chỉ có với khối container tự khai\n * `getComponentOutlet`. Component vỏ nhận nó qua input `childCanvas` và tự đặt vào giữa tiêu đề\n * với phần thân của mình. Không truyền xuống thì vỏ chiếm trọn chiều cao khối và đẩy toàn bộ thẻ\n * con ra ngoài vùng nhìn thấy.\n */\n private attachNode(\n node: T_gridLayout_node,\n depth: number,\n host: ViewContainerRef,\n childCanvas?: TemplateRef<unknown>\n ): void {\n const config = this.config;\n\n if (!config) {\n return;\n }\n\n const existing = this.componentRefs.get(node.id);\n\n if (existing) {\n this.applyInputs(existing, node, depth, childCanvas);\n\n return;\n }\n\n // Khối tự khai thì hỏi nó; không thì hỏi hàm phân giải chung. Cả hai đều nhận `node` để đọc\n // được `data.type` mà quyết định trả component nào.\n const stream = (node.getComponentOutlet ?? config.getComponentOutlet)?.(node);\n\n if (!stream) {\n return;\n }\n\n // 🔴 Huỷ lượt tải CŨ của đúng khối này trước khi mở lượt mới.\n // Khối bị gỡ rồi gắn lại (đổi bố cục, sắp gọn) trong lúc `import()` chưa xong thì lượt cũ vẫn\n // chạy tiếp và dựng component vào một `ViewContainerRef` đã chết.\n this.pendingLoads.get(node.id)?.unsubscribe();\n\n const sub = stream.pipe(take(1)).subscribe((componentType) => {\n this.pendingLoads.delete(node.id);\n\n // Khối có thể đã bị xoá trong lúc chờ tải — dựng vào đây là rò rỉ.\n if (!this.treeService.findById(this.rootNode() ?? node, node.id)) {\n return;\n }\n\n const ref = host.createComponent(componentType);\n\n this.applyInputs(ref, node, depth, childCanvas);\n this.componentRefs.set(node.id, ref);\n });\n\n this.pendingLoads.set(node.id, sub);\n }\n\n /**\n * Gỡ component của một khối và huỷ nó. */\n private detachNode(nodeId: string): void {\n // Khối bị gỡ khi component của nó còn đang tải — phải huỷ lượt tải, không thì nó dựng vào một\n // `ViewContainerRef` đã chết.\n this.pendingLoads.get(nodeId)?.unsubscribe();\n this.pendingLoads.delete(nodeId);\n\n const ref = this.componentRefs.get(nodeId);\n\n if (!ref) {\n return;\n }\n\n ref.destroy();\n this.componentRefs.delete(nodeId);\n }\n\n private destroy(): void {\n for (const sub of this.pendingLoads.values()) {\n sub.unsubscribe();\n }\n\n for (const ref of this.componentRefs.values()) {\n ref.destroy();\n }\n\n for (const observer of this.nestedResizeObservers) {\n observer.disconnect();\n }\n\n this.pendingLoads.clear();\n this.componentRefs.clear();\n this.nestedResizeObservers.clear();\n this.config = undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // Nhóm hàm cho nơi dùng CHỦ ĐỘNG gọi — không phải chờ người dùng bấm nút trên khối.\n // Sửa cây thì dùng thẳng `TreeService` rồi gọi `refresh()` — xem demo trong core-ui.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Báo cho service biết cây vừa đổi từ bên ngoài (thêm/xoá khối, sắp gọn, nạp bố cục khác).\n *\n * 🔴 PHẢI thay THAM CHIẾU của node gốc, không chỉ bơm `version`.\n * `@for … track item.id` giữ nguyên object khi id không đổi, nên `<gridster-item [item]=\"…\">` vẫn\n * nhận đúng object cũ và gridster không hề biết `x/y/cols/rows/layerIndex` vừa bị sửa. Bơm mỗi\n * `version` thì computed chạy lại nhưng trả về CÙNG mảng cũ — lưới đứng im (đo 28/08/2026: bấm\n * \"Sắp gọn\" cây đã dồn khít mà màn hình không nhúc nhích; bật chồng khối mà `$item.layerIndex`\n * vẫn trống).\n *\n * Nhân bản NÔNG cả node gốc và danh sách con là đủ: mảng mới → `@for` dựng lại item, object con\n * mới → gridster đọc lại toàn bộ toạ độ.\n */\n refresh(event?: T_gridLayout_changeEvent): void {\n const root = event?.root ?? this.rootNode();\n\n if (!root) {\n this.version.update((v) => v + 1);\n\n return;\n }\n\n if (this.config) {\n this.config = { ...this.config, data: root };\n }\n\n this.rootNode.set(this.shallowCloneTree(root));\n this.version.update((v) => v + 1);\n }\n\n /** Nhân bản nông theo cả chiều sâu: mỗi node và mảng `children` thành tham chiếu mới. */\n /**\n * Nhân bản SÂU cả cây — dùng cho `exportLayout()`.\n *\n * 🔴 BỎ `getComponentOutlet` khỏi bản sao: nó là một HÀM, không tuần tự hoá được nên gửi xuống\n * backend là hỏng (`JSON.stringify` nuốt mất, `structuredClone` ném lỗi). Nạp lại thì hàm phân\n * giải chung của cấu hình lo — component suy ra từ `data.type`, không cần lưu.\n */\n private deepCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n const copy: T_gridLayout_node = { ...node };\n\n // Cắt hàm phân giải — xem chú thích trên.\n delete copy.getComponentOutlet;\n\n const { children, data, ...rest } = copy;\n\n return {\n ...rest,\n ...(data === undefined ? {} : { data: cloneDeep(data) }),\n ...(children ? { children: children.map((child) => this.deepCloneTree(child)) } : {}),\n };\n }\n\n private shallowCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n if (!node.children?.length) {\n return { ...node };\n }\n\n return { ...node, children: node.children.map((child) => this.shallowCloneTree(child)) };\n }\n\n /**\n * Gán `layerIndex` khác nhau cho từng khối khi bật chồng khối.\n *\n * 🔴 `allowMultiLayer: true` MỘT MÌNH không cho khối đè nhau. Mã lib so `layerIndex` của hai khối:\n * KHÁC nhau thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n * `defaultLayerIndex` — tức CÙNG lớp, nên kéo vào nhau là bị chặn y như lưới thường (người dùng\n * báo 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n *\n * Nơi dùng tự khai `layerIndex` thì giữ nguyên; ai không khai thì thư viện xếp mỗi khối một lớp\n * theo thứ tự, đủ để mọi cặp đều khác lớp.\n */\n private assignOverlapLayers(root: T_gridLayout_node): void {\n const config = this.config;\n const canOverlap = config?.mode === E_gridLayout_mode_string.free || (config?.allowOverlap ?? false);\n\n if (!canOverlap) {\n return;\n }\n\n let layer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n if (child.layerIndex === undefined) {\n layer += 1;\n child.layerIndex = layer;\n }\n\n walk(child);\n }\n };\n\n walk(root);\n\n }\n\n /** Đưa một khối lên trên tất cả: lớp của nó = lớp lớn nhất đang có + 1. */\n private raiseToTopLayer(item: GridsterItem): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n let topLayer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n topLayer = Math.max(topLayer, child.layerIndex ?? 0);\n walk(child);\n }\n };\n\n walk(root);\n\n // `item` gridster trả về CHÍNH là object node của cây (truyền thẳng qua `[item]`), nên gán vào\n // đây là cây cũng đổi theo.\n const node = item as unknown as T_gridLayout_node;\n\n if (node.layerIndex === topLayer) {\n\n return;\n }\n\n node.layerIndex = topLayer + 1;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // SỬA CÂY — thư viện đã giữ cây nên bạn KHÔNG phải truyền nó vào.\n // Mọi hàm dưới đây tự vẽ lại; không cần gọi `refresh()`.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Thêm một khối.\n *\n * @param item khối mới — KHÔNG cần `id` (thư viện sinh) và `x`/`y` (tự đặt xuống hàng trống).\n * @param parentId container muốn thêm vào; bỏ trống thì thêm vào mặt phẳng gốc.\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addBlock(item: T_gridLayout_newNode, parentId?: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root ? this.treeService.addChild(root, parentId ?? root.id, item) : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n /**\n * Thêm một khối tại toạ độ (col, row) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertBlockWithCollision(\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n parentId?: string,\n ): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root\n ? this.treeService.insertWithCollision(root, parentId ?? root.id, item, targetCol, targetRow)\n : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n private readonly activeDragPayload = signal<unknown | undefined>(undefined);\n\n /** Đặt payload khi bắt đầu kéo từ bên ngoài vào (ví dụ: palette, drawer) */\n setDragPayload(payload: unknown): void {\n this.activeDragPayload.set(payload);\n }\n\n /** Lấy payload đang kéo */\n getDragPayload(): unknown {\n return this.activeDragPayload();\n }\n\n /** Xoá payload khi kết thúc kéo */\n clearDragPayload(): void {\n this.activeDragPayload.set(undefined);\n }\n\n /** Xoá một khối. Xoá container là xoá cả ruột. Trả `false` khi không xoá được (vd khối gốc). */\n removeBlock(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.removeById(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /**\n * Số cột thật của lưới cấp trang.\n *\n * 🔴 Mặc định phải TRÙNG `minCols/maxCols` của `gridLayoutRootConfig()`. Trước đây chỗ này trả 24\n * trong khi lưới vẽ 12: nơi dùng không truyền `cols` thì va chạm, `toContainer` và `compact` tính\n * theo 24 cột còn màn hình chỉ có 12 — khối rơi ra ngoài mép phải mà không ai hiểu vì sao.\n */\n get totalColumns(): number {\n return this.config?.cols ?? gridLayoutRootConfig().maxCols ?? 12;\n }\n\n /**\n * Chiều cao một hàng lưới (pixel) dùng để tính khung xem trước lúc kéo thả.\n *\n * 🔴 Phải đọc từ `config.rowHeight` của nơi dùng. Trước đây `calculateDropGhost` đóng cứng 68, nên\n * mặt phẳng khai hàng thấp thì khung xem trước cao gấp nhiều lần khối thật — nơi dùng phải ẩn khung\n * của thư viện đi rồi tự vẽ lại.\n */\n get rowStepPx(): number {\n return this.config?.rowHeight ?? gridLayoutRootConfig().fixedRowHeight ?? 68;\n }\n\n /**\n * Khe NHÌN THẤY giữa hai khối cấp gốc (px). `0` = không áp, giữ đúng hành vi cũ.\n */\n get visualGapPx(): number {\n return this.config?.visualGap ?? 0;\n }\n\n /**\n * Đổi số cột / số hàng của một khối rồi vẽ lại.\n *\n * Kéo `cols` rộng quá mép phải thì dịch khối sang trái cho vừa, thay vì để nó tràn ra ngoài lưới.\n */\n resizeBlock(id: string, size: { cols?: number; rows?: number }): boolean {\n const node = this.findBlock(id);\n\n if (!node) {\n return false;\n }\n\n if (size.cols !== undefined) {\n node.cols = size.cols;\n if (node.x + size.cols > this.totalColumns) {\n node.x = Math.max(0, this.totalColumns - size.cols);\n }\n }\n\n if (size.rows !== undefined) {\n node.rows = size.rows;\n }\n this.refresh();\n\n return true;\n }\n\n /**\n * Nhân bản một khối — đặt kế bên phải nếu còn chỗ, không thì xuống dòng dưới.\n *\n * `transformData` để nơi dùng đổi phần dữ liệu riêng của mình (vd nối thêm \"(Bản sao)\" vào tiêu\n * đề); thư viện không tự đoán trường nào là tiêu đề.\n */\n duplicateBlock(id: string, transformData?: (data: unknown) => unknown): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const node = root ? findNodeRecursive(root, id) : undefined;\n\n if (!root || !node) {\n return undefined;\n }\n const parent = findParentRecursive(root, id);\n const isNested = Boolean(parent && parent.id !== root.id);\n const clonedData = cloneDeep(node.data);\n\n let targetX = node.x + node.cols;\n let targetY = node.y;\n\n if (targetX + node.cols > this.totalColumns) {\n targetX = 0;\n targetY = node.y + node.rows;\n }\n\n return this.addBlock(\n {\n x: targetX,\n y: targetY,\n cols: node.cols,\n rows: node.rows,\n data: transformData ? transformData(clonedData) : clonedData,\n getComponentOutlet: node.getComponentOutlet,\n },\n isNested ? parent?.id : undefined\n );\n }\n\n /** Biến khối đơn thành CONTAINER — nội dung cũ thành khối con đầu tiên, không mất dữ liệu. */\n toContainer(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toContainer(root, id, this.totalColumns) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Đưa CONTAINER về khối đơn — khối con được nâng lên cấp trên, không bị xoá. */\n toSingle(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toSingle(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Dồn khối khít lên trên, lấp hết chỗ trống. Đệ quy vào container. */\n compact(): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n this.treeService.compact(root, this.totalColumns);\n this.refresh();\n }\n\n /**\n * Bố cục HIỆN TẠI, đã cắt mọi tham chiếu — gửi thẳng xuống backend được.\n *\n * Dùng khi bấm nút Lưu. Khác `Root()` ở chỗ đây là bản SAO: nơi dùng có sửa gì trên kết quả cũng\n * không đụng tới cây mà thư viện đang vẽ.\n *\n * @returns `undefined` khi mặt phẳng chưa `init()`.\n */\n exportLayout(): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.deepCloneTree(root) : undefined;\n }\n\n /** Tìm một khối theo id. */\n findBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findById(root, id) : undefined;\n }\n\n /** Tìm khối cha trực tiếp của một khối. */\n findParentBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findParent(root, id) : undefined;\n }\n\n /**\n * Đặt tỷ lệ thu phóng của canvas (kẹp giữa min và max).\n *\n * @param value Tỷ lệ (0.4 = 40%, 1.0 = 100%, 1.5 = 150%)\n * @param persistKey Khóa localStorage để lưu lại (bỏ trống thì lấy từ config)\n */\n setZoom(value: number, persistKey?: string): void {\n const min = this.config?.zoomMin ?? 0.4;\n const max = this.config?.zoomMax ?? 1.5;\n const clamped = Math.min(max, Math.max(min, Math.round(value * 100) / 100));\n this.zoomLevel.set(clamped);\n\n const storageKey = persistKey ?? this.config?.storageKey;\n if (storageKey && typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(storageKey, String(clamped));\n } catch {\n // ignore localStorage access error\n }\n }\n\n this.version.update((v) => v + 1);\n }\n\n /** Phóng to thêm một bước (mặc định 0.05 tức 5%) */\n zoomIn(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() + s, persistKey);\n }\n\n /** Thu nhỏ bớt một bước (mặc định 0.05 tức 5%) */\n zoomOut(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() - s, persistKey);\n }\n\n /** Đặt lại tỷ lệ thu phóng gốc 100% (1.0) */\n resetZoom(persistKey?: string): void {\n this.setZoom(1.0, persistKey);\n }\n\n /**\n * Tự động tính toán và đặt tỷ lệ thu phóng để canvas vừa vặn với chiều rộng container.\n *\n * @param containerWidth Chiều rộng container đo được (px)\n * @param stageWidth Chiều rộng chuẩn của canvas (mặc định 1668px)\n * @param padding Khoảng cách lề hai bên (mặc định 48px)\n * @param persistKey Khóa localStorage\n * @returns Tỷ lệ thu phóng vừa tính\n */\n fitToScreen(containerWidth: number, stageWidth?: number, padding = 48, persistKey?: string): number {\n const targetWidth = stageWidth ?? this.config?.stageWidth ?? 1668;\n const min = this.config?.zoomMin ?? 0.4;\n const max = 1.25;\n const ratio = Math.min(max, Math.max(min, Math.round(((containerWidth - padding) / targetWidth) * 100) / 100));\n this.setZoom(ratio, persistKey);\n return ratio;\n }\n\n /** Kiểm tra tính năng thu phóng có được cấu hình bật không */\n isZoomConfigured(): boolean {\n return Boolean(this.config?.enableZoom);\n }\n\n /**\n * Cổng DUY NHẤT cho canvas của thư viện. Nơi dùng KHÔNG gọi tới đây.\n *\n * Mọi thứ canvas cần đều là `private` để không lọt ra API công khai; gom vào một getter theo đúng\n * khuôn `FunctionsControl` của bộ quy ước, thay vì để rải rác hàm public mà người ngoài tưởng\n * mình phải gọi (người dùng chốt 28/08/2026).\n */\n get FunctionsControl() {\n return {\n maxContainerDepth: () => this.maxContainerDepth(),\n containerPadding: () => this.containerPadding(),\n isZoomEnabled: () => this.isZoomConfigured(),\n zoom: () => this.zoomLevel(),\n setZoom: (v: number, key?: string) => this.setZoom(v, key),\n zoomIn: (step?: number, key?: string) => this.zoomIn(step, key),\n zoomOut: (step?: number, key?: string) => this.zoomOut(step, key),\n resetZoom: (key?: string) => this.resetZoom(key),\n fitToScreen: (cW: number, sW?: number, pad?: number, key?: string) => this.fitToScreen(cW, sW, pad, key),\n gridsterOptions: (depth: number, cb?: () => void) => this.buildGridsterOptions(depth, cb),\n attachNode: (node: T_gridLayout_node, depth: number, host: ViewContainerRef, childCanvas?: TemplateRef<unknown>) =>\n this.attachNode(node, depth, host, childCanvas),\n detachNode: (nodeId: string) => this.detachNode(nodeId),\n getNodeElement: (nodeId: string, scope?: ParentNode) => this.getNodeElement(nodeId, scope),\n getNodeCanvasElement: (nodeId: string, scope?: ParentNode) => this.getNodeCanvasElement(nodeId, scope),\n };\n }\n\n /**\n * Trả về vỏ DOM của một khối theo `id`.\n *\n * 🔴 Nơi dùng cần chạm vào DOM của khối (đo kích thước, gắn lớp phủ riêng) BẮT BUỘC đi qua đây.\n * Trước khi có hàm này, nơi dùng phải tự viết `querySelector('.libs-ui-grid-layout-block-shell[...]')`\n * — tức bám vào tên class NỘI BỘ của thư viện: đổi tên class là màn bên kia vỡ IM LẶNG, biên dịch\n * vẫn xanh vì chuỗi selector không ai kiểm.\n *\n * `scope` giới hạn phạm vi tìm (mặc định cả tài liệu) — cần khi nhiều mặt phẳng cùng nằm trên màn.\n */\n getNodeElement(nodeId: string, scope?: ParentNode): HTMLElement | undefined {\n if (typeof document === 'undefined') {\n return undefined;\n }\n\n const root = scope ?? document;\n\n return (root.querySelector(`.libs-ui-grid-layout-block-shell[data-node-id=\"${nodeId}\"]`) as HTMLElement | null) ?? undefined;\n }\n\n /**\n * Trả về mặt phẳng LỒNG nằm trong một khối container (khối có con), nếu có.\n *\n * Tách riêng khỏi `getNodeElement` vì nơi dùng thường cần chèn phần tử của mình vào TRƯỚC mặt phẳng\n * lồng này (ví dụ hàng tiêu đề của khối ghép), nên phải cầm đúng nó chứ không phải cả vỏ.\n */\n getNodeCanvasElement(nodeId: string, scope?: ParentNode): HTMLElement | undefined {\n const shell = this.getNodeElement(nodeId, scope);\n\n if (!shell) {\n return undefined;\n }\n\n return (shell.querySelector(':scope > libs_ui-services-grid_layout-canvas') as HTMLElement | null) ?? undefined;\n }\n\n private applyInputs(\n ref: ComponentRef<unknown>,\n node: T_gridLayout_node,\n depth: number,\n childCanvas?: TemplateRef<unknown>\n ): void {\n ref.setInput('data', node.data);\n ref.setInput('node', node);\n ref.setInput('isEditMode', this.editMode());\n ref.setInput('depth', depth);\n // 🔴 CHỈ đặt khi có khuôn: `setInput` với một input component không khai là lỗi lúc chạy, mà\n // component nội dung của khối LÁ thì không cần biết đến mặt phẳng lồng.\n if (childCanvas) {\n ref.setInput('childCanvas', childCanvas);\n }\n }\n}\n","/**\n * Cầu nối cho phép một phần tử BÁO CÁO scroll của phần tử khác.\n *\n * 🔴 Vì sao tồn tại: `angular-gridster2` đổi vị trí chuột thành ô lưới bằng\n * `e.clientY + (el.scrollTop - el.offsetTop)` — công thức chỉ đúng khi CHÍNH `<gridster>` là phần tử\n * cuộn. Ở mặt phẳng có THU PHÓNG, việc cuộn nằm ở khung bọc còn `<gridster>` giữ đủ cỡ sân khấu bên\n * trong một tầng `transform: scale`, nên `el.scrollTop` luôn bằng 0: mọi px người dùng cuộn đều vô\n * hình với thư viện. Hệ quả đo được 15/09/2026: tự cuộn lúc kéo không chạy, và nếu nơi dùng tự cuộn\n * thì khối đứng im trong khi mặt phẳng trôi.\n *\n * 🔴 CHỈ vá `scrollTop`/`scrollLeft`. CẤM đụng `offsetWidth`/`offsetHeight`: `setGridSize()` của\n * gridster đọc hai cái đó để tính bề rộng cột, đè vào là vỡ lưới.\n */\n\n/**\n * Cắm cầu nối, trả về hàm gỡ.\n *\n * `zoom` là hàm chứ không phải số: mức phóng đổi bất cứ lúc nào, đọc lại mỗi lần truy cập mới đúng.\n * Chia cho mức phóng vì `offsetTop` là px BỐ CỤC còn scroll của khung bọc đã nhân thu phóng — không\n * quy đổi thì ở mức khác 100% khối trôi nhanh hơn hoặc chậm hơn con trỏ.\n */\nexport const bridgeScrollBetweenElements = (\n target: HTMLElement,\n source: HTMLElement,\n zoom: () => number\n): (() => void) => {\n const mucPhong = (): number => {\n const value = zoom();\n\n return Number.isFinite(value) && value > 0 ? value : 1;\n };\n\n Object.defineProperty(target, 'scrollTop', {\n configurable: true,\n get: () => source.scrollTop / mucPhong(),\n set: (val: number) => {\n source.scrollTop = val * mucPhong();\n },\n });\n Object.defineProperty(target, 'scrollLeft', {\n configurable: true,\n get: () => source.scrollLeft / mucPhong(),\n set: (val: number) => {\n source.scrollLeft = val * mucPhong();\n },\n });\n\n // Xoá thuộc tính RIÊNG vừa cắm là trả lại accessor gốc của `Element` — nhờ `configurable: true`.\n return () => {\n delete (target as unknown as Record<string, unknown>)['scrollTop'];\n delete (target as unknown as Record<string, unknown>)['scrollLeft'];\n };\n};\n\n/**\n * Bước cuộn cho một trục khi con trỏ đang ở sát mép vùng cuộn.\n *\n * Trả `0` khi con trỏ còn ở giữa. Mép DƯỚI/PHẢI được soát trước: con trỏ ra ngoài hẳn khung thì\n * `pos` vượt `max`, phải cuộn xuôi chứ không phải ngược.\n */\nexport const edgeScrollStep = (options: {\n pos: number;\n min: number;\n max: number;\n edge: number;\n step: number;\n}): number => {\n // 🔴 Mép kích hoạt KHÔNG được rộng quá 1/4 cạnh khung. Khung nhỏ (ruột khối ghép nhiều khi chỉ cao\n // vài chục px) thì hai vùng mép chạm nhau, đặt con trỏ ở đâu trong đó mặt phẳng cũng tự trôi — và\n // trôi cả hai chiều ngược nhau tuỳ thứ tự kiểm.\n const mep = Math.min(options.edge, (options.max - options.min) / 4);\n\n if (options.max - options.pos < mep) {\n return options.step;\n }\n if (options.pos - options.min < mep) {\n return -options.step;\n }\n\n return 0;\n};\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n OnDestroy,\n TemplateRef,\n ViewContainerRef,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { IScrollOverlayOptions, LibsUiComponentsScrollOverlayDirective } from '@libs-ui/components-scroll-overlay';\nimport { GridsterComponent, GridsterModule } from 'gridster18';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { emptyRootNode } from '../defines/gridster-config.define';\nimport { LibsUiGridLayoutService } from '../grid-layout.service';\nimport {\n T_gridLayout_actionEvent,\n T_gridLayout_addEvent,\n T_gridLayout_changeEvent,\n T_gridLayout_dropEvent,\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n T_gridLayout_toolbarContext,\n T_gridLayout_zoomPreset,\n} from '../interfaces/grid-layout.interface';\nimport { calculateDropGhost, parseDropPayload } from '../defines/collision.define';\nimport { bridgeScrollBetweenElements, edgeScrollStep } from '../defines/scroll-bridge.define';\n\n/**\n * Mặt phẳng kéo thả. Đệ quy: khối có `children` thì ruột nó lại là một mặt phẳng nữa.\n *\n * Nơi dùng KHÔNG dựng component này trực tiếp cho từng khối — chỉ đặt MỘT thẻ ở gốc và truyền\n * `nodeComponentType` qua `LibsUiGridLayoutService.init()`. Thư viện tự gắn component cho mọi khối.\n */\n@Component({\n selector: 'libs_ui-services-grid_layout-canvas',\n standalone: true,\n imports: [\n GridsterModule,\n LibsUiComponentsButtonsButtonComponent,\n LibsUiComponentsScrollOverlayDirective,\n NgTemplateOutlet,\n TranslateModule,\n ],\n templateUrl: './grid-layout-canvas.component.html',\n styleUrl: './grid-layout-canvas.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiGridLayoutCanvasComponent implements AfterViewInit, OnDestroy {\n /**\n * @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền khi vẽ ruột container.\n *\n * Nơi dùng KHÔNG truyền: mặt phẳng gốc đọc cây từ service (đã đưa vào qua `init()`), truyền thêm\n * ở đây là khai hai lần cùng một thứ (người dùng chốt 28/08/2026).\n */\n readonly node = input<T_gridLayout_node>();\n /** @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền. */\n readonly depth = input<number>(0);\n\n /**\n * Ẩn hẳn thanh công cụ mặc định (thêm-vào-trong · gộp/tách · xoá) của MỌI khối.\n *\n * Dùng khi sản phẩm gom các hành động đó vào chỗ khác — vd một nút ⋮ nằm trong chính nội dung\n * khối. Ẩn rồi thì `outRemoveNode` · `outAddBlockInside` · `outToggleType` không còn nguồn phát\n * từ thư viện; nơi dùng tự gọi `removeBlock` · `addBlock` · `toggleType` của service.\n */\n readonly hiddenToolbar = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /**\n * Template tự vẽ thanh công cụ, thay cho bộ nút mặc định.\n *\n * Nhận context `{ $implicit: node, isContainer, canAddInside, canToggleType }` để nơi dùng vẽ đúng\n * nút cho từng khối, rồi gọi ngược qua `outRemoveNode` · `outAddBlockInside` · `outToggleType`\n * bằng chính các hàm trong context. Truyền cả `hiddenToolbar` và `templateToolbar` thì\n * `hiddenToolbar` thắng — không vẽ gì.\n */\n readonly templateToolbar = input<TemplateRef<T_gridLayout_toolbarContext> | undefined>(undefined);\n\n /**\n * Bố cục vừa đổi do NGƯỜI DÙNG kéo hoặc đổi kích thước khối.\n *\n * Nơi dùng tự gọi `addBlock` · `removeBlock` · `compact` thì KHÔNG bắn — họ vừa gọi thì đã biết,\n * bắn ngược lại là thừa (người dùng chốt 28/08/2026).\n */\n readonly outChange = output<T_gridLayout_changeEvent>();\n /**\n * Người dùng bấm nút XOÁ trên một khối. Thư viện CHƯA xoá — gọi `event.confirm()` để xoá thật.\n * Cần hỏi trước thì hỏi xong mới gọi; không cho phép thì đừng gọi.\n */\n readonly outRemoveNode = output<T_gridLayout_actionEvent>();\n /**\n * Người dùng bấm nút THÊM trên một container. Thư viện KHÔNG tự thêm — nó không biết bạn có\n * những loại khối nào. Mở menu chọn loại rồi gọi `event.confirm(item)` với khối bạn muốn thêm.\n */\n readonly outAddBlockInside = output<T_gridLayout_addEvent>();\n /** Người dùng bấm nút GỘP/TÁCH. Thư viện chưa làm gì — gọi `event.confirm()` để thực hiện. */\n readonly outToggleType = output<T_gridLayout_actionEvent>();\n\n /** Bật tính năng thu phóng (zoom) canvas. Chỉ áp dụng cho canvas gốc (depth 0). */\n readonly enableZoom = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Tỷ lệ thu phóng hiện tại (hỗ trợ two-way binding [(zoom)]=\"myZoom\"). */\n readonly zoom = model<number | undefined>(undefined);\n\n /** Giới hạn thu phóng tối thiểu. Mặc định 0.4 (40%). */\n readonly zoomMin = input<number>(0.4);\n\n /** Giới hạn thu phóng tối đa. Mặc định 1.5 (150%). */\n readonly zoomMax = input<number>(1.5);\n\n /** Bước nhảy thu phóng mỗi lần bấm +/- hoặc lăn chuột. Mặc định 0.05 (5%). */\n readonly zoomStep = input<number>(0.05);\n\n /** Chiều rộng chuẩn của canvas stage tính bằng px. Mặc định 1668. */\n readonly stageWidth = input<number>(1668);\n\n /** Chiều cao tối thiểu của canvas stage tính bằng px. Mặc định 937. */\n readonly stageMinHeight = input<number>(937);\n\n /** Khóa lưu tỷ lệ thu phóng vào localStorage. Mặc định 'ocb_bi_canvas_zoom'. */\n readonly storageKey = input<string | undefined>('ocb_bi_canvas_zoom');\n\n /** Hiển thị thanh dock điều khiển thu phóng nổi ở góc dưới phải. Mặc định true. */\n readonly showZoomDock = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Tự động vừa màn hình khi tải trang lần đầu nếu khung nhìn nhỏ hơn stageWidth. Mặc định true. */\n readonly autoFitOnLoad = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Phát ra khi tỷ lệ thu phóng thay đổi. */\n readonly outZoomChange = output<number>();\n\n /** Bật tính năng kéo thả thẻ từ bên ngoài vào canvas (mặc định true) */\n readonly enableExternalDrop = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Luôn hiển thị đường kẻ lưới 24 cột */\n readonly showGridLines = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Mã id của khối đang được chọn */\n readonly selectedNodeId = model<string | null | undefined>(undefined);\n\n /** Phát ra khi thả một thẻ mới từ bên ngoài vào canvas */\n readonly outDropNode = output<T_gridLayout_dropEvent>();\n\n /** Phát ra khi người dùng click chọn một khối */\n readonly outSelectNode = output<T_gridLayout_node>();\n\n /** Phát ra khi người dùng bấm nút cấu hình trên thanh công cụ của khối */\n readonly outConfigNode = output<T_gridLayout_actionEvent>();\n\n private readonly gridsterRef = viewChild(GridsterComponent);\n private readonly scrollAreaRef = viewChild<ElementRef<HTMLElement>>('scrollArea');\n /**\n * Cầm BẤT CỨ ĐÂU trên khối để kéo, thay cho dải kéo ba chấm.\n *\n * 🔴 Mặc định `false` — giữ nguyên luật đã chốt 28/08/2026 cho mọi sản phẩm: *\"phải hover vào vùng\n * màu xanh thì mới kéo thả được cho đồng nhất\"*. Nơi dùng nào muốn kiểu \"cầm vào thẻ là kéo\" thì tự\n * bật, không đổi hành vi của màn khác.\n *\n * Bật lên thì dải kéo biến mất và gridster chuyển sang `ignoreContent: false` — cho kéo từ mọi chỗ\n * TRỪ phần tử mang `ignoreContentClass`. Nhờ vậy khối con nằm trong khối ghép vẫn không nhấc nhầm\n * khối ghép: vỏ khối con đã mang sẵn class chặn đó.\n */\n readonly dragFromAnywhere = input(false);\n /**\n * Nơi dùng đã đẩy vùng cuộn DỌC vào thẳng `<gridster>` (bằng CSS của chính nó).\n *\n * 🔴 Bật cờ này là trả `angular-gridster2` về đúng giả định gốc của nó — `dragMove` đọc\n * `gridster.el.scrollTop`, `scroll()` đo `gridsterElement.offsetHeight` — nên thư viện KHÔNG bắc\n * cầu `scrollTop` sang khung bọc nữa, và vòng tự cuộn khi kéo cũng cuộn thẳng vào gridster.\n *\n * 🔴 PHẢI là input, KHÔNG dò bằng `getComputedStyle`: thanh cuộn nổi của libs-ui mới là thứ đặt\n * `overflow` lên phần tử, mà nó chạy SAU `ngAfterViewInit` — dò lúc đó luôn ra \"không cuộn\" và cầu\n * nối vẫn cắm vào, nuốt sạch đoạn cuộn thật (đo 15/09/2026: `g.scrollTop = 300` xong đọc lại vẫn 0).\n */\n readonly gridsterOwnsScroll = input(false);\n /**\n * Vẽ thanh cuộn nổi của libs-ui cho mặt phẳng LỒNG (ruột khối ghép).\n *\n * 🔴 Vùng cuộn của mặt phẳng lồng phải giấu thanh cuộn mặc định của trình duyệt — nó dày, xám, và\n * ăn mất bề rộng của lưới con nên 24 cột hẹp lại mỗi khi nội dung vừa đủ tràn. Hệ quả là người\n * dùng cuộn được nhưng KHÔNG THẤY có gì để cuộn: thẻ con nằm dưới đáy trông như biến mất (người\n * dùng chỉ ra 16/09/2026). Bật cờ này để thư viện gắn thanh cuộn nổi — nhìn thấy được mà không\n * chiếm chỗ.\n */\n readonly nestedScrollbar = input(false);\n private readonly zoomDockRef = viewChild<ElementRef<HTMLElement>>('zoomDock');\n /** Gỡ cầu nối scroll đã cắm lên phần tử `<gridster>` — xem `bridgeScrollToGridster`. */\n private removeScrollBridge: (() => void) | undefined;\n /** Gỡ vòng tự cuộn khi kéo — xem `startDragAutoScroll`. */\n private stopDragAutoScroll: (() => void) | undefined;\n\n /** Khoảng cách tới mép vùng cuộn (px) bắt đầu tự cuộn, và bước cuộn mỗi khung hình. */\n private readonly dragScrollEdge = 36;\n private readonly dragScrollStep = 8;\n /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */\n private readonly itemHosts = viewChildren('itemHost', { read: ViewContainerRef });\n /**\n * Khuôn mặt phẳng LỒNG của từng khối container, để đưa vào component vỏ khi khối đó tự khai\n * `getComponentOutlet`.\n *\n * 🔴 Danh sách này KHÔNG cùng thứ tự với `children()`: `ng-template #childCanvasTpl` chỉ tồn tại\n * cho khối CÓ CON. Ghép theo index là gán nhầm khuôn của khối này cho khối khác — phải lọc lại\n * đúng cùng điều kiện mà template dùng (xem `childCanvasTemplateOf`).\n */\n private readonly childCanvasTemplates = viewChildren<TemplateRef<unknown>>('childCanvasTpl');\n\n /** Khung xem trước vị trí thả thẻ từ bên ngoài (snapped ghost preview) */\n protected readonly dropGhost = signal<T_gridLayout_dropGhost | undefined>(undefined);\n\n private activeHoveredEl?: HTMLElement;\n private rootGridsterEl?: HTMLElement;\n\n /** Menu chọn preset thu phóng đang mở hay đóng */\n protected readonly isMenuOpen = signal<boolean>(false);\n\n /** Các mốc thu phóng định sẵn */\n protected readonly zoomPresets: Array<T_gridLayout_zoomPreset> = [\n { label: 'i18n_zoom_preset_overview', value: 0.5 },\n { label: 'i18n_zoom_preset_small_laptop', value: 0.67 },\n { label: 'i18n_zoom_preset_laptop_1080p', value: 0.75 },\n { label: 'i18n_zoom_preset_screen_1080p', value: 0.85 },\n { label: 'i18n_zoom_preset_standard', value: 0.9 },\n { label: 'i18n_zoom_preset_original_size', value: 1 },\n { label: 'i18n_zoom_preset_large_screen', value: 1.1 },\n { label: 'i18n_zoom_preset_high_dpi_2k', value: 1.25 },\n ];\n\n /** Sáu chấm của tay cầm kéo — chỉ để `@for` dựng đủ 6 thẻ, giá trị không dùng tới. */\n protected readonly dragBarDots = [0, 1, 2, 3, 4, 5];\n\n private readonly service = inject(LibsUiGridLayoutService);\n\n /** Chế độ thu phóng có đang hoạt động trên canvas này không (chỉ root canvas depth 0) */\n protected readonly isZoomActive = computed(() => {\n return this.depth() === 0 && (this.enableZoom() || this.service.FunctionsControl.isZoomEnabled());\n });\n\n protected readonly currentZoom = computed(() => this.service.Zoom());\n protected readonly zoomPercent = computed(() => Math.round(this.currentZoom() * 100));\n\n /**\n * Node THẬT của mặt phẳng này.\n *\n * 🔴 Mặt phẳng GỐC (depth 0) đọc cây từ SERVICE, không dùng input.\n * Nơi dùng thường sửa cây TẠI CHỖ (`treeService.compact(tree)`) rồi gọi `refresh()`, nên signal\n * `root()` của họ giữ nguyên tham chiếu và input `node` không hề đổi — `@for` không dựng lại\n * `gridster-item`, lưới đứng im dù dữ liệu đã khác (đo 28/08/2026: bấm \"Sắp gọn\" không tác dụng).\n * `refresh()` của service thay tham chiếu cây, nên đọc từ đó mới thấy thay đổi.\n *\n * Mặt phẳng LỒNG vẫn dùng input: nó nhận node con từ mặt phẳng cha, vốn đã là object mới.\n */\n protected readonly currentNode = computed(() => {\n this.service.Version();\n\n if (this.depth() > 0) {\n return this.node() ?? emptyRootNode();\n }\n\n return this.service.Root() ?? emptyRootNode();\n });\n\n protected readonly children = computed(() => this.currentNode().children ?? []);\n\n /**\n * Bối cảnh cho `templateToolbar`, dựng sẵn theo từng khối.\n *\n * Dựng ở `computed` chứ không gọi hàm trên template: gọi hàm trong template chạy lại mỗi vòng\n * dò thay đổi (rule `fe-coding-convention-templates` mục 6).\n */\n protected readonly toolbarContexts = computed<Array<T_gridLayout_toolbarContext>>(() =>\n this.children().map((item) => ({\n $implicit: item,\n isContainer: this.isContainer(item),\n canAddInside: this.canAddInside(item),\n canToggleType: this.canToggleType(item),\n remove: () => this.outRemoveNode.emit({ nodeId: item.id, node: item, confirm: () => this.service.removeBlock(item.id) }),\n addInside: () => this.emitAddInside(item),\n toggleType: () => this.emitToggleType(item),\n }))\n );\n\n protected readonly isNestedCanvas = computed(() => this.depth() > 0);\n /** Chỉ mặt phẳng LỒNG mới vẽ thanh cuộn nổi — mặt phẳng gốc do nơi dùng tự lo. */\n protected readonly showNestedScrollbar = computed(() => this.isNestedCanvas() && this.nestedScrollbar());\n /**\n * Chỉ cuộn DỌC: bề rộng khối con luôn bị gridster kẹp trong số cột của lưới nên không có gì để\n * cuộn ngang.\n */\n protected readonly nestedScrollOverlayOptions: IScrollOverlayOptions = { scrollX: 'hidden', scrollY: 'scroll' };\n\n /**\n * Khe nhìn thấy giữa các khối CẤP GỐC. Mặt phẳng lồng trả 0 — khối con là các dòng của cùng một\n * thẻ, tách chúng ra làm chúng trông như thẻ rời.\n */\n protected readonly visualGap = computed(() => (this.depth() === 0 ? this.service.visualGapPx : 0));\n\n /** trần lồng container — khối đã chạm trần thì không cho chuyển thành container */\n protected readonly maxContainerDepth = computed(() => this.service.FunctionsControl.maxContainerDepth());\n\n /**\n * Lề trong của container, px.\n *\n * 🔴 Đặt trên VỎ container, không đặt vào lưới con. Lưới con giữ nguyên `margin: 2` như cũ; lề\n * này chỉ co ruột lại khỏi biên vỏ, nhờ đó tay cầm đổi kích thước của khối con luôn nằm trong tầm\n * chuột (người dùng chốt 28/08/2026).\n */\n protected readonly containerPadding = computed(() => `${this.service.FunctionsControl.containerPadding()}px`);\n\n /** Dải kéo chỉ hiện ở chế độ sửa — chế độ xem không kéo được nên hiện dải là gây nhầm. */\n protected readonly isEditMode = computed(() => this.service.IsEditMode());\n\n protected readonly gridOptions = computed(() => {\n // Đọc `Version` để `init()` lại (đổi chế độ, bật/tắt chồng khối) sinh ra options MỚI —\n // gridster chỉ áp dụng cấu hình khi tham chiếu `options` đổi.\n this.service.Version();\n\n const options = this.service.FunctionsControl.gridsterOptions(this.depth(), () =>\n this.outChange.emit({ root: this.currentNode() })\n );\n\n if (!this.dragFromAnywhere()) {\n return options;\n }\n\n // 🔴 `delayStart` PHẢI khác 0 ở chế độ này. Với tay cầm chuyên dụng thì `0` là đúng (bấm vào dải\n // chỉ có thể là ý định kéo), nhưng khi cả thẻ là tay cầm thì `0` nuốt luôn mọi cú bấm vào nút và\n // liên kết bên trong thẻ. 150ms: bấm nhanh vẫn ăn, giữ lại một nhịp mới là kéo.\n return {\n ...options,\n draggable: { ...options.draggable, ignoreContent: false, delayStart: 150 },\n };\n });\n\n constructor() {\n // Gắn component của nơi dùng vào từng ô, và gắn LẠI mỗi khi cây đổi.\n // Dùng effect vì `itemHosts()` chỉ có giá trị sau khi Angular dựng xong @for.\n effect(() => {\n const hosts = this.itemHosts();\n const items = this.children();\n const canvasTemplates = this.childCanvasTemplates();\n\n items.forEach((item, i) => {\n const host = hosts[i];\n\n if (!host) {\n return;\n }\n\n // Khối có con là CONTAINER: RUỘT nó do mặt phẳng lồng vẽ.\n //\n // 🔴 Nhưng container VẪN được gắn component nếu nơi dùng chủ động khai `getComponentOutlet`\n // cho chính khối đó — đó là VỎ của khối ghép: hàng tiêu đề, nút thu gọn, nền. Vỏ KHÔNG thay\n // thế mặt phẳng lồng; nó NHẬN mặt phẳng đó vào trong qua input `childCanvas` và tự đặt vào\n // đúng chỗ giữa tiêu đề và phần thân của mình.\n //\n // Container KHÔNG khai outlet riêng thì vẫn bỏ qua y như cũ — `config.getComponentOutlet`\n // dùng chung là để vẽ NỘI DUNG khối lá, đem áp cho container sẽ đè mất mặt phẳng lồng.\n const isContainerNode = (item.children?.length ?? 0) > 0;\n\n if (isContainerNode && !item.getComponentOutlet) {\n return;\n }\n\n this.service.FunctionsControl.attachNode(\n item,\n this.depth() + 1,\n host,\n isContainerNode ? this.childCanvasTemplateOf(item, canvasTemplates) : undefined\n );\n });\n });\n\n // Đồng bộ nếu model zoom bên ngoài thay đổi\n effect(() => {\n const z = this.zoom();\n if (z !== undefined && Math.abs(z - this.service.Zoom()) > 0.001) {\n this.service.FunctionsControl.setZoom(z, this.storageKey());\n }\n });\n }\n\n ngAfterViewInit(): void {\n this.bridgeScrollToGridster();\n if (!this.isZoomActive() || !this.autoFitOnLoad()) {\n return;\n }\n\n const key = this.storageKey();\n let hasSaved = false;\n if (key && typeof localStorage !== 'undefined') {\n try {\n hasSaved = Boolean(localStorage.getItem(key));\n } catch {\n // ignore localStorage access error\n }\n }\n\n if (!hasSaved) {\n setTimeout(() => {\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n if (scrollEl && scrollEl.clientWidth > 0 && scrollEl.clientWidth < this.stageWidth() + 64) {\n this.handlerFitScreen();\n }\n }, 50);\n }\n }\n\n ngOnDestroy(): void {\n this.removeScrollBridge?.();\n this.stopDragAutoScroll?.();\n this.cleanupDragGrid();\n for (const item of this.children()) {\n this.service.FunctionsControl.detachNode(item.id);\n }\n }\n\n /** Vẽ lại lưới — gọi khi khung ngoài đổi kích thước hoặc cây vừa đổi diện rộng. */\n get FunctionControl() {\n return {\n veLaiLuoi: () => this.gridsterRef()?.optionsChanged(),\n zoomIn: () => this.handlerZoomIn(),\n zoomOut: () => this.handlerZoomOut(),\n resetZoom: () => this.handlerResetZoom(),\n fitToScreen: () => this.handlerFitScreen(),\n setZoom: (val: number) => {\n this.service.FunctionsControl.setZoom(val, this.storageKey());\n this.syncZoomOut();\n },\n // Vùng cuộn của mặt phẳng — nơi dùng cần nó để tự cuộn tới một khối, hoặc đo toạ độ khi kéo.\n // Không mở ở đây thì nơi dùng phải dò bằng tên lớp CSS nội bộ, và tên đó đổi lúc nào không hay.\n scrollArea: (): HTMLElement | undefined => this.scrollAreaRef()?.nativeElement,\n };\n }\n\n /**\n * Bắc CẦU NỐI để `<gridster>` báo cáo scroll của KHUNG CUỘN, thay vì scroll của chính nó.\n *\n * 🔴 Vì sao cần: gridster đổi vị trí chuột thành ô lưới bằng\n * `e.clientY + (el.scrollTop - el.offsetTop)` (xem `calculateItemPositionWithoutScale` và\n * `this.offsetTop = this.gridster.el.scrollTop - this.gridster.el.offsetTop` trong\n * `angular-gridster2@18`). Công thức chỉ đúng khi CHÍNH `<gridster>` là phần tử cuộn — đúng như\n * comment đã ghi ở template cho `offsetParent`. Ở nhánh THU PHÓNG, việc cuộn nằm ở `#scrollArea`\n * còn `<gridster>` giữ đủ cỡ sân khấu bên trong một tầng `transform: scale`, nên\n * `el.scrollTop` luôn bằng 0: mọi px người dùng cuộn đều vô hình với thư viện. Hệ quả đo được\n * 15/09/2026 trên mặt phẳng cấp trang: tự cuộn lúc kéo không chạy, và nếu nơi dùng tự cuộn thì thẻ\n * đứng im trong khi mặt phẳng trôi.\n *\n * 🔴 CHỈ vá `scrollTop`/`scrollLeft`. CẤM đụng `offsetWidth`/`offsetHeight`: `setGridSize()` của\n * gridster đọc hai cái đó để tính `curColWidth`, đè vào là vỡ bề rộng cột của mọi lưới.\n *\n * 🔴 Chia cho mức phóng: `offsetTop` là px BỐ CỤC, còn `scrollTop` của khung cuộn là px đã nhân\n * thu phóng. Không quy đổi thì ở mức phóng khác 100% khối trôi nhanh hơn hoặc chậm hơn con trỏ.\n */\n /** Phần tử thật sự cuộn theo chiều dọc — `<gridster>` nếu nơi dùng đã đẩy cuộn vào trong nó. */\n private vungCuonDoc(): HTMLElement | undefined {\n const gridsterEl = this.gridsterRef()?.el as HTMLElement | undefined;\n\n if (this.gridsterOwnsScroll() && gridsterEl) {\n return gridsterEl;\n }\n\n return this.scrollAreaRef()?.nativeElement;\n }\n\n private bridgeScrollToGridster(): void {\n // `GridsterComponent.el` là HTMLElement thẳng, không phải `ElementRef` (xem `gridster.component.d.ts`).\n const gridsterEl = this.gridsterRef()?.el;\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n\n if (!this.isZoomActive() || !gridsterEl || !scrollEl || this.removeScrollBridge) {\n return;\n }\n\n // 🔴 `<gridster>` đã tự cuộn thì CẤM bắc cầu: cầu nối ghi đè `scrollTop`/`scrollLeft` của phần tử\n // bằng số của khung bọc, nên chính đoạn cuộn thật của gridster bị nuốt — đặt `scrollTop` không\n // ăn, kéo khối là nó nhảy về đầu lưới.\n if (this.gridsterOwnsScroll()) {\n return;\n }\n this.removeScrollBridge = bridgeScrollBetweenElements(gridsterEl, scrollEl, () => this.service.Zoom());\n }\n\n /**\n * Tự cuộn mặt phẳng khi người dùng kéo khối tới sát mép.\n *\n * 🔴 Tự cuộn sẵn có của gridster (`scrollSensitivity`) không dùng được ở nhánh thu phóng: hàm\n * `scroll()` của nó đo bằng `gridsterElement.offsetHeight`, mà `<gridster>` cao bằng CẢ sân khấu\n * nên con trỏ không bao giờ \"tới sát mép\" theo con mắt của nó.\n *\n * 🔴 Chỉ cuộn khi thư viện ĐANG kéo thật (`.gridster-item-moving`) — không có chốt này thì một cú\n * bấm bình thường gần mép cũng làm mặt phẳng trôi.\n */\n protected handlerScrollAreaPointerDown(): void {\n this.startDragAutoScroll();\n }\n\n private startDragAutoScroll(): void {\n this.stopDragAutoScroll?.();\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n const cuonDoc = this.vungCuonDoc();\n\n if (!scrollEl) {\n return;\n }\n let viTri: { x: number; y: number } | undefined;\n let khung: number | undefined;\n const chay = (): void => {\n if (viTri && scrollEl.querySelector('.gridster-item-moving')) {\n const hop = scrollEl.getBoundingClientRect();\n const buoc = { edge: this.dragScrollEdge, step: this.dragScrollStep };\n // `edgeScrollStep` tự kẹp mép theo cạnh khung, nên khung nhỏ như ruột khối ghép vẫn đúng.\n const doc = edgeScrollStep({ ...buoc, pos: viTri.y, min: hop.top, max: hop.bottom });\n const ngang = edgeScrollStep({ ...buoc, pos: viTri.x, min: hop.left, max: hop.right });\n\n if (doc !== 0 || ngang !== 0) {\n // Hai chiều có thể nằm ở HAI phần tử khác nhau: nơi dùng được phép đẩy cuộn dọc vào trong\n // `<gridster>` mà vẫn để cuộn ngang ở khung bọc (sân khấu rộng hơn khung khi phóng to).\n (cuonDoc ?? scrollEl).scrollTop += doc;\n scrollEl.scrollLeft += ngang;\n // 🔴 Cuộn xong PHẢI bắn lại một nhịp `mousemove` ở đúng chỗ con trỏ đang đứng. gridster chỉ\n // tính lại vị trí khối trong `dragMove`, tức chỉ khi có sự kiện chuột — cuộn bằng mã mà\n // không bắn thì giữa hai lần người dùng rê chuột, mặt phẳng trôi còn khối đứng im rồi giật\n // về chỗ đúng ở nhịp sau (người dùng chỉ ra 15/09/2026: \"kéo xuống dưới bị giật giật\").\n // Bắn `mousemove` chứ không phải `pointermove`: draggable của gridster chỉ nghe `mousemove`\n // và `touchmove`, nên cũng không dội ngược vào chính listener bên dưới.\n document.dispatchEvent(\n new MouseEvent('mousemove', { clientX: viTri.x, clientY: viTri.y, bubbles: true, cancelable: true, view: window })\n );\n }\n }\n khung = requestAnimationFrame(chay);\n };\n const theoChuot = (event: PointerEvent): void => {\n viTri = { x: event.clientX, y: event.clientY };\n };\n\n this.stopDragAutoScroll = () => {\n document.removeEventListener('pointermove', theoChuot);\n document.removeEventListener('pointerup', dung);\n if (khung !== undefined) {\n cancelAnimationFrame(khung);\n khung = undefined;\n }\n this.stopDragAutoScroll = undefined;\n };\n\n const dung = (): void => this.stopDragAutoScroll?.();\n\n document.addEventListener('pointermove', theoChuot);\n document.addEventListener('pointerup', dung);\n chay();\n }\n\n protected handlerZoomIn(): void {\n this.service.FunctionsControl.zoomIn(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerZoomOut(): void {\n this.service.FunctionsControl.zoomOut(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerResetZoom(): void {\n this.service.FunctionsControl.resetZoom(this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerFitScreen(): void {\n this.isMenuOpen.set(false);\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n const containerWidth = scrollEl?.clientWidth || (typeof window !== 'undefined' ? window.innerWidth - 300 : 1200);\n this.service.FunctionsControl.fitToScreen(containerWidth, this.stageWidth(), 48, this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerToggleMenu(): void {\n this.isMenuOpen.update((open) => !open);\n }\n\n protected handlerSelectPreset(value: number): void {\n this.isMenuOpen.set(false);\n this.service.FunctionsControl.setZoom(value, this.storageKey());\n this.syncZoomOut();\n }\n\n protected isCurrentPreset(value: number): boolean {\n return Math.abs(this.currentZoom() - value) < 0.01;\n }\n\n private syncZoomOut(): void {\n const val = this.service.Zoom();\n this.outZoomChange.emit(val);\n if (this.zoom() !== val) {\n this.zoom.set(val);\n }\n }\n\n protected handlerWheel(event: WheelEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n if (event.deltaY < 0) {\n this.handlerZoomIn();\n } else if (event.deltaY > 0) {\n this.handlerZoomOut();\n }\n }\n }\n\n @HostListener('document:keydown', ['$event'])\n protected handlerDocumentKeyDown(event: KeyboardEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n if (event.key === '=' || event.key === '+') {\n event.preventDefault();\n this.handlerZoomIn();\n } else if (event.key === '-' || event.key === '_') {\n event.preventDefault();\n this.handlerZoomOut();\n } else if (event.key === '0') {\n event.preventDefault();\n this.handlerResetZoom();\n }\n }\n }\n\n @HostListener('document:click', ['$event'])\n protected handlerDocumentClick(event: MouseEvent): void {\n if (!this.isMenuOpen()) {\n return;\n }\n\n const dockEl = this.zoomDockRef()?.nativeElement;\n if (dockEl && !dockEl.contains(event.target as Node)) {\n this.isMenuOpen.set(false);\n }\n }\n\n protected handlerTrackNode(_index: number, item: T_gridLayout_node): string {\n return item.id;\n }\n\n /**\n * 🔴 Chặn `mousedown` nổi lên lưới CHA khi thao tác trong lưới con.\n * Không chặn thì cả hai lưới cùng nhận một cú bấm: kéo khối con là nhấc luôn container.\n */\n /**\n * Chặn `mousedown` của khối trong lưới LỒNG nổi lên lưới cha.\n *\n * Chỉ chặn ở lưới lồng: lưới cấp trang không có cha nào để chặn, và chặn ở đó sẽ nuốt luôn thao\n * tác của chính nó.\n */\n /**\n * 🔴 Ba handler dưới đây PHẢI `stopPropagation`.\n * Nút nằm trong vùng mang `dragHandleClass`, không chặn thì cú bấm bị gridster hiểu là bắt đầu kéo\n * và `delayStart: 160` nuốt luôn `click` — người dùng thấy như nút chết.\n */\n protected handlerRemove(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outRemoveNode.emit({ nodeId: node.id, node, confirm: () => this.service.removeBlock(node.id) });\n }\n\n protected handlerAddInside(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitAddInside(node);\n }\n\n protected handlerToggleType(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitToggleType(node);\n }\n\n /**\n * Chặn cú bấm trong thanh công cụ nổi lên gridster.\n *\n * Chỉ `stopPropagation`, KHÔNG `preventDefault`: nút bên trong template của nơi dùng vẫn cần\n * hành vi mặc định của mình (mở dropdown, focus…).\n */\n protected handlerStopEvent(event: Event): void {\n event.stopPropagation();\n }\n\n /** Phát `outAddBlockInside` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitAddInside(node: T_gridLayout_node): void {\n this.outAddBlockInside.emit({\n nodeId: node.id,\n node,\n confirm: (item: T_gridLayout_newNode) => this.service.addBlock(item, node.id),\n });\n }\n\n /** Phát `outToggleType` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitToggleType(node: T_gridLayout_node): void {\n this.outToggleType.emit({\n nodeId: node.id,\n node,\n // Gộp hay tách suy ra từ chính khối: đang là container thì tách, không thì gộp.\n confirm: () => (this.isContainer(node) ? this.service.toSingle(node.id) : this.service.toContainer(node.id)),\n });\n }\n\n /** khối này có phải container không (có khối con) */\n protected isContainer(item: T_gridLayout_node): boolean {\n return (item.children?.length ?? 0) > 0;\n }\n\n /**\n * Lấy đúng khuôn mặt phẳng lồng của MỘT khối.\n *\n * 🔴 `viewChildren('childCanvasTpl')` chỉ chứa khuôn của khối CÓ CON, còn `children()` chứa mọi\n * khối — hai danh sách lệch nhau. Phải lọc `children()` theo cùng điều kiện mà template dùng rồi\n * mới tra theo vị trí trong danh sách đã lọc; ghép thẳng theo index của `children()` là gán khuôn\n * của khối này cho khối khác, và thẻ con hiện sai chỗ.\n */\n private childCanvasTemplateOf(\n item: T_gridLayout_node,\n templates: readonly TemplateRef<unknown>[]\n ): TemplateRef<unknown> | undefined {\n const index = this.children()\n .filter((node) => (node.children?.length ?? 0) > 0)\n .findIndex((node) => node.id === item.id);\n\n return index >= 0 ? templates[index] : undefined;\n }\n\n /** container đã chạm trần lồng thì không cho thêm khối vào trong nữa */\n protected canAddInside(item: T_gridLayout_node): boolean {\n return this.isContainer(item) && this.depth() < this.maxContainerDepth();\n }\n\n /** khối đơn ở cấp chưa chạm trần mới được chuyển thành container */\n protected canToggleType(item: T_gridLayout_node): boolean {\n if (this.isContainer(item)) {\n return true;\n }\n\n return this.depth() < this.maxContainerDepth();\n }\n\n protected handlerBlockParentDrag(event: Event): void {\n if (!this.isNestedCanvas()) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerMouseDownTrongLuoi(event: Event): void {\n if (this.depth() === 0) {\n return;\n }\n\n // 🔴 `dragFromAnywhere` bật thì KHÔNG chặn — CẤM bỏ nhánh này.\n // Khối ghép không còn dải kéo riêng, nên chỗ DUY NHẤT còn lại để cầm nó là NỀN TRỐNG của mặt\n // phẳng lồng bên trong. Chặn ở đây là bịt nốt đường đó: người dùng bấm vào đâu trong khối ghép\n // cũng không kéo nó đi được (người dùng chỉ ra 15/09/2026).\n // Khối CON vẫn an toàn: `gridster-item` của chúng tự chặn (xem `handlerBlockParentDrag`), nên\n // chỉ sự kiện rơi vào nền trống mới nổi lên tới khối ghép.\n if (this.dragFromAnywhere()) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerSelectNode(node: T_gridLayout_node, event?: MouseEvent): void {\n if (event) {\n // 🔴 CHỈ bỏ qua khi đích thực sự là nút bấm. Trước đây bỏ qua cả vùng\n // `.libs-ui-grid-layout-toolbar`: thanh này phủ gần kín khối nhỏ nên bấm vào khối không bao giờ\n // chọn được, nơi dùng phải tắt `pointer-events` của cả thanh để cứu.\n const target = event.target as HTMLElement;\n if (target.closest('button') || target.closest('[data-grid-layout-action]')) {\n return;\n }\n }\n this.selectedNodeId.set(node.id);\n this.outSelectNode.emit(node);\n }\n\n protected handlerConfig(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n const actionEvent: T_gridLayout_actionEvent = {\n nodeId: node.id,\n node,\n confirm: () => true,\n };\n this.outConfigNode.emit(actionEvent);\n }\n\n protected handlerDragOver(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n const container = this.scrollAreaRef()?.nativeElement;\n const root = this.service.Root();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n if (!container || !root || !payload) {\n return;\n }\n\n const rootGridster = container.querySelector('gridster') as HTMLElement | null;\n if (rootGridster) {\n if (!rootGridster.classList.contains('display-grid')) {\n rootGridster.classList.add('display-grid');\n }\n this.rootGridsterEl = rootGridster;\n }\n\n const ghost = calculateDropGhost(event, container, root, payload, this.service.totalColumns, this.service.rowStepPx);\n\n if (ghost?.isInsideGroup && ghost.hoveredGridster) {\n if (this.activeHoveredEl !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add('display-grid');\n this.activeHoveredEl = ghost.hoveredGridster;\n }\n } else {\n this.cleanupHoveredGroup();\n }\n\n this.dropGhost.set(ghost);\n }\n\n protected handlerDragLeave(event: DragEvent): void {\n if (this.depth() > 0) {\n return;\n }\n if (event.relatedTarget) {\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && container.contains(event.relatedTarget as Node)) {\n return;\n }\n }\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n }\n\n protected handlerDrop(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n const ghost = this.dropGhost();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n this.service.clearDragPayload();\n\n if (!ghost || !payload) {\n return;\n }\n\n const targetParentId = ghost.isInsideGroup ? ghost.targetParentId : undefined;\n const isInside = Boolean(targetParentId);\n\n let itemToAdd: T_gridLayout_newNode;\n const payloadAny = payload as Record<string, unknown>;\n if (typeof payloadAny['resolveNode'] === 'function') {\n const resolved = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(isInside);\n itemToAdd = resolved ?? {\n cols: ghost.cols,\n rows: ghost.rows,\n data: payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined),\n };\n } else {\n const newNodeData = payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined);\n itemToAdd = {\n cols: ghost.cols,\n rows: ghost.rows,\n data: newNodeData,\n };\n }\n\n const addedNode = this.service.insertBlockWithCollision(\n itemToAdd,\n ghost.col,\n ghost.row,\n targetParentId,\n );\n\n if (addedNode) {\n this.selectedNodeId.set(addedNode.id);\n this.outDropNode.emit({\n node: addedNode,\n parentId: targetParentId,\n col: ghost.col,\n row: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n rawEvent: event,\n payload,\n });\n const root = this.service.Root();\n if (root) {\n this.outChange.emit({\n root,\n nodeId: addedNode.id,\n });\n }\n }\n }\n\n private cleanupHoveredGroup(): void {\n if (this.activeHoveredEl) {\n this.activeHoveredEl.classList.remove('display-grid');\n this.activeHoveredEl = undefined;\n }\n }\n\n private cleanupDragGrid(): void {\n this.cleanupHoveredGroup();\n if (this.rootGridsterEl && !this.showGridLines()) {\n this.rootGridsterEl.classList.remove('display-grid');\n this.rootGridsterEl = undefined;\n }\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && !this.showGridLines()) {\n container.querySelectorAll('gridster.display-grid').forEach((el) => {\n el.classList.remove('display-grid');\n });\n }\n }\n}\n","@if (isZoomActive()) {\n <!-- Khu vực cuộn chứa canvas stage thu phóng -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0 overflow-auto p-6 flex justify-start items-start\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (pointerdown)=\"handlerScrollAreaPointerDown()\"\n (wheel)=\"handlerWheel($event)\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <div\n #canvasStage\n id=\"bi-canvas-stage\"\n class=\"libs-ui-grid-layout-stage relative flex flex-col transition-[zoom] duration-150 origin-top shrink-0 mx-auto bg-white/80 border border-slate-200/80 rounded-2xl shadow-sm p-4\"\n [style.zoom]=\"currentZoom()\"\n [style.width.px]=\"stageWidth()\"\n [style.min-width.px]=\"stageWidth()\"\n [style.min-height.px]=\"stageMinHeight()\"\n [style.--libs-ui-grid-layout-visual-gap.px]=\"visualGap()\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster\n class=\"h-full w-full\"\n [class.display-grid]=\"showGridLines()\"\n [class.libs-ui-grid-layout-drag-anywhere]=\"dragFromAnywhere()\"\n [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <!-- 🔴 `dragFromAnywhere` bật thì BỎ class chặn — CẤM gắn lại vô điều kiện.\n `libs-ui-grid-layout-block-parent-drag` CHÍNH LÀ `ignoreContentClass` của gridster (xem\n `gridster-config.define`). Với `ignoreContent: true` nó chỉ mang nghĩa \"không phải tay\n cầm\"; nhưng với `ignoreContent: false` (chế độ cầm-cả-thẻ) gridster hiểu là \"vùng CẤM\n kéo\": duyệt từ chỗ bấm lên gặp class này là dừng hẳn, nên KHỐI CON trong khối ghép bấm\n vào đâu cũng không nhúc nhích (người dùng chỉ ra 15/09/2026; đo được kéo 150px mà khối\n lệch 0px). Chặn lưới cha ở chế độ này do `handlerBlockParentDrag` trên chính\n `gridster-item` lo, không cần class này. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [attr.data-node-id]=\"item.id\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas() && !dragFromAnywhere()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n <!-- 🔴 `dragFromAnywhere` bật thì KHÔNG vẽ dải: cả thẻ đã là tay cầm, để lại dải chỉ thừa. -->\n @if (isEditMode() && !dragFromAnywhere()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <!-- 🔴 Container CÓ `getComponentOutlet`: khung này là VỎ, và canvas con được đưa VÀO TRONG\n component vỏ qua input `childCanvas` (một `TemplateRef`) — xem `ng-template #childCanvasTpl`\n bên dưới. Vỏ tự quyết đặt canvas ở đâu giữa tiêu đề và phần thân của nó.\n Trước đây canvas con là ANH EM của khung này, nên vỏ chiếm trọn chiều cao rồi đẩy toàn bộ\n thẻ con ra ngoài vùng nhìn thấy (đo 14/09/2026: mọi khối ghép chỉ còn nhãn và ruột trắng). -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item) && !item.getComponentOutlet\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px.\n\n 🔴 Khuôn đặt trong `ng-template` để đi được HAI đường:\n - Container KHÔNG có vỏ riêng → vẽ thẳng tại đây, y như trước.\n - Container CÓ `getComponentOutlet` → thư viện truyền khuôn này xuống component vỏ qua\n input `childCanvas`, vỏ tự đặt nó vào giữa tiêu đề và phần thân của mình. Vẽ thêm ở\n đây nữa là hai mặt phẳng lồng chồng nhau. -->\n <ng-template #childCanvasTpl>\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [dragFromAnywhere]=\"dragFromAnywhere()\"\n [nestedScrollbar]=\"nestedScrollbar()\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n </ng-template>\n\n @if (!item.getComponentOutlet) {\n <ng-container [ngTemplateOutlet]=\"childCanvasTpl\" />\n }\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n </div>\n\n <!-- Thanh dock điều khiển thu phóng nổi ở góc dưới trái -->\n @if (showZoomDock()) {\n <div\n #zoomDock\n id=\"canvas-zoom-dock\"\n role=\"toolbar\"\n tabindex=\"0\"\n class=\"absolute bottom-4 left-6 z-30 flex items-center bg-white rounded-full shadow-2xl border-2 border-slate-400 p-1 space-x-1 select-none\"\n (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\">\n <!-- Thu nhỏ (-) -->\n <button\n type=\"button\"\n class=\"w-[28px] h-[28px] flex items-center justify-center rounded-full text-slate-700 hover:text-slate-900 hover:bg-slate-200 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() <= zoomMin()\"\n [title]=\"'i18n_zoom_out' | translate\"\n (click)=\"handlerZoomOut()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Tỷ lệ % và menu preset -->\n <div class=\"relative\">\n <button\n type=\"button\"\n class=\"h-[28px] px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-slate-700 hover:bg-slate-200 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_options' | translate\"\n (click)=\"handlerToggleMenu()\">\n <span>{{ zoomPercent() }}%</span>\n <svg class=\"w-[12px] h-[12px] text-slate-400 transition-transform duration-150\" [class.rotate-180]=\"isMenuOpen()\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n\n <!-- Menu dropdown các mốc thu phóng -->\n @if (isMenuOpen()) {\n <div class=\"absolute bottom-full mb-2 left-0 w-[256px] bg-white rounded-xl shadow-xl border border-slate-200 py-1.5 z-40 text-xs select-none\">\n <div class=\"px-3 py-1 text-[11px] font-semibold text-slate-400 uppercase tracking-wider\">\n {{ 'i18n_zoom_canvas_width' | translate: { width: stageWidth() } }}\n </div>\n <button\n type=\"button\"\n class=\"w-full px-3 py-2 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n (click)=\"handlerFitScreen()\">\n <span class=\"flex items-center gap-2 text-slate-700 font-medium\">\n <svg class=\"w-3.5 h-3.5 text-slate-600\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n {{ 'i18n_zoom_fit_screen' | translate }}\n </span>\n <span class=\"text-[10px] bg-blue-50 text-blue-600 px-1.5 py-0.5 rounded font-medium\">{{ 'i18n_auto' | translate }}</span>\n </button>\n <div class=\"h-px bg-slate-100 my-1\"></div>\n @for (preset of zoomPresets; track preset.value) {\n <button\n type=\"button\"\n class=\"w-full px-3 py-1.5 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n [class.text-blue-600]=\"isCurrentPreset(preset.value)\"\n [class.font-semibold]=\"isCurrentPreset(preset.value)\"\n [class.bg-blue-50]=\"isCurrentPreset(preset.value)\"\n (click)=\"handlerSelectPreset(preset.value)\">\n <span class=\"text-slate-700\" [class.text-blue-600]=\"isCurrentPreset(preset.value)\">\n {{ preset.label | translate }}\n </span>\n @if (isCurrentPreset(preset.value)) {\n <svg class=\"w-3.5 h-3.5 text-blue-600\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n }\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Phóng to (+) -->\n <button\n type=\"button\"\n class=\"w-[28px] h-[28px] flex items-center justify-center rounded-full text-slate-700 hover:text-slate-900 hover:bg-slate-200 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() >= zoomMax()\"\n [title]=\"'i18n_zoom_in' | translate\"\n (click)=\"handlerZoomIn()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Phân cách -->\n <div class=\"h-[16px] w-px bg-slate-200\"></div>\n\n <!-- Nút Vừa màn hình nhanh -->\n <button\n type=\"button\"\n class=\"h-[28px] shrink-0 px-2.5 flex items-center gap-1 rounded-full text-xs text-slate-700 hover:text-slate-900 hover:bg-slate-200 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_fit_screen_tooltip' | translate\"\n (click)=\"handlerFitScreen()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n <span class=\"whitespace-nowrap font-medium\">{{ 'i18n_zoom_fit_screen' | translate }}</span>\n </button>\n\n <!-- Nút Đặt lại 100% (chỉ hiện khi khác 100%) -->\n @if (zoomPercent() !== 100) {\n <button\n type=\"button\"\n class=\"h-[28px] px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-blue-600 hover:bg-blue-50 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_reset_tooltip' | translate: { width: stageWidth(), height: stageMinHeight() }\"\n (click)=\"handlerResetZoom()\">\n <svg class=\"w-[12px] h-[12px]\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>\n <span>100%</span>\n </button>\n }\n </div>\n }\n} @else {\n <!-- 🔴 `relative` là BẮT BUỘC, CẤM bỏ.\n gridster đổi vị trí chuột thành ô lưới bằng `e.clientY + (el.scrollTop - el.offsetTop)` — công\n thức đó chỉ đúng khi `offsetParent` của <gridster> CHÍNH LÀ khối cuộn này. Thiếu `relative` thì\n `offsetParent` nhảy lên khối bao ngoài: `offsetTop` trả 16 trong khi lệch thật là 65 → gridster\n tính ô sai 49px, ô chờ đặt hiện lệch khỏi con trỏ nên kéo thả không đổi được vị trí, và kéo mép\n cũng tính sai điểm dừng. -->\n <!-- 🔴 `ignoreInit` là công tắc BẬT/TẮT của thanh cuộn nổi: directive không thể gắn có điều kiện,\n nên khi tắt phải chặn ngay ở đây — bật rồi mới bọc thêm `div.libs-ui-scroll-overlay-container`.\n Nhờ vậy mặt phẳng GỐC của nơi dùng khác giữ nguyên cấu trúc DOM như trước. -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0\"\n [class.overflow-y-auto]=\"!isNestedCanvas()\"\n LibsUiComponentsScrollOverlayDirective\n [ignoreInit]=\"!showNestedScrollbar()\"\n [options]=\"nestedScrollOverlayOptions\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (pointerdown)=\"handlerScrollAreaPointerDown()\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster\n class=\"h-full w-full\"\n [class.display-grid]=\"showGridLines()\"\n [class.libs-ui-grid-layout-drag-anywhere]=\"dragFromAnywhere()\"\n [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <!-- 🔴 `dragFromAnywhere` bật thì BỎ class chặn — CẤM gắn lại vô điều kiện.\n `libs-ui-grid-layout-block-parent-drag` CHÍNH LÀ `ignoreContentClass` của gridster (xem\n `gridster-config.define`). Với `ignoreContent: true` nó chỉ mang nghĩa \"không phải tay\n cầm\"; nhưng với `ignoreContent: false` (chế độ cầm-cả-thẻ) gridster hiểu là \"vùng CẤM\n kéo\": duyệt từ chỗ bấm lên gặp class này là dừng hẳn, nên KHỐI CON trong khối ghép bấm\n vào đâu cũng không nhúc nhích (người dùng chỉ ra 15/09/2026; đo được kéo 150px mà khối\n lệch 0px). Chặn lưới cha ở chế độ này do `handlerBlockParentDrag` trên chính\n `gridster-item` lo, không cần class này. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [attr.data-node-id]=\"item.id\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas() && !dragFromAnywhere()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n <!-- 🔴 `dragFromAnywhere` bật thì KHÔNG vẽ dải: cả thẻ đã là tay cầm, để lại dải chỉ thừa. -->\n @if (isEditMode() && !dragFromAnywhere()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <!-- 🔴 Container CÓ `getComponentOutlet`: khung này là VỎ, và canvas con được đưa VÀO TRONG\n component vỏ qua input `childCanvas` (một `TemplateRef`) — xem `ng-template #childCanvasTpl`\n bên dưới. Vỏ tự quyết đặt canvas ở đâu giữa tiêu đề và phần thân của nó.\n Trước đây canvas con là ANH EM của khung này, nên vỏ chiếm trọn chiều cao rồi đẩy toàn bộ\n thẻ con ra ngoài vùng nhìn thấy (đo 14/09/2026: mọi khối ghép chỉ còn nhãn và ruột trắng). -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item) && !item.getComponentOutlet\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px.\n\n 🔴 Khuôn đặt trong `ng-template` để đi được HAI đường:\n - Container KHÔNG có vỏ riêng → vẽ thẳng tại đây, y như trước.\n - Container CÓ `getComponentOutlet` → thư viện truyền khuôn này xuống component vỏ qua\n input `childCanvas`, vỏ tự đặt nó vào giữa tiêu đề và phần thân của mình. Vẽ thêm ở\n đây nữa là hai mặt phẳng lồng chồng nhau. -->\n <ng-template #childCanvasTpl>\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [dragFromAnywhere]=\"dragFromAnywhere()\"\n [nestedScrollbar]=\"nestedScrollbar()\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n </ng-template>\n\n @if (!item.getComponentOutlet) {\n <ng-container [ngTemplateOutlet]=\"childCanvasTpl\" />\n }\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n}\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\nimport { calculateDropGhost } from './defines/collision.define';\n\n/** Lớp CSS bật ô li của một lưới trong lúc người dùng đang kéo khối vào. */\nconst LOP_HIEN_O_LI = 'display-grid';\n\n/**\n * Giữ trạng thái một lượt kéo khối từ palette bên ngoài vào mặt phẳng.\n *\n * Việc nó lo: bật ô li của lưới đang được kéo tới (lưới gốc, và lưới của container khi con trỏ đi\n * vào trong), tắt đúng lúc, và trả về ghost để nơi dùng vẽ khung xem trước.\n *\n * 🔴 Tự bật/tắt ô li bằng tay ở nơi dùng là chỗ rất dễ sót: kéo ra khỏi container rồi mà quên tắt\n * thì ô li của nó nằm lại trên màn, kéo sang lưới khác lại chồng thêm một lớp nữa.\n */\nexport class LibsUiGridLayoutDragController {\n private payload?: T_gridLayout_externalDragPayload;\n private hoveredElement?: HTMLElement;\n private rootGridsterElement?: HTMLElement;\n\n /** Payload của khối đang được kéo; `undefined` khi không có lượt kéo nào. */\n get ActivePayload(): T_gridLayout_externalDragPayload | undefined {\n return this.payload;\n }\n\n /** Gọi ở `dragstart` của thẻ trong palette. */\n onDragStart(payload: T_gridLayout_externalDragPayload): void {\n this.payload = payload;\n }\n\n /** Gọi ở `dragend` — dọn sạch mọi ô li đang bật. */\n onDragEnd(container?: HTMLElement): void {\n this.payload = undefined;\n this.cleanupAll(container);\n }\n\n /** Tắt ô li của container đang hover. */\n cleanupHoveredGroup(): void {\n if (!this.hoveredElement) {\n return;\n }\n this.hoveredElement.classList.remove(LOP_HIEN_O_LI);\n this.hoveredElement = undefined;\n }\n\n /** Tắt ô li của lưới gốc, và quét sạch lớp còn sót trong khung chứa. */\n cleanupRootGrid(container?: HTMLElement): void {\n if (this.rootGridsterElement) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n this.rootGridsterElement = undefined;\n }\n container?.querySelectorAll(`gridster.${LOP_HIEN_O_LI}`).forEach((el) => el.classList.remove(LOP_HIEN_O_LI));\n }\n\n /** Tắt toàn bộ ô li đang bật. */\n cleanupAll(container?: HTMLElement): void {\n this.cleanupHoveredGroup();\n this.cleanupRootGrid(container);\n }\n\n /**\n * Gọi ở `dragover` của khung chứa mặt phẳng. Trả ghost để nơi dùng vẽ khung xem trước, đồng thời\n * tự bật ô li của lưới đang được kéo tới.\n */\n onDragOver(\n event: DragEvent,\n container: HTMLElement | undefined,\n root: T_gridLayout_node | undefined,\n totalCols?: number,\n // Chiều cao một hàng lưới (pixel) để khung xem trước đúng cỡ; không truyền thì giữ mặc định cũ.\n rowStep?: number\n ): T_gridLayout_dropGhost | undefined {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n if (!container || !root || !this.payload) {\n return undefined;\n }\n this.showRootGrid(container);\n\n const ghost = calculateDropGhost(event, container, root, this.payload, totalCols, rowStep);\n\n if (!ghost?.isInsideGroup || !ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n\n return ghost;\n }\n\n if (this.hoveredElement !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add(LOP_HIEN_O_LI);\n this.hoveredElement = ghost.hoveredGridster;\n }\n\n return ghost;\n }\n\n /** Bật ô li của lưới CẤP TRANG trong suốt lượt kéo, tắt lưới cũ nếu khung chứa đã đổi. */\n private showRootGrid(container: HTMLElement): void {\n const rootGridster = (container.querySelector('gridster') as HTMLElement | null) ?? undefined;\n\n if (!rootGridster) {\n return;\n }\n\n if (this.rootGridsterElement && this.rootGridsterElement !== rootGridster) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n }\n rootGridster.classList.add(LOP_HIEN_O_LI);\n this.rootGridsterElement = rootGridster;\n }\n}\n","// Bề mặt CÔNG KHAI — chỉ những gì nơi dùng thật sự cần.\n//\n// `LibsUiGridLayoutTreeService` CỐ Ý không xuất: mọi thao tác trên cây đã có mặt trên\n// `LibsUiGridLayoutService` với chữ ký gọn hơn (không phải truyền `root` — thư viện đang giữ nó).\n// Cấu hình gridster cũng không xuất: nó đã được vá theo hàng chục lỗi đo trên sản phẩm thật, để nơi\n// dùng sửa lại là mở đường cho chính những lỗi đó quay về.\nexport * from './grid-layout.service';\nexport * from './canvas/grid-layout-canvas.component';\nexport * from './interfaces/grid-layout.interface';\nexport * from './defines/collision.define';\nexport * from './drag-controller';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}