From 08da8f15a45c53cba7ced6854e772096d04d7051 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 17 May 2024 17:49:59 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/11409 --- app/src/protyle/render/av/cell.ts | 7 +- app/src/protyle/render/av/select.ts | 40 ++++- app/src/protyle/util/insertHTML.ts | 258 +++++++++++++++------------- 3 files changed, 178 insertions(+), 127 deletions(-) diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 714db18ca..d9cec86d4 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -514,7 +514,8 @@ const updateCellValueByInput = (protyle: IProtyle, type: TAVCol, blockElement: H }); }; -export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, value?: any, cElements?: HTMLElement[]) => { +export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, value?: any, cElements?: HTMLElement[], + columns?: IAVColumn[]) => { const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; @@ -535,7 +536,7 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va }); } } - + const isCustomAttr = !hasClosestByClassName(cellElements[0], "custom-attr"); cellElements.forEach((item: HTMLElement, elementIndex) => { const rowElement = hasClosestByClassName(item, "av__row"); if (!rowElement) { @@ -617,7 +618,7 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va rowID, data: oldValue }); - if (!hasClosestByClassName(cellElements[0], "custom-attr")) { + if (!isCustomAttr) { updateAttrViewCellAnimation(item, cellValue); } else { item.innerHTML = genAVValueHTML(cellValue); diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index 7fe5386c4..0e966b492 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -63,7 +63,7 @@ export const removeCellOption = (protyle: IProtyle, cellElements: HTMLElement[], const doOperations: IOperation[] = []; const undoOperations: IOperation[] = []; let mSelectValue: IAVCellSelectValue[]; - const avID = blockElement.getAttribute("data-av-id"); + const avID = blockElement.getAttribute("data-av-id"); cellElements.forEach((item, elementIndex) => { if (!blockElement.contains(item)) { const rowElement = hasClosestByClassName(item, "av__row"); @@ -565,3 +565,41 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[], init
${filterSelectHTML("", colData.options, selected)}
`; }; + +export const mergeAddOption = (column: IAVColumn, cellValue: IAVCellValue, avID:string) => { + const doOperations: IOperation[] = []; + const undoOperations: IOperation[] = []; + cellValue.mSelect.forEach((item: IAVCellSelectValue) => { + const needAdd = column.options.find((option: { + name: string, + color: string, + }) => { + if (option.name === item.content) { + item.color = option.color; + return true; + } + }); + if (!needAdd) { + column.options.push({ + name: item.content, + color:(column.options?.length || 0) % 13 + 1 + }); + doOperations.push({ + action: "updateAttrViewColOptions", + id: column.id, + avID, + data: column.options + }) + undoOperations.push({ + action: "removeAttrViewColOption", + id: column.id, + avID, + data: item.content, + }); + } + }); + return { + doOperations, + undoOperations + }; +} diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 795791284..325cfba50 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -10,6 +10,8 @@ import {updateAttrViewCellAnimation, updateAVName} from "../render/av/action"; import {genCellValue, genCellValueByElement, getTypeByCellElement, updateCellsValue} from "../render/av/cell"; import {input} from "../wysiwyg/input"; import {objEquals} from "../../util/functions"; +import {fetchPost} from "../../util/fetch"; +import {mergeAddOption} from "../render/av/select"; const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: HTMLElement) => { const tempElement = document.createElement("template"); @@ -32,147 +34,157 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement: }); }); } - if (values && Array.isArray(values) && values.length > 0) { - const cellElements: Element[] = Array.from(blockElement.querySelectorAll(".av__cell--active, .av__cell--select")) || []; - if (cellElements.length === 0) { - blockElement.querySelectorAll(".av__row--select:not(.av__row--header)").forEach(rowElement => { - rowElement.querySelectorAll(".av__cell").forEach(cellElement => { - cellElements.push(cellElement); + const avID = blockElement.dataset.avId; + fetchPost("/api/av/getAttributeViewKeysByAvID", {avID}, (response) => { + const columns: IAVColumn[] = response.data; + if (values && Array.isArray(values) && values.length > 0) { + const cellElements: Element[] = Array.from(blockElement.querySelectorAll(".av__cell--active, .av__cell--select")) || []; + if (cellElements.length === 0) { + blockElement.querySelectorAll(".av__row--select:not(.av__row--header)").forEach(rowElement => { + rowElement.querySelectorAll(".av__cell").forEach(cellElement => { + cellElements.push(cellElement); + }); }); - }); - } - if (cellElements.length === 0) { - cellElements.push(blockElement.querySelector(".av__row:not(.av__row--header) .av__cell")); - } - const doOperations: IOperation[] = []; - const undoOperations: IOperation[] = []; + } + if (cellElements.length === 0) { + cellElements.push(blockElement.querySelector(".av__row:not(.av__row--header) .av__cell")); + } + const doOperations: IOperation[] = []; + const undoOperations: IOperation[] = []; - const avID = blockElement.dataset.avId; - const id = blockElement.dataset.nodeId; - let currentRowElement: Element; - const firstColIndex = cellElements[0].getAttribute("data-col-id"); - values.find(rowItem => { - if (!currentRowElement) { - currentRowElement = cellElements[0].parentElement; - } else { - currentRowElement = currentRowElement.nextElementSibling; - } - if (!currentRowElement.classList.contains("av__row")) { - return true; - } - let cellElement: HTMLElement; - rowItem.find(cellValue => { - if (!cellElement) { - cellElement = currentRowElement.querySelector(`.av__cell[data-col-id="${firstColIndex}"]`) as HTMLElement; + const avID = blockElement.dataset.avId; + const id = blockElement.dataset.nodeId; + let currentRowElement: Element; + const firstColIndex = cellElements[0].getAttribute("data-col-id"); + values.find(rowItem => { + if (!currentRowElement) { + currentRowElement = cellElements[0].parentElement; } else { - cellElement = cellElement.nextElementSibling as HTMLElement; + currentRowElement = currentRowElement.nextElementSibling; } - if (!cellElement.classList.contains("av__cell")) { + if (!currentRowElement.classList.contains("av__row")) { return true; } - const type = getTypeByCellElement(cellElement) || cellElement.dataset.type as TAVCol; - if (["created", "updated", "template", "rollup"].includes(type) || - (type === "block" && !cellElement.dataset.detached)) { - return; - } - const rowID = currentRowElement.getAttribute("data-id"); - const cellId = cellElement.getAttribute("data-id"); - const colId = cellElement.getAttribute("data-col-id"); + let cellElement: HTMLElement; + rowItem.find(cellValue => { + if (!cellElement) { + cellElement = currentRowElement.querySelector(`.av__cell[data-col-id="${firstColIndex}"]`) as HTMLElement; + } else { + cellElement = cellElement.nextElementSibling as HTMLElement; + } + if (!cellElement.classList.contains("av__cell")) { + return true; + } + const type = getTypeByCellElement(cellElement) || cellElement.dataset.type as TAVCol; + if (["created", "updated", "template", "rollup"].includes(type) || + (type === "block" && !cellElement.dataset.detached)) { + return; + } + const rowID = currentRowElement.getAttribute("data-id"); + const cellId = cellElement.getAttribute("data-id"); + const colId = cellElement.getAttribute("data-col-id"); - const oldValue = genCellValueByElement(type, cellElement); - if (cellValue.type !== type) { - if (type === "date") { - // 类型不能转换时就不进行替换 + const oldValue = genCellValueByElement(type, cellElement); + if (cellValue.type !== type && + !(["select", "mSelect"].includes(type) && ["select", "mSelect"].includes(cellValue.type))) { + if (type === "date") { + // 类型不能转换时就不进行替换 + return; + } + const content = cellValue[cellValue.type as "text"]?.content; + if (!content) { + return; + } + cellValue = genCellValue(type, cellValue[cellValue.type as "text"].content.toString()); + } + if (cellValue.type === "block") { + cellValue.isDetached = true; + delete cellValue.block.id; + } else if (type === "select" || type === "mSelect") { + const operations = mergeAddOption(columns.find(e => e.id === cellElement.dataset.colId), cellValue, avID); + doOperations.push(...operations.doOperations); + undoOperations.push(...operations.undoOperations); + } + cellValue.id = cellId; + if ((cellValue.type === "date" && typeof cellValue.date === "string") || + (cellValue.type === "relation" && typeof cellValue.relation === "string")) { return; } - const content = cellValue[cellValue.type as "text"].content; - if (!content) { + if (objEquals(cellValue, oldValue)) { return; } - cellValue = genCellValue(type, cellValue[cellValue.type as "text"].content.toString()); - } - if (cellValue.type === "block") { - cellValue.isDetached = true; - delete cellValue.block.id; - } - cellValue.id = cellId; - if ((cellValue.type === "date" && typeof cellValue.date === "string") || - (cellValue.type === "relation" && typeof cellValue.relation === "string")) { - return; - } - if (objEquals(cellValue, oldValue)) { - return; - } + doOperations.push({ + action: "updateAttrViewCell", + id: cellId, + avID, + keyID: colId, + rowID, + data: cellValue + }); + undoOperations.push({ + action: "updateAttrViewCell", + id: cellId, + avID, + keyID: colId, + rowID, + data: oldValue + }); + updateAttrViewCellAnimation(cellElement, cellValue); + }); + }); + if (doOperations.length > 0) { doOperations.push({ - action: "updateAttrViewCell", - id: cellId, - avID, - keyID: colId, - rowID, - data: cellValue + action: "doUpdateUpdated", + id, + data: dayjs().format("YYYYMMDDHHmmss"), }); undoOperations.push({ - action: "updateAttrViewCell", - id: cellId, - avID, - keyID: colId, - rowID, - data: oldValue + action: "doUpdateUpdated", + id, + data: blockElement.getAttribute("updated"), }); - updateAttrViewCellAnimation(cellElement, cellValue); - }); - }); - if (doOperations.length > 0) { - doOperations.push({ - action: "doUpdateUpdated", - id, - data: dayjs().format("YYYYMMDDHHmmss"), - }); - undoOperations.push({ - action: "doUpdateUpdated", - id, - data: blockElement.getAttribute("updated"), - }); - transaction(protyle, doOperations, undoOperations); - } - return; - } - const contenteditableElement = getContenteditableElement(tempElement.content.firstElementChild); - if (contenteditableElement && contenteditableElement.childNodes.length === 1 && contenteditableElement.firstElementChild?.getAttribute("data-type") === "block-ref") { - const selectCellElement = blockElement.querySelector(".av__cell--select") as HTMLElement; - if (selectCellElement) { - const avID = blockElement.dataset.avId; - const sourceId = contenteditableElement.firstElementChild.getAttribute("data-id"); - const previousID = selectCellElement.dataset.blockId; - transaction(protyle, [{ - action: "replaceAttrViewBlock", - avID, - previousID, - nextID: sourceId, - isDetached: false, - }], [{ - action: "replaceAttrViewBlock", - avID, - previousID: sourceId, - nextID: previousID, - isDetached: selectCellElement.dataset.detached === "true", - }]); + transaction(protyle, doOperations, undoOperations); + } return; } - } - const text = protyle.lute.BlockDOM2EscapeMarkerContent(html); - const cellsElement: HTMLElement[] = Array.from(blockElement.querySelectorAll(".av__cell--select")); - const rowsElement = blockElement.querySelector(".av__row--select"); - if (rowsElement) { - updateCellsValue(protyle, blockElement as HTMLElement, text); - } else if (cellsElement.length > 0) { - updateCellsValue(protyle, blockElement as HTMLElement, text, cellsElement); - } else if (hasClosestByClassName(range.startContainer, "av__title")) { - range.insertNode(document.createTextNode(text)); - range.collapse(false); - updateAVName(protyle, blockElement); - } + const contenteditableElement = getContenteditableElement(tempElement.content.firstElementChild); + if (contenteditableElement && contenteditableElement.childNodes.length === 1 && contenteditableElement.firstElementChild?.getAttribute("data-type") === "block-ref") { + const selectCellElement = blockElement.querySelector(".av__cell--select") as HTMLElement; + if (selectCellElement) { + const sourceId = contenteditableElement.firstElementChild.getAttribute("data-id"); + const previousID = selectCellElement.dataset.blockId; + transaction(protyle, [{ + action: "replaceAttrViewBlock", + avID, + previousID, + nextID: sourceId, + isDetached: false, + }], [{ + action: "replaceAttrViewBlock", + avID, + previousID: sourceId, + nextID: previousID, + isDetached: selectCellElement.dataset.detached === "true", + }]); + return; + } + } + + const text = protyle.lute.BlockDOM2EscapeMarkerContent(html); + const cellsElement: HTMLElement[] = Array.from(blockElement.querySelectorAll(".av__cell--select")); + const rowsElement = blockElement.querySelector(".av__row--select"); + + if (rowsElement) { + updateCellsValue(protyle, blockElement as HTMLElement, text, undefined, columns); + } else if (cellsElement.length > 0) { + updateCellsValue(protyle, blockElement as HTMLElement, text, cellsElement, columns); + } else if (hasClosestByClassName(range.startContainer, "av__title")) { + range.insertNode(document.createTextNode(text)); + range.collapse(false); + updateAVName(protyle, blockElement); + } + }); }; export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,