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}
`,
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 = ``
+ } 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")) {