diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index c38b9cdf0..e042695e1 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -173,6 +173,7 @@ border-right: 1px solid var(--b3-theme-surface-lighter); display: flex; align-items: center; + transition: var(--b3-transition); [data-type="block-ref"] { display: none; diff --git a/app/src/protyle/hint/extend.ts b/app/src/protyle/hint/extend.ts index 7ff8c9368..c50b4b7ad 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: ["数据库", "属性视图", "shujuku", "shuxingshitu", "sjk", "sxst", "database", "attribute view"], value: '
', html: `
${window.siyuan.languages.database}
`, - }, */{ + }, { 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 f001953d0..de7f8fd78 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -297,6 +297,53 @@ export const updateAVName = (protyle: IProtyle, blockElement: Element) => { nameElement.dataset.title = nameElement.textContent.trim(); }; +export const addAttrViewColAnimation = (options: { + blockElement: Element, + protyle: IProtyle, + type: TAVCol, + name: string, + previousId?: string, + id: string +}) => { + if (!options.blockElement) { + return + } + options.blockElement.querySelectorAll(".av__row").forEach((item, index) => { + let previousElement + if (options.previousId) { + previousElement = item.querySelector(`[data-col-id="${options.previousId}"]`) + } else { + previousElement = item.lastElementChild.previousElementSibling; + } + let html = "" + if (index === 0) { + html = `
+
+ + ${options.name} +
+
+
` + } else { + html = '
' + } + previousElement.insertAdjacentHTML("afterend", html) + }) + window.siyuan.menus.menu.remove(); + showColMenu(options.protyle, options.blockElement, options.blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${options.id}"]`)); +}; + +export const updateAttrViewCellAnimation = (cellElement: HTMLElement) => { + cellElement.style.opacity = "0.38" + cellElement.style.backgroundColor = "var(--b3-theme-surface-light)"; +} + +export const removeAttrViewColAnimation = (blockElement: Element, id: string) => { + blockElement.querySelectorAll(`.av__cell[data-col-id="${id}"]`).forEach(item => { + item.remove(); + }) +} + export const insertAttrViewBlockAnimation = (blockElement: Element, size: number, previousId: string) => { const previousElement = blockElement.querySelector(`.av__row[data-id="${previousId}"]`) || blockElement.querySelector(`.av__row--header`); let colHTML = "" diff --git a/app/src/protyle/render/av/addCol.ts b/app/src/protyle/render/av/addCol.ts index 9ca209545..53760ff4a 100644 --- a/app/src/protyle/render/av/addCol.ts +++ b/app/src/protyle/render/av/addCol.ts @@ -1,7 +1,8 @@ import {Menu} from "../../../plugin/Menu"; import {transaction} from "../../wysiwyg/transaction"; +import {addAttrViewColAnimation} from "./action"; -export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { +export const addCol = (protyle: IProtyle, blockElement: Element) => { const menu = new Menu("av-header-add"); const avID = blockElement.getAttribute("data-av-id"); menu.addItem({ @@ -20,6 +21,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "text", + name: "Text", + id + }); } }); menu.addItem({ @@ -38,6 +46,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "number", + name: "Number", + id + }); } }); menu.addItem({ @@ -56,6 +71,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "select", + name: "Select", + id + }); } }); menu.addItem({ @@ -74,6 +96,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "mSelect", + name: "Multi-select", + id + }); } }); menu.addItem({ @@ -92,6 +121,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "date", + name: "Date", + id + }); } }); menu.addItem({ @@ -110,6 +146,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "url", + name: "URL", + id + }); } }); menu.addItem({ @@ -128,6 +171,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "email", + name: "Email", + id + }); } }); menu.addItem({ @@ -146,6 +196,13 @@ export const addCol = (protyle: IProtyle, blockElement: HTMLElement) => { id, avID, }]); + addAttrViewColAnimation({ + blockElement: blockElement, + protyle: protyle, + type: "phone", + name: "Phone", + id + }); } }); return menu; diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 8ed2b6a85..1ffacafc3 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 {openMenuPanel} from "./openMenuPanel"; import {Menu} from "../../../plugin/Menu"; +import {updateAttrViewCellAnimation} from "./action"; export const getCalcValue = (column: IAVColumn) => { if (!column.calc || !column.calc.result) { @@ -439,6 +440,7 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem [type]: oldValue } }); + updateAttrViewCellAnimation(item); }); transaction(protyle, doOperations, undoOperations); setTimeout(() => { diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts index a38131cb7..5e7d11df2 100644 --- a/app/src/protyle/render/av/col.ts +++ b/app/src/protyle/render/av/col.ts @@ -6,6 +6,7 @@ import {getDefaultOperatorByType, setFilter} from "./filter"; import {genCellValue} from "./cell"; import {openMenuPanel} from "./openMenuPanel"; import {getLabelByNumberFormat} from "./number"; +import {addAttrViewColAnimation, removeAttrViewColAnimation} from "./action"; export const duplicateCol = (options: { protyle: IProtyle, @@ -72,6 +73,14 @@ export const duplicateCol = (options: { avID: options.avID, }]); } + addAttrViewColAnimation({ + blockElement: options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.nodeID}"]`), + protyle: options.protyle, + type: options.type, + name: options.newValue, + previousId: options.colId, + id + }); }; export const getEditHTML = (options: { @@ -274,7 +283,7 @@ export const updateHeader = (rowElement: HTMLElement) => { avHeadElement.style.position = "sticky"; }; -export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellElement: HTMLElement) => { +export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElement: HTMLElement) => { const type = cellElement.getAttribute("data-dtype") as TAVCol; const colId = cellElement.getAttribute("data-col-id"); const avID = blockElement.getAttribute("data-av-id"); @@ -405,7 +414,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl filter, protyle, data: avData, - target: cellElement, + target: blockElement.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`), }); }); } @@ -458,6 +467,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl type: type, id: colId }]); + removeAttrViewColAnimation(blockElement, colId) } }); menu.addSeparator(); diff --git a/app/src/protyle/render/av/date.ts b/app/src/protyle/render/av/date.ts index 5ba718f3a..8b68c23da 100644 --- a/app/src/protyle/render/av/date.ts +++ b/app/src/protyle/render/av/date.ts @@ -1,5 +1,6 @@ import {transaction} from "../../wysiwyg/transaction"; import * as dayjs from "dayjs"; +import {updateAttrViewCellAnimation} from "./action"; export const getDateHTML = (data: IAVTable, cellElements: HTMLElement[]) => { let hasEndDate = true; @@ -152,6 +153,7 @@ export const setDateValue = (options: { date: oldValue } }); + updateAttrViewCellAnimation(item); }); transaction(options.protyle, cellDoOperations, cellUndoOperations); }; diff --git a/app/src/protyle/render/av/openMenuPanel.ts b/app/src/protyle/render/av/openMenuPanel.ts index 0e4c0bdd9..c4b16493f 100644 --- a/app/src/protyle/render/av/openMenuPanel.ts +++ b/app/src/protyle/render/av/openMenuPanel.ts @@ -9,10 +9,11 @@ import {addFilter, getFiltersHTML, setFilter} from "./filter"; import {addSort, bindSortsEvent, getSortsHTML} from "./sort"; import {bindDateEvent, getDateHTML, setDateValue} from "./date"; import {formatNumber} from "./number"; +import {removeAttrViewColAnimation} from "./action"; export const openMenuPanel = (options: { protyle: IProtyle, - blockElement: HTMLElement, + blockElement: Element, type: "select" | "properties" | "config" | "sorts" | "filters" | "edit" | "date", colId?: string, // for edit cellElements?: HTMLElement[] // for select & date @@ -608,6 +609,7 @@ export const openMenuPanel = (options: { type: colData.type, id: colId }]); + removeAttrViewColAnimation(options.blockElement, colId); avPanelElement.remove(); event.preventDefault(); event.stopPropagation(); diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index 7d8a95347..593b7a73f 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -171,14 +171,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => { lastElement = protyle.contentElement; lastParentID = operation.parentID; const avId = operation.avID; - if (operation.action === "addAttrViewCol") { - Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => { - item.removeAttribute("data-render"); - avRender(item, protyle, () => { - showColMenu(protyle, item, item.querySelector(`.av__row--header .av__cell[data-col-id="${operation.id}"]`)); - }); - }); - } else if (operation.action === "setAttrViewColWidth") { + if (operation.action === "setAttrViewColWidth") { Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => { const cellElement = item.querySelector(`.av__cell[data-col-id="${operation.id}"]`) as HTMLElement; if (!cellElement || cellElement.style.width === operation.data) { diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index 2f9cd6dcb..620d4f25a 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -4,6 +4,7 @@ import {hasClosestByClassName} from "../../util/hasClosest"; import {confirmDialog} from "../../../dialog/confirmDialog"; import {upDownHint} from "../../../util/upDownHint"; import {bindEditEvent, getEditHTML} from "./col"; +import {updateAttrViewCellAnimation} from "./action"; const filterSelectHTML = (key: string, options: { name: string, color: string }[]) => { let html = ""; @@ -91,6 +92,7 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM mSelect: oldValue } }); + updateAttrViewCellAnimation(item); }); transaction(protyle, doOperations, undoOperations); target.remove(); @@ -460,6 +462,7 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H [colData.type]: oldValue } }); + updateAttrViewCellAnimation(item); }); if (currentElement.querySelector(".b3-menu__accelerator")) {