Browse Source

:art: https://github.com/siyuan-note/siyuan/issues/9892

Vanessa 1 year ago
parent
commit
4bd45961fa

+ 12 - 3
app/src/protyle/render/av/action.ts

@@ -3,7 +3,7 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../
 import {transaction} from "../../wysiwyg/transaction";
 import {openEditorTab} from "../../../menus/util";
 import {copySubMenu} from "../../../menus/commonMenuItem";
-import {getCellText, getTypeByCellElement, popTextCell} from "./cell";
+import {getCellText, getTypeByCellElement, popTextCell, renderCell, updateHeaderCell} from "./cell";
 import {getColIconByType, showColMenu} from "./col";
 import {deleteRow, insertAttrViewBlockAnimation, setPageSize, updateHeader} from "./row";
 import {emitOpenMenu} from "../../../plugin/EventBus";
@@ -413,8 +413,17 @@ export const updateAVName = (protyle: IProtyle, blockElement: Element) => {
     });
 };
 
-export const updateAttrViewCellAnimation = (cellElement: HTMLElement) => {
-    cellElement.style.backgroundColor = "var(--b3-av-hover)";
+export const updateAttrViewCellAnimation = (cellElement: HTMLElement, value: IAVCellValue, headerValue?: {
+    icon?: string,
+    name?: string,
+    pin?: boolean,
+    type?: TAVCol
+}) => {
+    if (headerValue) {
+        updateHeaderCell(cellElement, headerValue);
+    } else {
+        cellElement.innerHTML = renderCell(value, cellElement.dataset.wrap === "true");
+    }
 };
 
 export const removeAttrViewColAnimation = (blockElement: Element, id: string) => {

+ 2 - 2
app/src/protyle/render/av/asset.ts

@@ -133,7 +133,7 @@ export const updateAssetCell = (options: {
                     // 为空时 cellId 每次请求都不一致
                     cellData.id = item.dataset.id;
                     if (!cellData.value || !cellData.value.mAsset) {
-                        cellData.value = {mAsset: []} as IAVCellValue;
+                        cellData.value = {type: "mAsset", mAsset: []} as IAVCellValue;
                     }
                 } else {
                     cellData = row.cells.find(cellItem => {
@@ -206,7 +206,7 @@ export const updateAssetCell = (options: {
         if (item.classList.contains("custom-attr__avvalue")) {
             item.innerHTML = genAVValueHTML(cellData.value);
         } else {
-            updateAttrViewCellAnimation(item);
+            updateAttrViewCellAnimation(item, cellData.value);
         }
     });
     transaction(options.protyle, cellDoOperations, cellUndoOperations);

+ 1 - 1
app/src/protyle/render/av/blockAttr.ts

@@ -88,7 +88,7 @@ export const renderAVAttribute = (element: HTMLElement, id: string, protyle?: IP
                     keyID: string,
                     id: string,
                     blockID: string,
-                    type?: TAVCol & IAVCellValue
+                    type: TAVCol & IAVCellValue
                 }  []
             }[],
             blockIDs: string[],

+ 98 - 4
app/src/protyle/render/av/cell.ts

@@ -7,6 +7,8 @@ import {objEquals} from "../../../util/functions";
 import {fetchPost} from "../../../util/fetch";
 import {focusBlock} from "../../util/selection";
 import * as dayjs from "dayjs";
+import {unicode2Emoji} from "../../../emoji";
+import {getColIconByType} from "./col";
 
 export const getCellText = (cellElement: HTMLElement | false) => {
     if (!cellElement) {
@@ -438,7 +440,11 @@ const updateCellValueByInput = (protyle: IProtyle, type: TAVCol, cellElements: H
                 data: blockElement.getAttribute("updated"),
             });
             if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
-                updateAttrViewCellAnimation(item);
+                updateAttrViewCellAnimation(item, {
+                    [type]: inputValue,
+                    isDetached: true,
+                    type
+                });
             }
         });
     }
@@ -487,14 +493,14 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va
         const colId = item.getAttribute("data-col-id");
 
         text += getCellText(item);
-
+        const cellValue = genCellValue(type, value);
         doOperations.push({
             action: "updateAttrViewCell",
             id: cellId,
             avID,
             keyID: colId,
             rowID,
-            data: genCellValue(type, value)
+            data: cellValue
         });
         undoOperations.push({
             action: "updateAttrViewCell",
@@ -505,7 +511,7 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va
             data: genCellValueByElement(type, item)
         });
         if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
-            updateAttrViewCellAnimation(item);
+            updateAttrViewCellAnimation(item, cellValue);
         }
     });
     if (doOperations.length > 0) {
@@ -523,3 +529,91 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va
     }
     return text;
 };
