From d076941a87d4aca5b50b3d26a1cb964b43ec3caf Mon Sep 17 00:00:00 2001 From: Vanessa Date: Mon, 3 Jul 2023 20:54:57 +0800 Subject: [PATCH] :art: sort https://github.com/siyuan-note/siyuan/issues/7536 --- app/src/protyle/render/av/cell.ts | 40 +++++++++++- app/src/protyle/render/av/openMenuPanel.ts | 72 ++++++++++++++++++++-- app/src/protyle/render/av/render.ts | 11 ++-- app/src/protyle/wysiwyg/transaction.ts | 2 +- app/src/types/index.d.ts | 1 + 5 files changed, 111 insertions(+), 15 deletions(-) diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 793586746..a702fa954 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -2,6 +2,7 @@ import {transaction} from "../../wysiwyg/transaction"; import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest"; import {Menu} from "../../../plugin/Menu"; import {getColIconByType} from "./col"; +import {fetchPost} from "../../../util/fetch"; export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => { const type = cellElement.parentElement.parentElement.firstElementChild.children[parseInt(cellElement.getAttribute("data-index")) + 1].getAttribute("data-dtype") as TAVCol; @@ -39,7 +40,6 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => { }); }; - const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVCol) => { const rowElement = hasClosestByClassName(cellElement, "av__row"); if (!rowElement) { @@ -128,14 +128,48 @@ export const showHeaderCellMenu = (protyle: IProtyle, blockElement: HTMLElement, icon: "iconUp", label: window.siyuan.languages.fileNameNatASC, click() { - + fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => { + transaction(protyle, [{ + action: "setAttrView", + id: avId, + data: { + sorts: [{ + column: colId, + order: "ASC" + }] + } + }], [{ + action: "setAttrView", + id: avId, + data: { + sorts: response.data.av.sorts + } + }]); + }); } }); menu.addItem({ icon: "iconDown", label: window.siyuan.languages.fileNameNatDESC, click() { - + fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => { + transaction(protyle, [{ + action: "setAttrView", + id: avId, + data: { + sorts: [{ + column: colId, + order: "DESC" + }] + } + }], [{ + action: "setAttrView", + id: avId, + data: { + sorts: response.data.av.sorts + } + }]); + }); } }); menu.addItem({ diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index 6255c9554..f78a27873 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -33,6 +33,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect(); setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height); + bindSortsEvent(protyle, menuElement, data); avPanelElement.addEventListener("click", (event) => { event.preventDefault(); let target = event.target as HTMLElement; @@ -40,6 +41,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type const type = target.dataset.type; if (type === "close") { avPanelElement.remove(); + window.siyuan.menus.menu.remove(); event.stopPropagation(); break; } else if (type === "goConfig") { @@ -54,6 +56,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type break; } else if (type === "goSorts") { menuElement.innerHTML = getSortsHTML(data); + bindSortsEvent(protyle, menuElement, data); setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height); event.stopPropagation(); break; @@ -73,6 +76,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type }]); data.sorts = []; menuElement.innerHTML = getSortsHTML(data); + bindSortsEvent(protyle, menuElement, data); setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height); event.stopPropagation(); break; @@ -81,7 +85,29 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type event.stopPropagation(); break; } else if (type === "removeSort") { - // TODO + const oldSorts = Object.assign([], data.sorts); + data.sorts.find((item: IAVSort, index: number) => { + if (item.column === target.parentElement.dataset.id) { + data.sorts.splice(index, 1); + return true; + } + }); + transaction(protyle, [{ + action: "setAttrView", + id: avId, + data: { + sorts: data.sorts + } + }], [{ + action: "setAttrView", + id: avId, + data: { + sorts: oldSorts + } + }]); + menuElement.innerHTML = getSortsHTML(data); + bindSortsEvent(protyle, menuElement, data); + setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height); event.stopPropagation(); break; } else if (type === "newCol") { @@ -224,25 +250,58 @@ const getConfigHTML = (data: IAV) => { `; }; +const bindSortsEvent = (protyle: IProtyle, menuElement: HTMLElement, data: IAV) => { + menuElement.querySelectorAll("select").forEach((item: HTMLSelectElement) => { + item.addEventListener("change", (event) => { + const colId = item.parentElement.getAttribute("data-id"); + const oldSort = JSON.parse(JSON.stringify(data.sorts)); + if (item.previousElementSibling.classList.contains("b3-menu__icon")) { + data.sorts.find((sort: IAVSort) => { + if (sort.column === colId) { + sort.column = item.value + item.parentElement.setAttribute("data-id", item.value); + return true + } + }); + } else { + data.sorts.find((sort: IAVSort) => sort.column === colId).order = item.value as "ASC" | "DESC"; + } + transaction(protyle, [{ + action: "setAttrView", + id: data.id, + data: { + sorts: data.sorts + } + }], [{ + action: "setAttrView", + id: data.id, + data: { + sorts: oldSort + } + }]); + }); + }); +} + const getSortsHTML = (data: IAV) => { let html = ""; const genSortItem = (id: string) => { let sortHTML = '' data.columns.forEach((item) => { - sortHTML += `` + sortHTML += `` }) return sortHTML; } data.sorts.forEach((item: IAVSort) => { - html += ``; @@ -256,7 +315,7 @@ const getSortsHTML = (data: IAV) => { ${html} - @@ -366,6 +425,7 @@ const addSort = (options: { } }]); options.menuElement.innerHTML = getSortsHTML(options.data); + bindSortsEvent(options.protyle, options.menuElement, options.data); setPosition(options.menuElement, options.tabRect.right - options.menuElement.clientWidth, options.tabRect.bottom, options.tabRect.height); } }); diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index 2190cc639..7868bf213 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -92,11 +92,11 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}< ${data.type}
- +
- +
@@ -137,15 +137,16 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => { } lastElement = protyle.contentElement; lastParentID = operation.parentID; + const avId = operation.action === "setAttrView"?operation.id: operation.parentID if (operation.action === "addAttrViewCol") { - Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => { + Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => { item.removeAttribute("data-render"); avRender(item, () => { showHeaderCellMenu(protyle, item, item.querySelector(".av__row--header").lastElementChild.previousElementSibling as HTMLElement); }); }); } else if (operation.action === "setAttrViewColWidth") { - Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => { + Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => { const cellElement = item.querySelector(`.av__cell[data-id="${operation.id}"]`) as HTMLElement; if (!cellElement || cellElement.style.width === operation.data) { return; @@ -156,7 +157,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => { }); }); } else { - Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => { + Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => { item.removeAttribute("data-render"); avRender(item); }); diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index cec997ff7..19c39283d 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -652,7 +652,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b } else if (operation.action === "append") { reloadProtyle(protyle, false); } else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewCell", "sortAttrViewRow", - "sortAttrViewCol", "setAttrViewColHidden", "setAttrViewColWrap", "setAttrViewColWidth"].includes(operation.action)) { + "sortAttrViewCol", "setAttrViewColHidden", "setAttrViewColWrap", "setAttrViewColWidth", "setAttrView"].includes(operation.action)) { refreshAV(protyle, operation); } }; diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 57632c05c..4b3384050 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -831,6 +831,7 @@ interface IAV { name: string, type: "table" rows: IAVRow[], + id: string } interface IAVSort {