diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 2b60bcf4c..b604117e3 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1,4 +1,6 @@ { + "hideAll": "隐藏全部", + "showAll": "显示全部", "number": "数字", "date": "日期", "select": "单选", diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index 45e5a3cf8..e3a460132 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -114,8 +114,16 @@ z-index: 504; position: relative; + .b3-menu { + width: 300px; + } + .b3-menu__item:not([data-type="title"]):hover { background-color: var(--b3-list-hover); + + .b3-menu__action { + opacity: 1; + } } } diff --git a/app/src/protyle/hint/extend.ts b/app/src/protyle/hint/extend.ts index 16102dcc1..2dddeab03 100644 --- a/app/src/protyle/hint/extend.ts +++ b/app/src/protyle/hint/extend.ts @@ -46,11 +46,11 @@ export const hintSlash = (key: string, protyle: IProtyle) => { filter: ["ai chat"], value: Constants.ZWSP + 5, html: '
AI Chat
', - }, /*{ + }, { filter: ["属性视图", "shuxingshitu", "sxst", "attribute view"], value: '
', html: `
${window.siyuan.languages.attributeView}
`, - },*/ { + }, { filter: ["文档", "子文档", "wendang", "wd", "ziwendang", "zwd", "xjwd"], value: Constants.ZWSP + 4, html: `
${window.siyuan.languages.newFile}${updateHotkeyTip(window.siyuan.config.keymap.general.newFile.custom)}
`, diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 74cc0babc..ad0549729 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -16,7 +16,13 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle } const addElement = hasClosestByAttribute(event.target, "data-type", "av-header-add"); if (addElement) { - addCol(protyle, blockElement, addElement); + const addMenu = addCol(protyle, blockElement); + const addRect = addElement.getBoundingClientRect() + addMenu.open({ + x: addRect.left, + y: addRect.bottom, + h: addRect.height + }); event.preventDefault(); event.stopPropagation(); return true; diff --git a/app/src/protyle/render/av/addCol.ts b/app/src/protyle/render/av/addCol.ts index d4aa5717b..ec230a391 100644 --- a/app/src/protyle/render/av/addCol.ts +++ b/app/src/protyle/render/av/addCol.ts @@ -1,7 +1,7 @@ import {Menu} from "../../../plugin/Menu"; import {transaction} from "../../wysiwyg/transaction"; -export const addCol = (protyle:IProtyle, blockElement:HTMLElement, addElement:HTMLElement) => { +export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { const menu = new Menu("av-header-add"); menu.addItem({ icon: "iconAlignLeft", @@ -98,10 +98,5 @@ export const addCol = (protyle:IProtyle, blockElement:HTMLElement, addElement:HT }]); } }); - const addRect = addElement.getBoundingClientRect(); - menu.open({ - x: addRect.left, - y: addRect.bottom, - h: addRect.height - }); + return menu; } diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts index 977473034..26d9bfc52 100644 --- a/app/src/protyle/render/av/col.ts +++ b/app/src/protyle/render/av/col.ts @@ -6,6 +6,14 @@ export const getColIconByType = (type: TAVCol) => { return "iconAlignLeft"; case "block": return "iconParagraph"; + case "number": + return "iconNumber"; + case "select": + return "iconListItem"; + case "mSelect": + return "iconList"; + case "date": + return "iconCalendar"; } }; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index 2c20bf22b..742f61181 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -1,7 +1,7 @@ -import {Menu} from "../../../plugin/Menu"; import {transaction} from "../../wysiwyg/transaction"; import {fetchPost} from "../../../util/fetch"; -import {hideElements} from "../../ui/hideElements"; +import {addCol} from "./addCol"; +import {getColIconByType} from "./col"; export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type: "properties" | "config" = "config") => { let avMenuPanel = document.querySelector(".av__panel"); @@ -10,90 +10,88 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type return; } window.siyuan.menus.menu.remove(); - fetchPost("/api/av/renderAttributeView", {id: blockElement.getAttribute("data-av-id")}, (response) => { - const data = response.data.av; + const avId = blockElement.getAttribute("data-av-id") + fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => { + const data = response.data.av as IAV; const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect() let html if (type === "config") { - html = `
-
-
- - - - - -
-
` + html = getConfigHTML(data, tabRect); } else if (type === "properties") { - html = `
-
-
- - - - - -
-
` + html = getPropertiesHTML(data, tabRect); } - document.body.insertAdjacentHTML("beforeend", html); + document.body.insertAdjacentHTML("beforeend", `
${html}
`); avMenuPanel = document.querySelector(".av__panel"); avMenuPanel.addEventListener("click", (event) => { event.preventDefault(); - event.stopPropagation(); let target = event.target as HTMLElement; while (target && !target.isSameNode(avMenuPanel)) { const type = target.dataset.type; if (type === "close") { avMenuPanel.remove(); + event.stopPropagation(); + break; + } else if (type === "goConfig") { + avMenuPanel.innerHTML = getConfigHTML(data, tabRect); + event.stopPropagation(); + break; + } else if (type === "goProperties") { + avMenuPanel.innerHTML = getPropertiesHTML(data, tabRect); + event.stopPropagation(); + break; + } else if (type === "newCol") { + avMenuPanel.remove(); + const addMenu = addCol(protyle, blockElement); + addMenu.open({ + x: tabRect.right, + y: tabRect.bottom, + h: tabRect.height, + isLeft: true + }); + event.stopPropagation(); + break; + } else if (type === "showAllCol") { +// showAllCol(data); + avMenuPanel.innerHTML = getPropertiesHTML(data, tabRect); + event.stopPropagation(); + break; + } else if (type === "hideAllCol") { + + event.stopPropagation(); + break; + } else if (type === "hideCol") { + const colId = target.getAttribute("data-id"); + transaction(protyle, [{ + action: "setAttrViewColHidden", + id: colId, + parentID: avId, + data: true + }], [{ + action: "setAttrViewColHidden", + id: colId, + parentID: avId, + data: false + }]); + data.columns.find((item: IAVColumn) => item.id === colId).hidden = true; + avMenuPanel.innerHTML = getPropertiesHTML(data, tabRect); + event.stopPropagation(); + break; + } else if (type === "showCol") { + const colId = target.getAttribute("data-id"); + transaction(protyle, [{ + action: "setAttrViewColHidden", + id: colId, + parentID: avId, + data: false + }], [{ + action: "setAttrViewColHidden", + id: colId, + parentID: avId, + data: true + }]); + data.columns.find((item: IAVColumn) => item.id === colId).hidden = false; + avMenuPanel.innerHTML = getPropertiesHTML(data, tabRect); + event.stopPropagation(); break; } target = target.parentElement; @@ -101,3 +99,88 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type }); }); } + +const getConfigHTML = (data: IAV, tabRect: DOMRect) => { + return `
+
+ + + + + + +
` +} + +const getPropertiesHTML = (data: IAV, tabRect: DOMRect) => { + let showHTML = ""; + let hideHTML = ""; + data.columns.forEach((item: IAVColumn) => { + if (item.hidden) { + hideHTML += `` + } else { + showHTML += `` + } + }); + if (hideHTML) { + hideHTML = ` + +${hideHTML}`; + } + return `
+
+ + + + ${showHTML} + ${hideHTML} + + +
` +} diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 68d2158a5..dfbe7ffb6 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -823,6 +823,12 @@ interface IBazaarItem { preferredFunding: string } +interface IAV { + columns: IAVColumn[], + filters: [], + sorts: [], +} + interface IAVColumn { width: number, icon: string,