+
+export const renderCell = (cellValue: IAVCellValue, wrap: boolean) => {
+    let text = "";
+    if (["text", "template"].includes(cellValue.type)) {
+        text = `<span class="av__celltext">${cellValue ? (cellValue[cellValue.type as "text"].content || "") : ""}</span>`;
+    } else if (["url", "email", "phone"].includes(cellValue.type)) {
+        const urlContent = cellValue ? cellValue[cellValue.type as "url"].content : "";
+        // https://github.com/siyuan-note/siyuan/issues/9291
+        let urlAttr = "";
+        if (cellValue.type === "url") {
+            urlAttr = ` data-href="${urlContent}"`;
+        }
+        text = `<span class="av__celltext av__celltext--url" data-type="${cellValue.type}"${urlAttr}>${urlContent}</span>`;
+    } else if (cellValue.type === "block") {
+        if (cellValue?.isDetached) {
+            text = `<span class="av__celltext${cellValue?.isDetached ? "" : " av__celltext--ref"}">${cellValue.block.content || ""}</span>
+<span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.more}</span>`;
+        } else {
+            text = `<span data-type="block-ref" data-id="${cellValue.block.id}" data-subtype="s" class="av__celltext${cellValue?.isDetached ? "" : " av__celltext--ref"}">${cellValue.block.content || ""}</span>
+<span class="b3-chip b3-chip--info b3-chip--small popover__block" data-id="${cellValue.block.id}" data-type="block-more">${window.siyuan.languages.update}</span>`;
+        }
+    } else if (cellValue.type === "number") {
+        text = `<span style="float: right;${wrap ? "word-break: break-word;" : ""}" class="av__celltext" data-content="${cellValue?.number.isNotEmpty ? cellValue?.number.content : ""}">${cellValue?.number.formattedContent || ""}</span>`;
+    } else if (cellValue.type === "mSelect" || cellValue.type === "select") {
+        cellValue?.mSelect?.forEach((item) => {
+            text += `<span class="b3-chip" style="background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">${item.content}</span>`;
+        });
+    } else if (cellValue.type === "date") {
+        const dataValue = cellValue ? cellValue.date : null;
+        text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
+        if (dataValue && dataValue.isNotEmpty) {
+            text += dayjs(dataValue.content).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
+        }
+        if (dataValue && dataValue.hasEndDate && dataValue.isNotEmpty && dataValue.isNotEmpty2) {
+            text += `<svg class="av__cellicon"><use xlink:href="#iconForward"></use></svg>${dayjs(dataValue.content2).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}`;
+        }
+        text += "</span>";
+    } else if (["created", "updated"].includes(cellValue.type)) {
+        const dataValue = cellValue ? cellValue[cellValue.type as "date"] : null;
+        text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
+        if (dataValue && dataValue.isNotEmpty) {
+            text += dayjs(dataValue.content).format("YYYY-MM-DD HH:mm");
+        }
+        text += "</span>";
+    } else if (cellValue.type === "mAsset") {
+        cellValue?.mAsset?.forEach((item) => {
+            if (item.type === "image") {
+                text += `<img class="av__cellassetimg" src="${item.content}">`;
+            } else {
+                text += `<span class="b3-chip av__celltext--url" data-url="${item.content}">${item.name}</span>`;
+            }
+        });
+    } else if (cellValue.type === "checkbox") {
+        text += `<svg class="av__checkbox"><use xlink:href="#icon${cellValue?.checkbox?.checked ? "Check" : "Uncheck"}"></use></svg>`;
+    }
+    if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cellValue.type) &&
+        cellValue && cellValue[cellValue.type as "url"].content) {
+        text += `<span ${cellValue.type !== "number" ? "" : 'style="right:auto;left:5px"'} data-type="copy" class="block__icon"><svg><use xlink:href="#iconCopy"></use></svg></span>`;
+    }
+    return text;
+}
+
+export const updateHeaderCell = (cellElement: HTMLElement, headerValue: {
+    icon?: string,
+    name?: string,
+    pin?: boolean,
+}) => {
+    if (typeof headerValue.icon !== "undefined") {
+        cellElement.dataset.icon = headerValue.icon;
+        cellElement.querySelector(".av__cellheadericon").outerHTML = headerValue.icon ? unicode2Emoji(headerValue.icon, "av__cellheadericon", true) : `<svg class="av__cellheadericon"><use xlink:href="#${getColIconByType(cellElement.dataset.dtype as TAVCol)}"></use></svg>`
+    }
+    if (typeof headerValue.name !== "undefined") {
+        cellElement.querySelector(".av__celltext").textContent = headerValue.name;
+    }
+    if (typeof headerValue.pin !== "undefined") {
+        const textElement = cellElement.querySelector(".av__celltext")
+        if (headerValue.pin) {
+            if (!textElement.nextElementSibling) {
+                textElement.insertAdjacentHTML("afterend", '<div class="fn__flex-1"></div><svg class="av__cellheadericon"><use xlink:href="#iconPin"></use></svg>')
+            }
+        } else {
+            if (textElement.nextElementSibling) {
+                textElement.nextElementSibling.nextElementSibling.remove();
+                textElement.nextElementSibling.remove();
+            }
+        }
+    }
+}

