diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 126f3b9f1..a368fcf0c 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -25,7 +25,7 @@ import {selectRow} from "./row"; import * as dayjs from "dayjs"; import {openCalcMenu} from "./calc"; import {avRender} from "./render"; -import {openViewMenu} from "./view"; +import {addView, openViewMenu} from "./view"; export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => { const blockElement = hasClosestBlock(event.target); @@ -82,7 +82,12 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle event.preventDefault(); event.stopPropagation(); return true; - } else if (type === "av-sort") { + } else if (type === "av-switcher") { + openMenuPanel({protyle, blockElement, type: "switcher"}); + event.preventDefault(); + event.stopPropagation(); + return true; + } else if (type === "av-sort") { openMenuPanel({protyle, blockElement, type: "sorts"}); event.preventDefault(); event.stopPropagation(); @@ -93,17 +98,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle event.stopPropagation(); return true; } else if (type === "av-add") { - const id = Lute.NewNodeID(); - const avID = blockElement.getAttribute("data-av-id"); - transaction(protyle, [{ - action: "addAttrViewView", - avID, - id - }], [{ - action: "removeAttrViewView", - avID, - id - }]); + addView(protyle, blockElement) event.preventDefault(); event.stopPropagation(); return true; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index 5f35e6c0f..022587315 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -21,14 +21,15 @@ import {openAsset} from "../../../editor/util"; /// #endif import {previewImage} from "../../preview/image"; import {assetMenu} from "../../../menus/protyle"; -import {bindViewEvent, getViewHTML} from "./view"; +import {addView, bindViewEvent, getSwitcherHTML, getViewHTML, openViewMenu} from "./view"; import {removeBlock} from "../../wysiwyg/remove"; import {getEditorRange} from "../../util/selection"; +import {avRender} from "./render"; export const openMenuPanel = (options: { protyle: IProtyle, blockElement: Element, - type: "select" | "properties" | "config" | "sorts" | "filters" | "edit" | "date" | "asset", + type: "select" | "properties" | "config" | "sorts" | "filters" | "edit" | "date" | "asset" | "switcher", colId?: string, // for edit cellElements?: HTMLElement[], // for select & date cb?: (avPanelElement: Element) => void @@ -51,6 +52,8 @@ export const openMenuPanel = (options: { html = getPropertiesHTML(data.view); } else if (options.type === "sorts") { html = getSortsHTML(data.view.columns, data.view.sorts); + } else if (options.type === "switcher") { + html = getSwitcherHTML(data.views, data.viewID); } else if (options.type === "filters") { html = getFiltersHTML(data.view); } else if (options.type === "select") { @@ -130,6 +133,8 @@ export const openMenuPanel = (options: { type = "sorts"; } else if (targetElement.querySelector('[data-type="removeFilter"]')) { type = "filters"; + } else if (targetElement.querySelector('[data-type="av-view-edit"]')) { + type = "switcher"; } else if (targetElement.querySelector('[data-type="editAssetItem"]')) { type = "assets"; } else if (targetElement.querySelector('[data-type="setColOption"]')) { @@ -213,6 +218,21 @@ export const openMenuPanel = (options: { bindSortsEvent(options.protyle, menuElement, data); return; } + if (type === "switcher") { + transaction(options.protyle, [{ + action: "sortAttrViewView", + avID, + id: sourceId, + previousID: isTop ? targetElement.previousElementSibling?.getAttribute("data-id") : targetElement.getAttribute("data-id") + }], [{ + action: "sortAttrViewView", + avID, + id: sourceId, + previousID: sourceElement.previousElementSibling?.getAttribute("data-id") + }]); + // TODO + return; + } if (type === "filters") { const changeData = data.view.filters; const oldData = Object.assign([], changeData); @@ -905,6 +925,34 @@ export const openMenuPanel = (options: { event.preventDefault(); event.stopPropagation(); break; + } else if (type === "av-add") { + addView(options.protyle, options.blockElement); + avPanelElement.remove(); + event.preventDefault(); + event.stopPropagation(); + break; + } else if (type === "av-view-edit") { + if (target.parentElement.querySelector(".b3-chip--primary")) { + openViewMenu({ + protyle: options.protyle, + blockElement: options.blockElement as HTMLElement, + element: target.parentElement + }); + } else { + options.blockElement.removeAttribute("data-render"); + avRender(options.blockElement, options.protyle, () => { + openViewMenu({ + protyle: options.protyle, + blockElement: options.blockElement as HTMLElement, + element: target.parentElement + }); + avPanelElement.querySelector(".b3-chip--primary").classList.remove("b3-chip--primary") + target.parentElement.querySelector(".b3-chip").classList.add("b3-chip--primary") + }, target.parentElement.dataset.id); + } + event.preventDefault(); + event.stopPropagation(); + break; } target = target.parentElement; } diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index 814f94d5c..e915a50bf 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -221,16 +221,21 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}`; -
- + + + + + + + - + - + diff --git a/app/src/protyle/render/av/view.ts b/app/src/protyle/render/av/view.ts index c07d7adab..dd9ac01b5 100644 --- a/app/src/protyle/render/av/view.ts +++ b/app/src/protyle/render/av/view.ts @@ -14,6 +14,7 @@ export const openViewMenu = (options: { protyle: IProtyle, blockElement: HTMLEle icon: "iconEdit", label: window.siyuan.languages.rename, click() { + document.querySelector(".av__panel")?.remove(); openMenuPanel({ protyle: options.protyle, blockElement: options.blockElement, @@ -28,6 +29,7 @@ export const openViewMenu = (options: { protyle: IProtyle, blockElement: HTMLEle icon: "iconSettings", label: window.siyuan.languages.config, click() { + document.querySelector(".av__panel")?.remove(); openMenuPanel({ protyle: options.protyle, blockElement: options.blockElement, @@ -40,6 +42,7 @@ export const openViewMenu = (options: { protyle: IProtyle, blockElement: HTMLEle icon: "iconCopy", label: window.siyuan.languages.duplicate, click() { + document.querySelector(".av__panel")?.remove(); const id = Lute.NewNodeID(); transaction(options.protyle, [{ action: "duplicateAttrViewView", @@ -57,7 +60,8 @@ export const openViewMenu = (options: { protyle: IProtyle, blockElement: HTMLEle icon: "iconTrashcan", label: window.siyuan.languages.delete, click() { - if (options.element.parentElement.querySelectorAll("item").length === 1) { + document.querySelector(".av__panel")?.remove(); + if (options.blockElement.querySelectorAll(".layout-tab-bar .item").length === 1) { removeBlock(options.protyle, options.blockElement, getEditorRange(options.blockElement)); } else { transaction(options.protyle, [{ @@ -147,3 +151,41 @@ export const getViewHTML = (data: IAVTable) => { `; }; + +export const getSwitcherHTML = (views: IAVView[], viewId: string) => { + let html = "" + views.forEach((item) => { + html += ``; + }); + return `` +} + +export const addView = (protyle: IProtyle, blockElement: Element) => { + const id = Lute.NewNodeID(); + const avID = blockElement.getAttribute("data-av-id"); + transaction(protyle, [{ + action: "addAttrViewView", + avID, + id + }], [{ + action: "removeAttrViewView", + avID, + id + }]); +} diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 9b4cad2fa..08fe9bb36 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -712,7 +712,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo: "setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrViewName", "setAttrViewFilters", "setAttrViewSorts", "setAttrViewColCalc", "removeAttrViewCol", "updateAttrViewColNumberFormat", "removeAttrViewBlock", "replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon", "setAttrViewColPin", "addAttrViewView", - "removeAttrViewView", "setAttrViewViewName", "setAttrViewViewIcon", "duplicateAttrViewView"].includes(operation.action)) { + "removeAttrViewView", "setAttrViewViewName", "setAttrViewViewIcon", "duplicateAttrViewView", "sortAttrViewView"].includes(operation.action)) { refreshAV(protyle, operation, isUndo); } else if (operation.action === "doUpdateUpdated") { updateElements.forEach(item => { diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 7997e9f2e..0b55f862c 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -47,6 +47,7 @@ type TOperation = | "removeAttrViewView" | "setAttrViewViewIcon" | "duplicateAttrViewView" + | "sortAttrViewView" type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins" type TCardType = "doc" | "notebook" | "all" type TEventBus = "ws-main" |