diff --git a/app/src/assets/scss/protyle/_wysiwyg.scss b/app/src/assets/scss/protyle/_wysiwyg.scss index 90050c0d9..44c370673 100644 --- a/app/src/assets/scss/protyle/_wysiwyg.scss +++ b/app/src/assets/scss/protyle/_wysiwyg.scss @@ -441,11 +441,11 @@ .dragover { // 需要 !important,否则拖拽到闪卡无 border &__top { - box-shadow: 0 -4px 0 var(--b3-theme-primary-lighter) !important; + box-shadow: 0 4px 0 var(--b3-theme-primary-lighter) inset !important; } &__bottom { - box-shadow: 0 4px 0 var(--b3-theme-primary-lighter) !important; + box-shadow: 0 -4px 0 var(--b3-theme-primary-lighter) inset !important; } &__left { diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index 1a2ca7dd4..aeed7a3b2 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -27,7 +27,7 @@ export const avRender = (element: Element, cb?: () => void) => { if (column.hidden) { return; } - tableHTML += `
+ tableHTML += `
${column.name}
`; @@ -43,7 +43,7 @@ export const avRender = (element: Element, cb?: () => void) => { // body data.rows.forEach((row: IAVRow) => { tableHTML += `
-
+
`; diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index 95882878d..81f91b81c 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -703,16 +703,43 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { event.preventDefault(); return; } - if (target.classList && target.classList.contains("protyle-action")) { + if (target.classList) { if (hasClosestByClassName(target, "protyle-wysiwyg__embed")) { window.siyuan.dragElement = undefined; event.preventDefault(); - } else { - window.siyuan.dragElement = protyle.wysiwyg.element; - event.dataTransfer.setData(`${Constants.SIYUAN_DROP_GUTTER}NodeListItem${Constants.ZWSP}${target.parentElement.getAttribute("data-subtype")}${Constants.ZWSP}${[target.parentElement.getAttribute("data-node-id")]}`, - protyle.wysiwyg.element.innerHTML); + } else if (target.classList.contains("protyle-action")) { + if (hasClosestByClassName(target, "protyle-wysiwyg__embed")) { + window.siyuan.dragElement = undefined; + event.preventDefault(); + } else { + window.siyuan.dragElement = protyle.wysiwyg.element; + event.dataTransfer.setData(`${Constants.SIYUAN_DROP_GUTTER}NodeListItem${Constants.ZWSP}${target.parentElement.getAttribute("data-subtype")}${Constants.ZWSP}${[target.parentElement.getAttribute("data-node-id")]}`, + protyle.wysiwyg.element.innerHTML); + } + return; + } else if (target.classList.contains("av__gutters")) { + + const blockElement = hasClosestBlock(target); + if (!blockElement) { + return; + } + const rowElement = target.parentElement; + const selectIds = [] + if (rowElement.classList.contains("av__row--select")) { + rowElement.parentElement.querySelectorAll(".av__row--select:not(.av__row--header)").forEach((item) => { + selectIds.push(item.getAttribute("data-id")) + }) + } else { + selectIds.push(rowElement.getAttribute("data-id")) + } + if (selectIds.length === 1) { + event.dataTransfer.setDragImage(rowElement, 0, 0); + } + window.siyuan.dragElement = rowElement; + event.dataTransfer.setData(`${Constants.SIYUAN_DROP_GUTTER}NodeAttributeView${Constants.ZWSP}Row${Constants.ZWSP}${selectIds}`, + rowElement.innerHTML); + return; } - return; } // 选中编辑器中的文字进行拖拽 event.dataTransfer.setData(Constants.SIYUAN_DROP_EDITOR, Constants.SIYUAN_DROP_EDITOR); @@ -795,22 +822,46 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { if (targetElement.classList.contains("av__row")) { // 拖拽到属性视图内 const blockElement = hasClosestBlock(targetElement); - if (blockElement) { - let previousID = ""; - if (targetElement.classList.contains("dragover__bottom")) { - previousID = targetElement.getAttribute("data-id") || ""; - } else { - previousID = targetElement.previousElementSibling?.getAttribute("data-id") || ""; - } + if (!blockElement) { + return; + } + let previousID = ""; + if (targetElement.classList.contains("dragover__bottom")) { + previousID = targetElement.getAttribute("data-id") || ""; + } else { + previousID = targetElement.previousElementSibling?.getAttribute("data-id") || ""; + } + const avId = blockElement.getAttribute("data-av-id") + if (gutterTypes[0] === "nodeattributeview" && gutterTypes[1] === "row") { + // 行内拖拽 + const doOperations: IOperation[] = []; + const undoOperations: IOperation[] = []; + const undoPreviousId = blockElement.querySelector(`[data-id="${selectedIds[0]}"]`).previousElementSibling.getAttribute("data-id") || ""; + selectedIds.reverse().forEach(item => { + doOperations.push({ + action: "sortAttrViewRow", + parentID: avId, + previousID, + id: item, + }) + undoOperations.push({ + action: "sortAttrViewRow", + parentID: avId, + previousID: undoPreviousId, + id: item, + }) + }); + transaction(protyle, doOperations, undoOperations); + } else { transaction(protyle, [{ action: "insertAttrViewBlock", - parentID: blockElement.getAttribute("data-av-id"), + parentID: avId, previousID, srcIDs: sourceIds, }], [{ action: "removeAttrViewBlock", srcIDs: sourceIds, - parentID: targetElement.getAttribute("data-av-id"), + parentID: avId, }]); } return; @@ -1007,16 +1058,11 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { // 列表项不能拖入列表上方块的下面 disabledPosition = "bottom"; } - const avRowElement = hasClosestByClassName(event.target, "av__row"); - if (targetElement.classList.contains("av") && avRowElement) { - if (avRowElement.classList.contains("av__row--header")) { - // 表头之前不能插入 - disabledPosition = "top"; - } - dragoverElement = avRowElement; - } else { - dragoverElement = targetElement; + if (targetElement?.classList.contains("av__row--header")) { + // 表头之前不能插入 + disabledPosition = "top"; } + dragoverElement = targetElement; } }); editorElement.addEventListener("dragleave", (event: DragEvent & { target: HTMLElement }) => { diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index c442a5128..8d5f16f3d 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -651,7 +651,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b updateRef(protyle, operation.id); } else if (operation.action === "append") { reloadProtyle(protyle, false); - } else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewCell"].includes(operation.action)) { + } else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewCell", "sortAttrViewRow"].includes(operation.action)) { refreshAV(protyle, operation); } }; diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 28fa3dc3f..97d4cceb5 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -24,6 +24,7 @@ type TOperation = | "removeFlashcards" | "updateAttrViewCell" | "updateAttrViewCol" + | "sortAttrViewRow" type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins" type TCardType = "doc" | "notebook" | "all" type TEventBus = "ws-main" |