+ 4 - 3
app/src/protyle/render/av/col.ts

@@ -216,7 +216,7 @@ export const bindEditEvent = (options: {
             type: colData.type,
         }]);
         colData.name = newValue;
-        updateAttrViewCellAnimation(options.protyle.wysiwyg.element.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`));
+        updateAttrViewCellAnimation(options.protyle.wysiwyg.element.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {name: newValue});
     });
     nameElement.addEventListener("keydown", (event: KeyboardEvent) => {
         if (event.isComposing) {
@@ -426,7 +426,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
             name: oldValue,
             type,
         }]);
-        updateAttrViewCellAnimation(cellElement);
+        updateAttrViewCellAnimation(blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {name: newValue});
         // https://github.com/siyuan-note/siyuan/issues/9862
         focusBlock(blockElement);
     });
@@ -458,7 +458,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
                     }]);
                     iconElement.setAttribute("data-icon", unicode);
                     iconElement.innerHTML = unicode ? unicode2Emoji(unicode) : `<svg><use xlink:href="#${getColIconByType(type)}"></use></svg>`;
-                    updateAttrViewCellAnimation(cellElement);
+                    updateAttrViewCellAnimation(blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {icon: unicode});
                 });
                 event.preventDefault();
                 event.stopPropagation();
@@ -607,6 +607,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
                 avID,
                 data: isPin
             }]);
+            updateAttrViewCellAnimation(blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {pin: !isPin});
         }
     });
     if (type !== "block") {

+ 4 - 2
app/src/protyle/render/av/date.ts

@@ -162,7 +162,9 @@ export const setDateValue = (options: {
                     // 为空时 cellId 每次请求都不一致
                     cellData.id = item.dataset.id;
                     if (!cellData.value) {
-                        cellData.value = {};
+                        cellData.value = {
+                            type: cellData.valueType
+                        };
                     } else {
                         cellData.value.id = item.dataset.id;
                     }
@@ -203,7 +205,7 @@ export const setDateValue = (options: {
         if (item.classList.contains("custom-attr__avvalue")) {
             item.innerHTML = genAVValueHTML(cellData.value);
         } else {
-            updateAttrViewCellAnimation(item);
+            updateAttrViewCellAnimation(item,  cellData.value);
         }
     });
     transaction(options.protyle, cellDoOperations, cellUndoOperations);

+ 1 - 1
app/src/protyle/render/av/openMenuPanel.ts

@@ -634,7 +634,7 @@ export const openMenuPanel = (options: {
                             data: target.dataset.icon,
                         }]);
                         target.innerHTML = unicode ? unicode2Emoji(unicode) : `<svg><use xlink:href="#${getColIconByType(target.dataset.colType as TAVCol)}"></use></svg>`;
-                        updateAttrViewCellAnimation(options.blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`));
+                        updateAttrViewCellAnimation(options.blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), undefined, {icon: unicode});
                         target.dataset.icon = unicode;
                     });
                     event.preventDefault();

+ 2 - 60
app/src/protyle/render/av/render.ts

@@ -1,8 +1,7 @@
 import {fetchPost} from "../../../util/fetch";
 import {getColIconByType} from "./col";
 import {Constants} from "../../../constants";
-import {popTextCell} from "./cell";
-import * as dayjs from "dayjs";
+import {popTextCell, renderCell} from "./cell";
 import {unicode2Emoji} from "../../../emoji";
 import {focusBlock} from "../../util/selection";
 import {isMac} from "../../util/compatibility";
@@ -136,69 +135,12 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
                         if (data.columns[index].hidden) {
                             return;
                         }
-                        let text = "";
-                        if (["text", "template"].includes(cell.valueType)) {
-                            text = `<span class="av__celltext">${cell.value ? (cell.value[cell.valueType as "text"].content || "") : ""}</span>`;
-                        } else if (["url", "email", "phone"].includes(cell.valueType)) {
-                            const urlContent = cell.value ? cell.value[cell.valueType as "url"].content : "";
-                            // https://github.com/siyuan-note/siyuan/issues/9291
-                            let urlAttr = "";
-                            if (cell.valueType === "url") {
-                                urlAttr = ` data-href="${urlContent}"`;
-                            }
-                            text = `<span class="av__celltext av__celltext--url" data-type="${cell.valueType}"${urlAttr}>${urlContent}</span>`;
-                        } else if (cell.valueType === "block") {
-                            if (cell.value?.isDetached) {
-                                text = `<span class="av__celltext${cell.value?.isDetached ? "" : " av__celltext--ref"}">${cell.value.block.content || ""}</span>
-<span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.more}</span>`;
-                            } else {
-                                text = `<span data-type="block-ref" data-id="${cell.value.block.id}" data-subtype="s" class="av__celltext${cell.value?.isDetached ? "" : " av__celltext--ref"}">${cell.value.block.content || ""}</span>
-<span class="b3-chip b3-chip--info b3-chip--small popover__block" data-id="${cell.value.block.id}" data-type="block-more">${window.siyuan.languages.update}</span>`;
-                            }
-                        } else if (cell.valueType === "number") {
-                            text = `<span style="float: right;${data.columns[index].wrap ? "word-break: break-word;" : ""}" class="av__celltext" data-content="${cell.value?.number.isNotEmpty ? cell.value?.number.content : ""}">${cell.value?.number.formattedContent || ""}</span>`;
-                        } else if (cell.valueType === "mSelect" || cell.valueType === "select") {
-                            cell.value?.mSelect?.forEach((item) => {
-                                text += `<span class="b3-chip" style="background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">${item.content}</span>`;
-                            });
-                        } else if (cell.valueType === "date") {
-                            const dataValue = cell.value ? cell.value.date : null;
-                            text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
-                            if (dataValue && dataValue.isNotEmpty) {
-                                text += dayjs(dataValue.content).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
-                            }
-                            if (dataValue && dataValue.hasEndDate && dataValue.isNotEmpty && dataValue.isNotEmpty2) {
-                                text += `<svg class="av__cellicon"><use xlink:href="#iconForward"></use></svg>${dayjs(dataValue.content2).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}`;
-                            }
-                            text += "</span>";
-                        } else if (["created", "updated"].includes(cell.valueType)) {
-                            const dataValue = cell.value ? cell.value[cell.valueType as "date"] : null;
-                            text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
-                            if (dataValue && dataValue.isNotEmpty) {
-                                text += dayjs(dataValue.content).format("YYYY-MM-DD HH:mm");
-                            }
-                            text += "</span>";
-                        } else if (cell.valueType === "mAsset") {
-                            cell.value?.mAsset?.forEach((item) => {
-                                if (item.type === "image") {
-                                    text += `<img class="av__cellassetimg" src="${item.content}">`;
-                                } else {
-                                    text += `<span class="b3-chip av__celltext--url" data-url="${item.content}">${item.name}</span>`;
-                                }
-                            });
-                        } else if (cell.valueType === "checkbox") {
-                            text += `<svg class="av__checkbox"><use xlink:href="#icon${cell.value?.checkbox?.checked ? "Check" : "Uncheck"}"></use></svg>`;
-                        }
-                        if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cell.valueType) &&
-                            cell.value && cell.value[cell.valueType as "url"].content) {
-                            text += `<span ${cell.valueType !== "number" ? "" : 'style="right:auto;left:5px"'} data-type="copy" class="block__icon"><svg><use xlink:href="#iconCopy"></use></svg></span>`;
-                        }
                         tableHTML += `<div class="av__cell" data-id="${cell.id}" data-col-id="${data.columns[index].id}"
 ${cell.valueType === "block" ? 'data-block-id="' + (cell.value.block.id || "") + '"' : ""} data-wrap="${data.columns[index].wrap}" 
 ${cell.value?.isDetached ? ' data-detached="true"' : ""} 
 style="width: ${data.columns[index].width || "200px"};
 ${cell.bgColor ? `background-color:${cell.bgColor};` : ""}
-${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
+${cell.color ? `color:${cell.color};` : ""}">${renderCell(cell.value, data.columns[index].wrap)}</div>`;
 
                         if (pinIndex === index) {
                             tableHTML += "</div>";

+ 5 - 5
app/src/protyle/render/av/select.ts

@@ -102,7 +102,7 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM
         if (item.classList.contains("custom-attr__avvalue")) {
             item.innerHTML = genAVValueHTML(cellData.value);
         } else {
-            updateAttrViewCellAnimation(item);
+            updateAttrViewCellAnimation(item, cellData.value);
         }
     });
     transaction(protyle, doOperations, undoOperations);
@@ -184,7 +184,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
                                 if (cellElement.classList.contains("custom-attr__avvalue")) {
                                     cellElement.innerHTML = genAVValueHTML(cell.value);
                                 } else {
-                                    updateAttrViewCellAnimation(cellElement);
+                                    updateAttrViewCellAnimation(cellElement, cell.value);
                                 }
                                 return true;
                             }
@@ -262,7 +262,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
                                         if (cellElement.classList.contains("custom-attr__avvalue")) {
                                             cellElement.innerHTML = genAVValueHTML(cell.value);
                                         } else {
-                                            updateAttrViewCellAnimation(cellElement);
+                                            updateAttrViewCellAnimation(cellElement, cell.value);
                                         }
                                         return true;
                                     }
@@ -342,7 +342,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
                                         if (cellElement.classList.contains("custom-attr__avvalue")) {
                                             cellElement.innerHTML = genAVValueHTML(cell.value);
                                         } else {
-                                            updateAttrViewCellAnimation(cellElement);
+                                            updateAttrViewCellAnimation(cellElement, cell.value);
                                         }
                                         return true;
                                     }
@@ -531,7 +531,7 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
         if (item.classList.contains("custom-attr__avvalue")) {
             item.innerHTML = genAVValueHTML(cellData.value);
         } else {
-            updateAttrViewCellAnimation(item);
+            updateAttrViewCellAnimation(item, cellData.value);
         }
     });
 

+ 1 - 1
app/src/protyle/wysiwyg/transaction.ts

@@ -716,7 +716,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
         "updateAttrViewColOption", "updateAttrViewCell", "sortAttrViewRow", "sortAttrViewCol", "setAttrViewColHidden",
         "setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrViewName", "setAttrViewFilters",
         "setAttrViewSorts", "setAttrViewColCalc", "removeAttrViewCol", "updateAttrViewColNumberFormat", "removeAttrViewBlock",
-        "replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon", "setAttrViewColPin", "addAttrViewView",
+        "replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColPin", "addAttrViewView",
         "removeAttrViewView", "setAttrViewViewName", "setAttrViewViewIcon", "duplicateAttrViewView", "sortAttrViewView",
         "setAttrViewPageSize"].includes(operation.action)) {
         refreshAV(protyle, operation, isUndo);

+ 1 - 1
app/src/types/index.d.ts

@@ -1098,7 +1098,7 @@ interface IAVCell {
 
 interface IAVCellValue {
     id?: string,
-    type?: TAVCol,
+    type: TAVCol,
     isDetached?: boolean,
     text?: {
         content: string