2023-06-10 16:27:52 +08:00
|
|
|
|
import {transaction} from "../../wysiwyg/transaction";
|
2023-06-30 11:11:45 +08:00
|
|
|
|
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
|
2023-07-09 23:54:32 +08:00
|
|
|
|
import {openMenuPanel} from "./openMenuPanel";
|
2023-09-21 10:54:17 +08:00
|
|
|
|
import {updateAttrViewCellAnimation} from "./action";
|
2023-12-15 12:30:57 +08:00
|
|
|
|
import {isNotCtrl} from "../../util/compatibility";
|
2024-03-28 23:34:11 +08:00
|
|
|
|
import {isDynamicRef, objEquals} from "../../../util/functions";
|
2023-10-13 11:30:44 +08:00
|
|
|
|
import {fetchPost} from "../../../util/fetch";
|
2023-12-26 22:33:04 +08:00
|
|
|
|
import {focusBlock, focusByRange} from "../../util/selection";
|
2023-10-14 11:04:23 +08:00
|
|
|
|
import * as dayjs from "dayjs";
|
2023-12-18 20:47:22 +08:00
|
|
|
|
import {unicode2Emoji} from "../../../emoji";
|
2025-06-14 14:03:35 +08:00
|
|
|
|
import {getColIconByType, getColId} from "./col";
|
2023-12-25 00:20:51 +08:00
|
|
|
|
import {genAVValueHTML} from "./blockAttr";
|
2023-12-26 22:33:04 +08:00
|
|
|
|
import {Constants} from "../../../constants";
|
|
|
|
|
|
import {hintRef} from "../../hint/extend";
|
2025-02-08 17:26:11 +08:00
|
|
|
|
import {getAssetName, pathPosix} from "../../../util/pathName";
|
2024-05-17 18:02:15 +08:00
|
|
|
|
import {mergeAddOption} from "./select";
|
2024-11-18 16:23:38 +08:00
|
|
|
|
import {escapeAttr, escapeHtml} from "../../../util/escape";
|
2024-06-16 16:01:52 +08:00
|
|
|
|
import {electronUndo} from "../../undo";
|
2025-06-14 14:03:35 +08:00
|
|
|
|
import {getFieldIdByCellElement} from "./row";
|
|
|
|
|
|
import {getFieldsByData} from "./view";
|
2025-07-09 23:02:20 +08:00
|
|
|
|
import {getCompressURL, removeCompressURL} from "../../../util/image";
|
2023-06-10 12:22:10 +08:00
|
|
|
|
|
2024-03-28 10:05:06 +08:00
|
|
|
|
const renderCellURL = (urlContent: string) => {
|
|
|
|
|
|
let host = urlContent;
|
2024-03-29 09:47:40 +08:00
|
|
|
|
let suffix = "";
|
2024-03-28 10:05:06 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const urlObj = new URL(urlContent);
|
2024-03-31 09:58:50 +08:00
|
|
|
|
if (urlObj.protocol.startsWith("http")) {
|
|
|
|
|
|
host = urlObj.host;
|
|
|
|
|
|
suffix = urlObj.href.replace(urlObj.origin, "");
|
|
|
|
|
|
if (suffix.length > 12) {
|
|
|
|
|
|
suffix = suffix.substring(0, 4) + "..." + suffix.substring(suffix.length - 6);
|
|
|
|
|
|
}
|
2024-03-28 10:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
// 不是 url 地址
|
2024-05-22 22:56:06 +08:00
|
|
|
|
host = Lute.EscapeHTMLStr(urlContent);
|
2024-03-28 10:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/9291
|
2024-05-22 22:56:06 +08:00
|
|
|
|
return `<span class="av__celltext av__celltext--url" data-type="url" data-href="${escapeAttr(urlContent)}"><span>${host}</span><span class="ft__on-surface">${suffix}</span></span>`;
|
2024-03-28 10:05:06 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-12-15 12:04:18 +08:00
|
|
|
|
export const getCellText = (cellElement: HTMLElement | false) => {
|
|
|
|
|
|
if (!cellElement) {
|
2023-12-15 12:30:57 +08:00
|
|
|
|
return "";
|
2023-12-15 12:04:18 +08:00
|
|
|
|
}
|
2023-12-17 16:24:11 +08:00
|
|
|
|
let cellText = "";
|
2024-01-14 12:09:42 +08:00
|
|
|
|
const textElements = cellElement.querySelectorAll(".b3-chip, .av__celltext--ref, .av__celltext");
|
|
|
|
|
|
if (textElements.length > 0) {
|
|
|
|
|
|
textElements.forEach(item => {
|
|
|
|
|
|
if (item.querySelector(".av__cellicon")) {
|
|
|
|
|
|
cellText += `${item.firstChild.textContent} → ${item.lastChild.textContent}, `;
|
2024-03-28 18:26:35 +08:00
|
|
|
|
} else if (item.getAttribute("data-type") === "url") {
|
|
|
|
|
|
cellText = item.getAttribute("data-href") + ", ";
|
2024-01-14 12:09:42 +08:00
|
|
|
|
} else if (item.getAttribute("data-type") !== "block-more") {
|
|
|
|
|
|
cellText += item.textContent + ", ";
|
|
|
|
|
|
}
|
2024-01-14 16:38:45 +08:00
|
|
|
|
});
|
2024-01-14 12:09:42 +08:00
|
|
|
|
cellText = cellText.substring(0, cellText.length - 2);
|
2023-12-15 12:04:18 +08:00
|
|
|
|
} else {
|
2023-12-15 12:30:57 +08:00
|
|
|
|
cellText = cellElement.textContent;
|
2023-12-15 12:04:18 +08:00
|
|
|
|
}
|
2023-12-15 12:30:57 +08:00
|
|
|
|
return cellText;
|
|
|
|
|
|
};
|
2023-12-15 12:04:18 +08:00
|
|
|
|
|
2023-12-29 12:55:26 +08:00
|
|
|
|
export const genCellValueByElement = (colType: TAVCol, cellElement: HTMLElement) => {
|
|
|
|
|
|
const cellValue: IAVCellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
id: cellElement.dataset.id,
|
|
|
|
|
|
};
|
2023-12-15 12:04:18 +08:00
|
|
|
|
if (colType === "number") {
|
2023-12-17 16:24:11 +08:00
|
|
|
|
const value = cellElement.querySelector(".av__celltext").getAttribute("data-content");
|
2023-12-29 12:55:26 +08:00
|
|
|
|
cellValue.number = {
|
|
|
|
|
|
content: parseFloat(value) || 0,
|
|
|
|
|
|
isNotEmpty: !!value
|
2023-12-15 12:04:18 +08:00
|
|
|
|
};
|
|
|
|
|
|
} else if (["text", "block", "url", "phone", "email", "template"].includes(colType)) {
|
2024-01-14 22:06:03 +08:00
|
|
|
|
const textElement = cellElement.querySelector(".av__celltext") as HTMLElement;
|
2023-12-29 12:55:26 +08:00
|
|
|
|
cellValue[colType as "text"] = {
|
2024-03-28 10:05:06 +08:00
|
|
|
|
content: colType === "url" ? textElement.dataset.href : textElement.textContent
|
2023-12-15 12:04:18 +08:00
|
|
|
|
};
|
2024-01-14 22:06:03 +08:00
|
|
|
|
if (colType === "block" && textElement.dataset.id) {
|
|
|
|
|
|
cellValue.block.id = textElement.dataset.id;
|
2024-12-24 16:19:55 +08:00
|
|
|
|
if (textElement.previousElementSibling?.classList.contains("b3-menu__avemoji")) {
|
2025-03-16 11:57:00 +08:00
|
|
|
|
const unicode = textElement.previousElementSibling.getAttribute("data-unicode");
|
2025-03-14 11:05:49 +08:00
|
|
|
|
if (unicode) {
|
|
|
|
|
|
cellValue.block.icon = unicode;
|
|
|
|
|
|
}
|
2024-12-23 20:55:11 +08:00
|
|
|
|
}
|
2024-01-14 22:06:03 +08:00
|
|
|
|
}
|
2023-12-15 12:04:18 +08:00
|
|
|
|
} else if (colType === "mSelect" || colType === "select") {
|
2023-12-17 16:24:11 +08:00
|
|
|
|
const mSelect: IAVCellSelectValue[] = [];
|
2023-12-15 12:04:18 +08:00
|
|
|
|
cellElement.querySelectorAll(".b3-chip").forEach((item: HTMLElement) => {
|
|
|
|
|
|
mSelect.push({
|
|
|
|
|
|
content: item.textContent.trim(),
|
|
|
|
|
|
color: item.style.color.replace("var(--b3-font-color", "").replace(")", "")
|
2023-12-17 16:24:11 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2023-12-29 12:55:26 +08:00
|
|
|
|
cellValue.mSelect = mSelect;
|
2023-12-15 12:04:18 +08:00
|
|
|
|
} else if (["date", "created", "updated"].includes(colType)) {
|
2023-12-29 15:00:36 +08:00
|
|
|
|
cellValue[colType as "date"] = JSON.parse(cellElement.querySelector(".av__celltext").getAttribute("data-value"));
|
2023-12-17 00:02:47 +08:00
|
|
|
|
} else if (colType === "checkbox") {
|
2023-12-29 12:55:26 +08:00
|
|
|
|
cellValue.checkbox = {
|
|
|
|
|
|
checked: cellElement.querySelector("use").getAttribute("xlink:href") === "#iconCheck" ? true : false
|
2023-12-17 00:02:47 +08:00
|
|
|
|
};
|
2023-12-24 23:24:35 +08:00
|
|
|
|
} else if (colType === "relation") {
|
2024-03-07 17:44:25 +08:00
|
|
|
|
const blockIDs: string[] = [];
|
|
|
|
|
|
const contents: IAVCellValue[] = [];
|
2025-01-04 22:31:24 +08:00
|
|
|
|
Array.from(cellElement.querySelectorAll(".av__cell--relation")).forEach((relationItem: HTMLElement) => {
|
|
|
|
|
|
const item = relationItem.querySelector(".av__celltext") as HTMLElement;
|
2025-08-12 01:23:47 +08:00
|
|
|
|
blockIDs.push(relationItem.dataset.rowId);
|
2024-03-07 17:44:25 +08:00
|
|
|
|
contents.push({
|
|
|
|
|
|
isDetached: !item.classList.contains("av__celltext--ref"),
|
|
|
|
|
|
block: {
|
|
|
|
|
|
content: item.textContent,
|
|
|
|
|
|
id: item.dataset.id,
|
|
|
|
|
|
},
|
2024-03-07 23:40:57 +08:00
|
|
|
|
type: "block"
|
2024-03-07 17:44:25 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2023-12-29 12:55:26 +08:00
|
|
|
|
cellValue.relation = {
|
2024-03-07 17:44:25 +08:00
|
|
|
|
blockIDs,
|
|
|
|
|
|
contents
|
2023-12-24 16:54:15 +08:00
|
|
|
|
};
|
2023-12-27 00:18:49 +08:00
|
|
|
|
} else if (colType === "mAsset") {
|
2023-12-29 15:00:36 +08:00
|
|
|
|
const mAsset: IAVCellAssetValue[] = [];
|
2023-12-27 00:18:49 +08:00
|
|
|
|
Array.from(cellElement.children).forEach((item) => {
|
2025-06-25 13:22:04 +08:00
|
|
|
|
if (!item.classList.contains("av__celltext--url") && !item.classList.contains("av__cellassetimg")) {
|
2024-01-27 22:06:22 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-12-29 15:00:36 +08:00
|
|
|
|
const isImg = item.classList.contains("av__cellassetimg");
|
2023-12-27 00:18:49 +08:00
|
|
|
|
mAsset.push({
|
|
|
|
|
|
type: isImg ? "image" : "file",
|
2025-07-09 23:02:20 +08:00
|
|
|
|
content: isImg ? removeCompressURL(item.getAttribute("src")) : item.getAttribute("data-url"),
|
2024-05-20 10:56:25 +08:00
|
|
|
|
name: isImg ? "" : item.getAttribute("data-name")
|
2023-12-29 15:00:36 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
cellValue.mAsset = mAsset;
|
2023-12-15 12:04:18 +08:00
|
|
|
|
}
|
2023-12-18 12:53:52 +08:00
|
|
|
|
if (colType === "block") {
|
|
|
|
|
|
cellValue.isDetached = cellElement.dataset.detached === "true";
|
|
|
|
|
|
}
|
2023-12-15 12:04:18 +08:00
|
|
|
|
return cellValue;
|
2023-12-17 16:24:11 +08:00
|
|
|
|
};
|
2023-12-15 12:04:18 +08:00
|
|
|
|
|
2025-05-09 20:27:53 +08:00
|
|
|
|
const getCellValueContent = (value: IAVCellValue): string => {
|
|
|
|
|
|
if (["number", "text", "block", "url", "phone", "email", "template", "mAsset"].includes(value.type)) {
|
|
|
|
|
|
return value[value.type as "text"].content;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (["mSelect", "select"].includes(value.type)) {
|
|
|
|
|
|
return value.mSelect[0].content;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "rollup") {
|
|
|
|
|
|
return getCellValueContent(value.relation.contents[0]);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "checkbox") {
|
|
|
|
|
|
return value.checkbox.checked ? "true" : "false";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "relation") {
|
|
|
|
|
|
return getCellValueContent(value.relation.contents[0]);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (["date", "created", "updated"].includes(value.type)) {
|
|
|
|
|
|
return dayjs(value[value.type as "date"].content).format("YYYY-MM-DD HH:mm");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "lineNumber") {
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const transformCellValue = (colType: TAVCol, value: IAVCellValue): IAVCellValue => {
|
|
|
|
|
|
if (colType === value.type) {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
const newValue: IAVCellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
};
|
|
|
|
|
|
if (colType === "number") {
|
|
|
|
|
|
if (["date", "created", "updated"].includes(colType)) {
|
|
|
|
|
|
newValue.number = {
|
|
|
|
|
|
content: value[value.type as "date"].content,
|
|
|
|
|
|
isNotEmpty: value[value.type as "date"].isNotEmpty
|
|
|
|
|
|
};
|
|
|
|
|
|
} else {
|
|
|
|
|
|
newValue.number = {
|
|
|
|
|
|
content: parseFloat(getCellValueContent(value)) || 0,
|
|
|
|
|
|
isNotEmpty: true
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (["text", "block", "url", "phone", "email", "template"].includes(colType)) {
|
|
|
|
|
|
newValue[colType as "text"] = {
|
2025-07-03 11:14:40 +08:00
|
|
|
|
content: getCellValueContent(value).toString()
|
2025-05-09 20:27:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
} else if (colType === "mSelect" || colType === "select") {
|
|
|
|
|
|
newValue.mSelect = [{
|
2025-07-03 11:14:40 +08:00
|
|
|
|
content: getCellValueContent(value).toString(),
|
2025-05-09 20:27:53 +08:00
|
|
|
|
color: "1"
|
|
|
|
|
|
}];
|
2025-08-12 23:37:32 +08:00
|
|
|
|
if (!newValue.mSelect[0].content) {
|
|
|
|
|
|
newValue.mSelect = [];
|
|
|
|
|
|
}
|
2025-05-09 20:27:53 +08:00
|
|
|
|
} else if (colType === "rollup") {
|
|
|
|
|
|
newValue.rollup = {contents: [value]};
|
|
|
|
|
|
} else if (colType === "checkbox") {
|
|
|
|
|
|
newValue.checkbox = {
|
|
|
|
|
|
checked: true
|
|
|
|
|
|
};
|
|
|
|
|
|
} else if (colType === "relation") {
|
|
|
|
|
|
if (value.type === "block") {
|
|
|
|
|
|
newValue.relation = {
|
2025-08-11 23:45:35 +08:00
|
|
|
|
blockIDs: [value.blockID],
|
2025-05-09 20:27:53 +08:00
|
|
|
|
contents: [value]
|
|
|
|
|
|
};
|
|
|
|
|
|
} else {
|
|
|
|
|
|
newValue.relation = {blockIDs: [], contents: []};
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (colType === "mAsset") {
|
2025-07-03 11:14:40 +08:00
|
|
|
|
const content = getCellValueContent(value).toString();
|
2025-05-09 20:27:53 +08:00
|
|
|
|
newValue.mAsset = [{
|
|
|
|
|
|
type: Constants.SIYUAN_ASSETS_IMAGE.includes(pathPosix().extname(content).toLowerCase()) ? "image" : "file",
|
|
|
|
|
|
content,
|
|
|
|
|
|
name: "",
|
|
|
|
|
|
}];
|
|
|
|
|
|
} else if (["date", "created", "updated"].includes(colType)) {
|
|
|
|
|
|
if (["date", "created", "updated"].includes(value.type)) {
|
|
|
|
|
|
newValue[colType as "date"] = JSON.parse(JSON.stringify(value[value.type as "date"]));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
newValue[colType as "date"] = {
|
|
|
|
|
|
content: null,
|
|
|
|
|
|
isNotEmpty: false,
|
|
|
|
|
|
content2: null,
|
|
|
|
|
|
isNotEmpty2: false,
|
|
|
|
|
|
hasEndDate: false,
|
|
|
|
|
|
isNotTime: true,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (colType === "lineNumber") {
|
|
|
|
|
|
return {
|
|
|
|
|
|
type: "lineNumber"
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
return newValue;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-09-22 20:24:00 +08:00
|
|
|
|
export const genCellValue = (colType: TAVCol, value: string | any) => {
|
2023-12-27 00:47:25 +08:00
|
|
|
|
let cellValue: IAVCellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
[colType === "select" ? "mSelect" : colType]: value as IAVCellDateValue
|
|
|
|
|
|
};
|
2024-04-12 16:04:05 +08:00
|
|
|
|
if (typeof value === "string" && value) {
|
2023-07-13 23:48:05 +08:00
|
|
|
|
if (colType === "number") {
|
2023-12-27 00:47:25 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
number: {
|
|
|
|
|
|
content: parseFloat(value) || 0,
|
|
|
|
|
|
isNotEmpty: true
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2023-10-09 09:52:40 +08:00
|
|
|
|
} else if (["text", "block", "url", "phone", "email", "template"].includes(colType)) {
|
2023-07-13 23:48:05 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-08-02 14:27:49 +08:00
|
|
|
|
[colType]: {
|
2024-05-22 22:56:06 +08:00
|
|
|
|
content: value
|
2023-07-13 23:48:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
} else if (colType === "mSelect" || colType === "select") {
|
2023-07-27 00:47:14 +08:00
|
|
|
|
cellValue = {
|
2023-07-13 23:48:05 +08:00
|
|
|
|
type: colType,
|
|
|
|
|
|
mSelect: [{
|
|
|
|
|
|
content: value,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
color: "1"
|
2023-07-13 23:48:05 +08:00
|
|
|
|
}]
|
|
|
|
|
|
};
|
2023-12-17 00:02:47 +08:00
|
|
|
|
} else if (colType === "checkbox") {
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
checkbox: {
|
2023-12-27 00:47:25 +08:00
|
|
|
|
checked: true
|
2023-12-17 00:02:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
2024-01-28 00:08:41 +08:00
|
|
|
|
} else if (colType === "date") {
|
2024-09-14 11:40:00 +08:00
|
|
|
|
let values = value.split("→");
|
|
|
|
|
|
if (values.length !== 2) {
|
|
|
|
|
|
values = value.split("-");
|
|
|
|
|
|
if (values.length !== 2) {
|
|
|
|
|
|
values = value.split("~");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
const dateObj1 = dayjs(values[0]);
|
|
|
|
|
|
const dateObj2 = dayjs(values[1] || "");
|
|
|
|
|
|
if (isNaN(dateObj1.valueOf())) {
|
2024-09-12 11:40:09 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
date: {
|
|
|
|
|
|
content: null,
|
|
|
|
|
|
isNotEmpty: false,
|
|
|
|
|
|
content2: null,
|
|
|
|
|
|
isNotEmpty2: false,
|
|
|
|
|
|
formattedContent: "",
|
|
|
|
|
|
hasEndDate: false,
|
|
|
|
|
|
isNotTime: true,
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
date: {
|
2024-09-14 11:40:00 +08:00
|
|
|
|
content: dateObj1.valueOf(),
|
2024-09-12 11:40:09 +08:00
|
|
|
|
isNotEmpty: true,
|
2024-09-14 11:40:00 +08:00
|
|
|
|
content2: dateObj2.valueOf() || 0,
|
|
|
|
|
|
isNotEmpty2: !isNaN(dateObj2.valueOf()),
|
|
|
|
|
|
hasEndDate: !isNaN(dateObj2.valueOf()),
|
|
|
|
|
|
isNotTime: dateObj1.hour() === 0,
|
2024-09-12 11:40:09 +08:00
|
|
|
|
formattedContent: "",
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2024-02-16 10:54:18 +08:00
|
|
|
|
} else if (colType === "relation") {
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2024-03-07 17:44:25 +08:00
|
|
|
|
relation: {blockIDs: [value], contents: []}
|
2024-02-16 10:54:18 +08:00
|
|
|
|
};
|
2024-04-12 16:04:05 +08:00
|
|
|
|
} else if (colType === "mAsset") {
|
|
|
|
|
|
const type = pathPosix().extname(value).toLowerCase();
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
mAsset: [{
|
|
|
|
|
|
type: Constants.SIYUAN_ASSETS_IMAGE.includes(type) ? "image" : "file",
|
|
|
|
|
|
content: value,
|
|
|
|
|
|
name: "",
|
|
|
|
|
|
}]
|
|
|
|
|
|
};
|
2023-12-27 00:47:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else if (typeof value === "undefined" || !value) {
|
|
|
|
|
|
if (colType === "number") {
|
2023-12-27 00:18:49 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
number: {
|
2024-01-03 00:21:26 +08:00
|
|
|
|
content: null,
|
|
|
|
|
|
isNotEmpty: false
|
2023-12-27 00:47:25 +08:00
|
|
|
|
}
|
2023-12-27 00:18:49 +08:00
|
|
|
|
};
|
2023-12-27 00:47:25 +08:00
|
|
|
|
} else if (["text", "block", "url", "phone", "email", "template"].includes(colType)) {
|
2023-07-27 00:47:14 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
[colType]: {
|
|
|
|
|
|
content: ""
|
|
|
|
|
|
}
|
2023-07-27 00:47:14 +08:00
|
|
|
|
};
|
2023-12-27 00:47:25 +08:00
|
|
|
|
} else if (colType === "mSelect" || colType === "select" || colType === "mAsset") {
|
2023-07-27 00:47:14 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
[colType === "select" ? "mSelect" : colType]: []
|
2023-07-27 00:47:14 +08:00
|
|
|
|
};
|
2023-12-27 00:47:25 +08:00
|
|
|
|
} else if (["date", "created", "updated"].includes(colType)) {
|
2023-09-22 20:24:00 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
[colType]: {
|
|
|
|
|
|
content: null,
|
|
|
|
|
|
isNotEmpty: false,
|
|
|
|
|
|
content2: null,
|
|
|
|
|
|
isNotEmpty2: false,
|
|
|
|
|
|
hasEndDate: false,
|
|
|
|
|
|
isNotTime: true,
|
|
|
|
|
|
}
|
2023-09-22 20:24:00 +08:00
|
|
|
|
};
|
2023-11-20 11:12:02 +08:00
|
|
|
|
} else if (colType === "checkbox") {
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
checkbox: {
|
2023-12-27 00:47:25 +08:00
|
|
|
|
checked: false
|
2023-07-15 22:24:54 +08:00
|
|
|
|
}
|
2023-11-20 11:12:02 +08:00
|
|
|
|
};
|
2023-12-24 23:24:35 +08:00
|
|
|
|
} else if (colType === "relation") {
|
2023-12-24 16:54:15 +08:00
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
2023-12-27 00:47:25 +08:00
|
|
|
|
relation: {blockIDs: [], contents: []}
|
2023-12-24 16:54:15 +08:00
|
|
|
|
};
|
2024-03-07 09:15:15 +08:00
|
|
|
|
} else if (colType === "rollup") {
|
|
|
|
|
|
cellValue = {
|
|
|
|
|
|
type: colType,
|
|
|
|
|
|
rollup: {contents: []}
|
|
|
|
|
|
};
|
2023-07-15 22:24:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-18 12:06:01 +08:00
|
|
|
|
if (colType === "block") {
|
2025-08-03 11:10:58 +08:00
|
|
|
|
if (typeof value === "object" && value && value.id) {
|
2024-12-23 16:21:59 +08:00
|
|
|
|
cellValue.isDetached = false;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cellValue.isDetached = true;
|
|
|
|
|
|
}
|
2023-12-18 12:06:01 +08:00
|
|
|
|
}
|
2023-11-20 11:12:02 +08:00
|
|
|
|
return cellValue;
|
2023-07-15 23:19:40 +08:00
|
|
|
|
};
|
2023-07-15 22:24:54 +08:00
|
|
|
|
|
2023-11-14 12:58:45 +08:00
|
|
|
|
export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Element, onlyHeight = true) => {
|
|
|
|
|
|
const cellRect = cellElement.getBoundingClientRect();
|
2023-10-13 21:50:14 +08:00
|
|
|
|
if (!onlyHeight) {
|
|
|
|
|
|
const avScrollElement = blockElement.querySelector(".av__scroll");
|
2024-12-06 10:06:56 +08:00
|
|
|
|
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
|
|
|
|
|
if (avScrollElement && rowElement) {
|
|
|
|
|
|
const stickyElement = rowElement.querySelector(".av__colsticky");
|
|
|
|
|
|
if (!stickyElement.contains(cellElement)) { // https://github.com/siyuan-note/siyuan/issues/12162
|
|
|
|
|
|
const stickyRight = stickyElement.getBoundingClientRect().right;
|
|
|
|
|
|
const avScrollRect = avScrollElement.getBoundingClientRect();
|
|
|
|
|
|
if (stickyRight > cellRect.left || avScrollRect.right < cellRect.left) {
|
|
|
|
|
|
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - stickyRight;
|
|
|
|
|
|
} else if (stickyRight < cellRect.left && avScrollRect.right < cellRect.right) {
|
|
|
|
|
|
if (cellRect.width + stickyRight > avScrollRect.right) {
|
|
|
|
|
|
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - stickyRight;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
|
2023-11-14 12:58:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-13 21:50:14 +08:00
|
|
|
|
}
|
2023-10-13 12:33:29 +08:00
|
|
|
|
}
|
2024-10-09 12:31:56 +08:00
|
|
|
|
/// #if MOBILE
|
|
|
|
|
|
const contentElement = hasClosestByClassName(blockElement, "protyle-content", true);
|
2024-10-09 22:32:47 +08:00
|
|
|
|
if (contentElement && cellElement.getAttribute("data-dtype") !== "checkbox") {
|
2024-10-12 12:34:59 +08:00
|
|
|
|
const keyboardToolbarElement = document.getElementById("keyboardToolbar");
|
|
|
|
|
|
const keyboardH = parseInt(keyboardToolbarElement.getAttribute("data-keyboardheight")) || (window.outerHeight / 2 - 42);
|
2024-10-09 22:32:47 +08:00
|
|
|
|
if (cellRect.bottom > window.innerHeight - keyboardH - 42) {
|
|
|
|
|
|
contentElement.scrollTop += cellRect.bottom - window.innerHeight + 42 + keyboardH;
|
|
|
|
|
|
} else if (cellRect.top < 110) {
|
|
|
|
|
|
contentElement.scrollTop -= 110 - cellRect.top;
|
|
|
|
|
|
}
|
2024-10-09 12:31:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
/// #else
|
2023-10-27 23:31:39 +08:00
|
|
|
|
if (!blockElement.querySelector(".av__header")) {
|
|
|
|
|
|
// 属性面板
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-08-23 22:27:42 +08:00
|
|
|
|
const bodyElement = hasClosestByClassName(cellElement, "av__body");
|
|
|
|
|
|
if (!bodyElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const avHeaderRect = bodyElement.querySelector(".av__row--header").getBoundingClientRect();
|
2023-10-13 12:33:29 +08:00
|
|
|
|
if (avHeaderRect.bottom > cellRect.top) {
|
2023-10-13 21:50:14 +08:00
|
|
|
|
const contentElement = hasClosestByClassName(blockElement, "protyle-content", true);
|
2023-10-13 12:33:29 +08:00
|
|
|
|
if (contentElement) {
|
|
|
|
|
|
contentElement.scrollTop = contentElement.scrollTop + cellRect.top - avHeaderRect.bottom;
|
|
|
|
|
|
}
|
2023-10-13 21:50:14 +08:00
|
|
|
|
} else {
|
2025-08-23 22:27:42 +08:00
|
|
|
|
const footerElement = bodyElement.querySelector(".av__row--footer");
|
2025-07-26 22:50:24 +08:00
|
|
|
|
if (footerElement?.querySelector(".av__calc--ashow")) {
|
2024-01-04 17:05:24 +08:00
|
|
|
|
const avFooterRect = footerElement.getBoundingClientRect();
|
|
|
|
|
|
if (avFooterRect.top < cellRect.bottom) {
|
|
|
|
|
|
const contentElement = hasClosestByClassName(blockElement, "protyle-content", true);
|
|
|
|
|
|
if (contentElement) {
|
|
|
|
|
|
contentElement.scrollTop = contentElement.scrollTop + cellRect.bottom - avFooterRect.top;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2023-10-13 21:50:14 +08:00
|
|
|
|
const contentElement = hasClosestByClassName(blockElement, "protyle-content", true);
|
|
|
|
|
|
if (contentElement) {
|
2024-02-04 12:19:46 +08:00
|
|
|
|
const contentRect = contentElement.getBoundingClientRect();
|
|
|
|
|
|
if (cellRect.bottom > contentRect.bottom) {
|
2025-03-24 18:16:02 +08:00
|
|
|
|
contentElement.scrollTop = contentElement.scrollTop + (cellRect.bottom - contentRect.bottom);
|
2024-01-04 17:05:24 +08:00
|
|
|
|
}
|
2023-10-13 21:50:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-10-13 12:33:29 +08:00
|
|
|
|
}
|
2024-10-09 12:31:56 +08:00
|
|
|
|
/// #endif
|
2023-10-21 23:49:28 +08:00
|
|
|
|
};
|
2023-10-13 12:33:29 +08:00
|
|
|
|
|
2023-11-14 12:58:45 +08:00
|
|
|
|
export const getTypeByCellElement = (cellElement: Element) => {
|
2025-08-21 10:50:42 +08:00
|
|
|
|
if (cellElement.parentElement.classList.contains("av__gallery-field")) {
|
2025-06-14 09:48:25 +08:00
|
|
|
|
return cellElement.getAttribute("data-dtype") as TAVCol;
|
|
|
|
|
|
}
|
2023-11-14 23:18:18 +08:00
|
|
|
|
const scrollElement = hasClosestByClassName(cellElement, "av__scroll");
|
2023-11-14 12:58:45 +08:00
|
|
|
|
if (!scrollElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
return scrollElement.querySelector(".av__row--header").querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
2023-11-14 23:18:18 +08:00
|
|
|
|
};
|
2023-11-14 12:58:45 +08:00
|
|
|
|
|
2023-09-24 17:53:28 +08:00
|
|
|
|
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type?: TAVCol) => {
|
2023-12-13 16:58:24 +08:00
|
|
|
|
if (cellElements.length === 0 || (cellElements.length === 1 && !cellElements[0])) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-09-24 17:53:28 +08:00
|
|
|
|
if (!type) {
|
2023-11-14 23:18:18 +08:00
|
|
|
|
type = getTypeByCellElement(cellElements[0]);
|
2023-09-24 17:53:28 +08:00
|
|
|
|
}
|
2023-12-13 16:58:24 +08:00
|
|
|
|
if (type === "updated" || type === "created" || document.querySelector(".av__mask")) {
|
2023-10-01 17:41:00 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-10-13 09:37:24 +08:00
|
|
|
|
const blockElement = hasClosestBlock(cellElements[0]);
|
2024-01-04 12:46:57 +08:00
|
|
|
|
if (!blockElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-06-14 09:48:25 +08:00
|
|
|
|
const viewType = blockElement.getAttribute("data-av-type") as TAVView;
|
2023-10-13 09:37:24 +08:00
|
|
|
|
let cellRect = cellElements[0].getBoundingClientRect();
|
2024-01-04 12:46:57 +08:00
|
|
|
|
const contentElement = hasClosestByClassName(blockElement, "protyle-content", true);
|
2025-06-14 09:48:25 +08:00
|
|
|
|
if (viewType === "table") {
|
|
|
|
|
|
cellScrollIntoView(blockElement, cellElements[0], false);
|
|
|
|
|
|
}
|
2023-10-13 09:37:24 +08:00
|
|
|
|
cellRect = cellElements[0].getBoundingClientRect();
|
2023-06-10 17:45:04 +08:00
|
|
|
|
let html = "";
|
2024-02-06 09:16:01 +08:00
|
|
|
|
let height = cellRect.height;
|
2024-12-06 09:36:08 +08:00
|
|
|
|
let style;
|
2024-02-04 12:19:46 +08:00
|
|
|
|
if (contentElement) {
|
|
|
|
|
|
const contentRect = contentElement.getBoundingClientRect();
|
|
|
|
|
|
if (cellRect.bottom > contentRect.bottom) {
|
|
|
|
|
|
height = contentRect.bottom - cellRect.top;
|
|
|
|
|
|
}
|
2024-12-09 10:20:40 +08:00
|
|
|
|
const width = Math.min(Math.max(cellRect.width, 25), contentRect.width);
|
2025-06-29 10:17:37 +08:00
|
|
|
|
style = `style="padding: ${viewType === "table" ? 6 : 3}px 8px;position:absolute;left: ${(cellRect.left < contentRect.left || cellRect.left + width > contentRect.right) ? contentRect.left : cellRect.left}px;top: ${cellRect.top}px;width:${width}px;height: ${height}px"`;
|
2024-12-06 09:36:08 +08:00
|
|
|
|
} else {
|
2025-06-29 10:17:37 +08:00
|
|
|
|
style = `style="padding: ${viewType === "table" ? 6 : 3}px 8px;position:absolute;left: ${cellRect.left}px;top: ${cellRect.top}px;width:${Math.max(cellRect.width, 25)}px;height: ${height}px"`;
|
2024-02-04 12:19:46 +08:00
|
|
|
|
}
|
2024-12-06 09:36:08 +08:00
|
|
|
|
|
2024-03-28 10:05:06 +08:00
|
|
|
|
if (["text", "email", "phone", "block", "template"].includes(type)) {
|
2025-01-14 22:06:40 +08:00
|
|
|
|
html = `<textarea ${style} spellcheck="false" class="b3-text-field"></textarea>`;
|
2024-03-28 10:05:06 +08:00
|
|
|
|
} else if (type === "url") {
|
2024-04-26 22:33:28 +08:00
|
|
|
|
html = `<textarea ${style} spellcheck="false" class="b3-text-field">${cellElements[0].firstElementChild.getAttribute("data-href")}</textarea>`;
|
2023-10-01 17:41:00 +08:00
|
|
|
|
} else if (type === "number") {
|
2024-04-26 22:33:28 +08:00
|
|
|
|
html = `<input type="number" spellcheck="false" value="${cellElements[0].firstElementChild.getAttribute("data-content")}" ${style} class="b3-text-field">`;
|
2024-01-04 12:46:57 +08:00
|
|
|
|
} else {
|
2023-11-14 12:58:45 +08:00
|
|
|
|
if (["select", "mSelect"].includes(type)) {
|
|
|
|
|
|
openMenuPanel({protyle, blockElement, type: "select", cellElements});
|
|
|
|
|
|
} else if (type === "mAsset") {
|
|
|
|
|
|
openMenuPanel({protyle, blockElement, type: "asset", cellElements});
|
2023-12-27 21:28:45 +08:00
|
|
|
|
focusBlock(blockElement);
|
2023-11-14 12:58:45 +08:00
|
|
|
|
} else if (type === "date") {
|
|
|
|
|
|
openMenuPanel({protyle, blockElement, type: "date", cellElements});
|
2023-11-20 11:12:02 +08:00
|
|
|
|
} else if (type === "checkbox") {
|
2024-01-04 12:46:57 +08:00
|
|
|
|
updateCellValueByInput(protyle, type, blockElement, cellElements);
|
2023-12-24 16:54:15 +08:00
|
|
|
|
} else if (type === "relation") {
|
|
|
|
|
|
openMenuPanel({protyle, blockElement, type: "relation", cellElements});
|
2024-01-01 17:20:22 +08:00
|
|
|
|
} else if (type === "rollup") {
|
2025-06-15 11:38:51 +08:00
|
|
|
|
openMenuPanel({
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
blockElement,
|
|
|
|
|
|
type: "rollup",
|
|
|
|
|
|
cellElements,
|
|
|
|
|
|
colId: getColId(cellElements[0], viewType)
|
|
|
|
|
|
});
|
2023-11-14 12:58:45 +08:00
|
|
|
|
}
|
2025-06-14 09:48:25 +08:00
|
|
|
|
if (viewType === "table" && !hasClosestByClassName(cellElements[0], "custom-attr")) {
|
2023-11-14 12:58:45 +08:00
|
|
|
|
cellElements[0].classList.add("av__cell--select");
|
2024-03-22 11:08:21 +08:00
|
|
|
|
addDragFill(cellElements[0]);
|
2023-11-14 12:58:45 +08:00
|
|
|
|
}
|
2023-07-09 23:54:32 +08:00
|
|
|
|
return;
|
2023-06-10 16:27:52 +08:00
|
|
|
|
}
|
2023-07-13 09:43:10 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
2023-09-02 11:13:47 +08:00
|
|
|
|
document.body.insertAdjacentHTML("beforeend", `<div class="av__mask" style="z-index: ${++window.siyuan.zIndex}">
|
2023-06-10 16:27:52 +08:00
|
|
|
|
${html}
|
|
|
|
|
|
</div>`);
|
|
|
|
|
|
const avMaskElement = document.querySelector(".av__mask");
|
|
|
|
|
|
const inputElement = avMaskElement.querySelector(".b3-text-field") as HTMLInputElement;
|
|
|
|
|
|
if (inputElement) {
|
2025-01-14 22:06:40 +08:00
|
|
|
|
if (["text", "email", "phone", "block", "template"].includes(type)) {
|
2025-01-18 00:12:41 +08:00
|
|
|
|
inputElement.value = cellElements[0].querySelector(".av__celltext")?.textContent || "";
|
2025-01-14 22:06:40 +08:00
|
|
|
|
}
|
2023-06-10 16:27:52 +08:00
|
|
|
|
inputElement.select();
|
2023-06-30 17:05:54 +08:00
|
|
|
|
inputElement.focus();
|
2024-01-04 12:46:57 +08:00
|
|
|
|
if (type === "template") {
|
2024-03-04 21:51:43 +08:00
|
|
|
|
fetchPost("/api/av/renderAttributeView", {
|
|
|
|
|
|
id: blockElement.dataset.avId,
|
|
|
|
|
|
viewID: blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW)
|
|
|
|
|
|
}, (response) => {
|
2025-06-14 14:03:35 +08:00
|
|
|
|
getFieldsByData(response.data).find((item: IAVColumn) => {
|
|
|
|
|
|
if (item.id === getColId(cellElements[0], viewType)) {
|
2023-10-13 11:30:44 +08:00
|
|
|
|
inputElement.value = item.template;
|
|
|
|
|
|
inputElement.dataset.template = item.template;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-12-26 22:36:59 +08:00
|
|
|
|
if (type === "block") {
|
2023-12-26 22:33:04 +08:00
|
|
|
|
inputElement.addEventListener("input", (event: InputEvent) => {
|
2023-12-26 22:36:59 +08:00
|
|
|
|
if (Constants.BLOCK_HINT_KEYS.includes(inputElement.value.substring(0, 2))) {
|
2023-12-26 22:33:04 +08:00
|
|
|
|
protyle.toolbar.range = document.createRange();
|
2025-06-14 14:03:35 +08:00
|
|
|
|
if (cellElements[0] && !blockElement.contains(cellElements[0])) {
|
|
|
|
|
|
const rowID = getFieldIdByCellElement(cellElements[0], viewType);
|
|
|
|
|
|
if (viewType === "table") {
|
|
|
|
|
|
cellElements[0] = (blockElement.querySelector(`.av__row[data-id="${rowID}"] .av__cell[data-col-id="${cellElements[0].dataset.colId}"]`)) as HTMLElement;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cellElements[0] = (blockElement.querySelector(`.av__gallery-item[data-id="${rowID}"] .av__cell[data-field-id="${cellElements[0].dataset.fieldId}"]`)) as HTMLElement;
|
2024-01-10 11:33:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-26 22:33:04 +08:00
|
|
|
|
protyle.toolbar.range.selectNodeContents(cellElements[0].lastChild);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
2025-06-21 10:52:17 +08:00
|
|
|
|
if (viewType === "table") {
|
|
|
|
|
|
cellElements[0].classList.add("av__cell--select");
|
|
|
|
|
|
addDragFill(cellElements[0]);
|
|
|
|
|
|
}
|
2024-03-28 23:34:11 +08:00
|
|
|
|
let textPlain = inputElement.value;
|
|
|
|
|
|
if (isDynamicRef(textPlain)) {
|
2024-03-29 09:47:40 +08:00
|
|
|
|
textPlain = textPlain.substring(2, 22 + 2);
|
2024-03-28 23:34:11 +08:00
|
|
|
|
} else {
|
2024-03-29 09:47:40 +08:00
|
|
|
|
textPlain = textPlain.substring(2);
|
2024-03-28 23:34:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
hintRef(textPlain, protyle, "av");
|
2023-12-26 22:33:04 +08:00
|
|
|
|
avMaskElement?.remove();
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
}
|
2023-12-29 15:00:36 +08:00
|
|
|
|
});
|
2023-12-26 22:33:04 +08:00
|
|
|
|
}
|
2023-06-10 16:27:52 +08:00
|
|
|
|
inputElement.addEventListener("keydown", (event) => {
|
|
|
|
|
|
if (event.isComposing) {
|
2023-06-10 17:45:04 +08:00
|
|
|
|
return;
|
2023-06-10 16:27:52 +08:00
|
|
|
|
}
|
2024-06-16 16:01:52 +08:00
|
|
|
|
if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-11-28 21:36:52 +08:00
|
|
|
|
if (event.key === "Escape" || event.key === "Tab" ||
|
2023-11-12 12:28:20 +08:00
|
|
|
|
(event.key === "Enter" && !event.shiftKey && isNotCtrl(event))) {
|
2024-01-04 12:46:57 +08:00
|
|
|
|
updateCellValueByInput(protyle, type, blockElement, cellElements);
|
2023-11-28 21:36:52 +08:00
|
|
|
|
if (event.key === "Tab") {
|
2023-11-28 23:27:04 +08:00
|
|
|
|
protyle.wysiwyg.element.dispatchEvent(new KeyboardEvent("keydown", {
|
|
|
|
|
|
shiftKey: event.shiftKey,
|
|
|
|
|
|
ctrlKey: event.ctrlKey,
|
|
|
|
|
|
altKey: event.altKey,
|
|
|
|
|
|
metaKey: event.metaKey,
|
|
|
|
|
|
key: "Tab",
|
|
|
|
|
|
keyCode: 9
|
|
|
|
|
|
}));
|
2023-11-28 21:36:52 +08:00
|
|
|
|
}
|
2023-06-10 16:27:52 +08:00
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
}
|
2023-06-10 17:45:04 +08:00
|
|
|
|
});
|
2023-06-10 16:27:52 +08:00
|
|
|
|
}
|
2024-04-10 22:38:48 +08:00
|
|
|
|
|
|
|
|
|
|
const removeAvMask = (event: Event) => {
|
2024-04-08 21:33:41 +08:00
|
|
|
|
if ((event.target as HTMLElement).classList.contains("av__mask")
|
|
|
|
|
|
&& document.activeElement.tagName !== "TEXTAREA" && document.activeElement.tagName !== "INPUT") {
|
2024-01-04 12:46:57 +08:00
|
|
|
|
updateCellValueByInput(protyle, type, blockElement, cellElements);
|
2023-06-10 16:27:52 +08:00
|
|
|
|
avMaskElement?.remove();
|
|
|
|
|
|
}
|
2024-04-11 08:55:37 +08:00
|
|
|
|
};
|
2024-04-10 22:38:48 +08:00
|
|
|
|
avMaskElement.addEventListener("click", (event) => {
|
2024-04-11 08:55:37 +08:00
|
|
|
|
removeAvMask(event);
|
2024-04-10 22:38:48 +08:00
|
|
|
|
});
|
|
|
|
|
|
avMaskElement.addEventListener("contextmenu", (event) => {
|
2024-04-11 08:55:37 +08:00
|
|
|
|
removeAvMask(event);
|
2023-06-10 17:45:04 +08:00
|
|
|
|
});
|
2024-09-27 22:53:19 +08:00
|
|
|
|
avMaskElement.addEventListener("mousedown", (event: MouseEvent & { target: HTMLElement }) => {
|
2024-09-23 23:36:24 +08:00
|
|
|
|
if (event.button === 1) {
|
2024-09-27 22:53:19 +08:00
|
|
|
|
if (event.target.classList.contains("av__mask") && document.activeElement && document.activeElement.nodeType === 1) {
|
|
|
|
|
|
(document.activeElement as HTMLElement).blur();
|
|
|
|
|
|
}
|
2024-09-23 23:36:24 +08:00
|
|
|
|
removeAvMask(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-06-10 16:27:52 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2024-01-04 12:46:57 +08:00
|
|
|
|
const updateCellValueByInput = (protyle: IProtyle, type: TAVCol, blockElement: HTMLElement, cellElements: HTMLElement[]) => {
|
2025-06-14 09:48:25 +08:00
|
|
|
|
const viewType = blockElement.getAttribute("data-av-type") as TAVView;
|
|
|
|
|
|
if (viewType === "table") {
|
|
|
|
|
|
const rowElement = hasClosestByClassName(cellElements[0], "av__row");
|
|
|
|
|
|
if (!rowElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (cellElements.length === 1 && cellElements[0].dataset.detached === "true" && !rowElement.dataset.id) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-09-28 00:33:00 +08:00
|
|
|
|
}
|
2023-07-17 19:56:52 +08:00
|
|
|
|
const avMaskElement = document.querySelector(".av__mask");
|
2023-07-13 00:07:33 +08:00
|
|
|
|
const avID = blockElement.getAttribute("data-av-id");
|
2023-10-13 11:30:44 +08:00
|
|
|
|
if (type === "template") {
|
2025-06-14 14:03:35 +08:00
|
|
|
|
const colId = getColId(cellElements[0], viewType);
|
2023-10-13 11:30:44 +08:00
|
|
|
|
const textElement = avMaskElement.querySelector(".b3-text-field") as HTMLInputElement;
|
2024-03-07 11:51:15 +08:00
|
|
|
|
if (textElement.value !== textElement.dataset.template && !blockElement.getAttribute("data-loading")) {
|
2023-10-13 11:34:19 +08:00
|
|
|
|
transaction(protyle, [{
|
|
|
|
|
|
action: "updateAttrViewColTemplate",
|
|
|
|
|
|
id: colId,
|
|
|
|
|
|
avID,
|
|
|
|
|
|
data: textElement.value,
|
|
|
|
|
|
type: "template",
|
|
|
|
|
|
}], [{
|
|
|
|
|
|
action: "updateAttrViewColTemplate",
|
|
|
|
|
|
id: colId,
|
|
|
|
|
|
avID,
|
|
|
|
|
|
data: textElement.dataset.template,
|
|
|
|
|
|
type: "template",
|
|
|
|
|
|
}]);
|
2024-03-07 11:51:15 +08:00
|
|
|
|
blockElement.setAttribute("data-loading", "true");
|
2023-10-13 11:34:19 +08:00
|
|
|
|
}
|
2023-10-13 11:30:44 +08:00
|
|
|
|
} else {
|
2024-01-04 12:46:57 +08:00
|
|
|
|
updateCellsValue(protyle, blockElement, type === "checkbox" ? {
|
|
|
|
|
|
checked: cellElements[0].querySelector("use").getAttribute("xlink:href") === "#iconUncheck"
|
|
|
|
|
|
} : (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value, cellElements);
|
2023-10-06 10:56:30 +08:00
|
|
|
|
}
|
2025-06-14 09:48:25 +08:00
|
|
|
|
if (viewType === "table" &&
|
|
|
|
|
|
// 兼容新增行后台隐藏
|
|
|
|
|
|
cellElements[0] &&
|
|
|
|
|
|
!hasClosestByClassName(cellElements[0], "custom-attr")) {
|
2023-11-20 12:27:20 +08:00
|
|
|
|
cellElements[0].classList.add("av__cell--select");
|
2024-03-22 11:08:21 +08:00
|
|
|
|
addDragFill(cellElements[0]);
|
2023-11-20 12:27:20 +08:00
|
|
|
|
}
|
2024-01-04 12:46:57 +08:00
|
|
|
|
// 单元格编辑中 ctrl+p 光标定位
|
|
|
|
|
|
if (!document.querySelector(".b3-dialog")) {
|
2023-10-13 11:55:51 +08:00
|
|
|
|
focusBlock(blockElement);
|
|
|
|
|
|
}
|
2023-12-07 21:12:29 +08:00
|
|
|
|
document.querySelectorAll(".av__mask").forEach((item) => {
|
|
|
|
|
|
item.remove();
|
2023-06-10 17:45:04 +08:00
|
|
|
|
});
|
|
|
|
|
|
};
|
2023-12-15 12:04:18 +08:00
|
|
|
|
|
2025-05-09 20:27:53 +08:00
|
|
|
|
export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, value?: any,
|
|
|
|
|
|
cElements?: HTMLElement[], columns?: IAVColumn[], html?: string, getOperations = false) => {
|
2023-12-17 16:24:11 +08:00
|
|
|
|
const doOperations: IOperation[] = [];
|
|
|
|
|
|
const undoOperations: IOperation[] = [];
|
2023-12-15 12:04:18 +08:00
|
|
|
|
|
2023-12-17 16:24:11 +08:00
|
|
|
|
const avID = nodeElement.dataset.avId;
|
|
|
|
|
|
const id = nodeElement.dataset.nodeId;
|
|
|
|
|
|
let text = "";
|
2024-03-23 10:25:15 +08:00
|
|
|
|
const json: IAVCellValue[][] = [];
|
2023-12-25 00:20:51 +08:00
|
|
|
|
let cellElements: Element[];
|
|
|
|
|
|
if (cElements?.length > 0) {
|
|
|
|
|
|
cellElements = cElements;
|
|
|
|
|
|
} else {
|
2024-01-27 22:06:22 +08:00
|
|
|
|
cellElements = Array.from(nodeElement.querySelectorAll(".av__cell--active, .av__cell--select"));
|
2023-12-25 00:20:51 +08:00
|
|
|
|
if (cellElements.length === 0) {
|
|
|
|
|
|
nodeElement.querySelectorAll(".av__row--select:not(.av__row--header)").forEach(rowElement => {
|
|
|
|
|
|
rowElement.querySelectorAll(".av__cell").forEach(cellElement => {
|
|
|
|
|
|
cellElements.push(cellElement);
|
|
|
|
|
|
});
|
2023-12-17 16:24:11 +08:00
|
|
|
|
});
|
2023-12-25 00:20:51 +08:00
|
|
|
|
}
|
2023-12-15 12:04:18 +08:00
|
|
|
|
}
|
2024-05-17 23:35:36 +08:00
|
|
|
|
const isCustomAttr = hasClosestByClassName(cellElements[0], "custom-attr");
|
2025-06-14 09:48:25 +08:00
|
|
|
|
const viewType = nodeElement.getAttribute("data-av-type") as TAVView;
|
2023-12-29 14:56:00 +08:00
|
|
|
|
cellElements.forEach((item: HTMLElement, elementIndex) => {
|
2025-06-14 14:03:35 +08:00
|
|
|
|
const rowID = getFieldIdByCellElement(item, viewType);
|
|
|
|
|
|
if (!rowID) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!nodeElement.contains(item)) {
|
|
|
|
|
|
if (viewType === "table") {
|
|
|
|
|
|
item = cellElements[elementIndex] = (nodeElement.querySelector(`.av__row[data-id="${rowID}"] .av__cell[data-col-id="${item.dataset.colId}"]`) ||
|
2025-06-14 09:48:25 +08:00
|
|
|
|
nodeElement.querySelector(`.fn__flex-1[data-col-id="${item.dataset.colId}"]`)) as HTMLElement;
|
2025-06-14 14:03:35 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
item = cellElements[elementIndex] = (nodeElement.querySelector(`.av__gallery-item[data-id="${rowID}"] .av__cell[data-field-id="${item.dataset.fieldId}"]`)) as HTMLElement;
|
2025-06-14 09:48:25 +08:00
|
|
|
|
}
|
2024-01-04 12:46:57 +08:00
|
|
|
|
}
|
2025-06-14 09:48:25 +08:00
|
|
|
|
|
2024-03-07 09:15:15 +08:00
|
|
|
|
if (!item) {
|
|
|
|
|
|
// 兼容新增行后台隐藏
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-12-25 00:23:26 +08:00
|
|
|
|
const type = getTypeByCellElement(item) || item.dataset.type as TAVCol;
|
2024-01-04 17:33:54 +08:00
|
|
|
|
if (["created", "updated", "template", "rollup"].includes(type)) {
|
2023-12-15 12:04:18 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-04-14 08:45:42 +08:00
|
|
|
|
const cellId = item.dataset.id; // 刚创建时无 id,更新需和 oldValue 保持一致
|
2025-06-15 11:38:51 +08:00
|
|
|
|
const colId = getColId(item, viewType);
|
2023-12-15 12:04:18 +08:00
|
|
|
|
|
2025-07-23 13:08:38 +08:00
|
|
|
|
text += getCellText(item) + ((cellElements[elementIndex + 1] && item.nextElementSibling && item.nextElementSibling === cellElements[elementIndex + 1]) ? "\t" : "\n\n");
|
2023-12-27 00:18:49 +08:00
|
|
|
|
const oldValue = genCellValueByElement(type, item);
|
2025-07-23 13:08:38 +08:00
|
|
|
|
if (elementIndex === 0 || cellElements[elementIndex - 1] !== item.previousElementSibling) {
|
2024-03-28 10:05:06 +08:00
|
|
|
|
json.push([]);
|
2024-03-23 10:25:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
json[json.length - 1].push(oldValue);
|
2024-12-21 11:52:45 +08:00
|
|
|
|
let newValue = value;
|
2023-12-27 00:18:49 +08:00
|
|
|
|
// relation 为全部更新,以下类型为添加
|
|
|
|
|
|
if (type === "mAsset") {
|
|
|
|
|
|
if (Array.isArray(value)) {
|
2024-12-21 11:52:45 +08:00
|
|
|
|
newValue = oldValue.mAsset.concat(value);
|
2025-05-09 20:27:53 +08:00
|
|
|
|
} else if (typeof value !== "undefined" && typeof value !== "object") { // 不传入为删除,传入字符串不进行处理
|
2024-05-20 11:56:19 +08:00
|
|
|
|
let link = protyle.lute.GetLinkDest(value);
|
|
|
|
|
|
let name = "";
|
2024-05-25 17:58:06 +08:00
|
|
|
|
let imgSrc = "";
|
2025-02-08 17:26:11 +08:00
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/13892
|
|
|
|
|
|
if (!link && value.startsWith("assets/")) {
|
|
|
|
|
|
link = value;
|
|
|
|
|
|
name = getAssetName(value) + pathPosix().extname(value);
|
|
|
|
|
|
}
|
2024-05-20 11:56:19 +08:00
|
|
|
|
if (html) {
|
2024-05-21 00:24:54 +08:00
|
|
|
|
const tempElement = document.createElement("template");
|
|
|
|
|
|
tempElement.innerHTML = html;
|
|
|
|
|
|
const aElement = tempElement.content.querySelector('[data-type~="a"]');
|
2024-05-20 11:56:19 +08:00
|
|
|
|
if (aElement) {
|
|
|
|
|
|
link = aElement.getAttribute("data-href");
|
2024-05-21 00:24:54 +08:00
|
|
|
|
name = aElement.textContent;
|
2024-05-25 17:58:06 +08:00
|
|
|
|
} else {
|
2024-05-27 11:06:54 +08:00
|
|
|
|
const imgElement = tempElement.content.querySelector(".img img");
|
2024-05-25 17:58:06 +08:00
|
|
|
|
if (imgElement) {
|
|
|
|
|
|
imgSrc = imgElement.getAttribute("data-src");
|
|
|
|
|
|
}
|
2024-05-20 11:56:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-08 22:08:53 +08:00
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/12308
|
|
|
|
|
|
if (!link) {
|
|
|
|
|
|
name = value;
|
|
|
|
|
|
}
|
2024-05-25 17:58:06 +08:00
|
|
|
|
if (!link && !name && !imgSrc) {
|
2024-05-20 11:56:19 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-05-25 17:58:06 +08:00
|
|
|
|
if (imgSrc) {
|
|
|
|
|
|
// 支持解析 ![]() https://github.com/siyuan-note/siyuan/issues/11487
|
2024-12-21 11:52:45 +08:00
|
|
|
|
newValue = oldValue.mAsset.concat({
|
2024-05-25 17:58:06 +08:00
|
|
|
|
type: "image",
|
|
|
|
|
|
content: imgSrc,
|
|
|
|
|
|
name: ""
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 支持解析 https://github.com/siyuan-note/siyuan/issues/11463
|
2024-12-21 11:52:45 +08:00
|
|
|
|
newValue = oldValue.mAsset.concat({
|
2024-05-25 17:58:06 +08:00
|
|
|
|
type: "file",
|
|
|
|
|
|
content: link,
|
|
|
|
|
|
name
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-12-27 00:18:49 +08:00
|
|
|
|
}
|
2025-07-03 11:14:40 +08:00
|
|
|
|
} else if (type === "mSelect" || type === "select") {
|
2023-12-27 00:18:49 +08:00
|
|
|
|
// 不传入为删除
|
|
|
|
|
|
if (typeof value === "string") {
|
2024-11-13 16:37:28 +08:00
|
|
|
|
const newMSelectValue: IAVCellSelectValue[] = [];
|
|
|
|
|
|
let colorIndex = oldValue.mSelect.length;
|
|
|
|
|
|
// 以逗号分隔,去重,去空,去换行后做为选项
|
|
|
|
|
|
[...new Set(value.split(",").map(v => v.trim().replace(/\n|\r\n|\r|\u2028|\u2029/g, "")))].forEach((item) => {
|
|
|
|
|
|
if (!item) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-11-14 23:21:55 +08:00
|
|
|
|
let hasSameContent = false;
|
2024-11-13 16:37:28 +08:00
|
|
|
|
oldValue.mSelect.find((mSelectItem) => {
|
|
|
|
|
|
if (mSelectItem.content === item) {
|
2024-11-14 23:21:55 +08:00
|
|
|
|
hasSameContent = true;
|
|
|
|
|
|
return true;
|
2024-11-13 16:37:28 +08:00
|
|
|
|
}
|
2024-11-14 23:21:55 +08:00
|
|
|
|
});
|
2024-11-13 16:37:28 +08:00
|
|
|
|
if (hasSameContent) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
colorIndex++;
|
|
|
|
|
|
newMSelectValue.push({
|
|
|
|
|
|
content: item,
|
|
|
|
|
|
color: colorIndex.toString()
|
2024-11-14 23:21:55 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
2024-12-21 11:52:45 +08:00
|
|
|
|
newValue = oldValue.mSelect.concat(newMSelectValue);
|
2023-12-27 00:18:49 +08:00
|
|
|
|
}
|
2024-12-23 16:21:59 +08:00
|
|
|
|
} else if (type === "block" && typeof value === "string" && oldValue.block.id) {
|
|
|
|
|
|
newValue = {
|
|
|
|
|
|
content: value,
|
2024-12-23 20:55:11 +08:00
|
|
|
|
id: oldValue.block.id,
|
2024-12-23 16:21:59 +08:00
|
|
|
|
};
|
2025-01-12 11:58:10 +08:00
|
|
|
|
if (oldValue.block.icon) {
|
|
|
|
|
|
newValue.icon = oldValue.block.icon;
|
|
|
|
|
|
}
|
2023-12-27 00:18:49 +08:00
|
|
|
|
}
|
2025-05-09 20:27:53 +08:00
|
|
|
|
let cellValue: IAVCellValue;
|
|
|
|
|
|
if (typeof newValue === "object" && newValue.type) {
|
|
|
|
|
|
cellValue = transformCellValue(type, newValue);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cellValue = genCellValue(type, newValue);
|
|
|
|
|
|
}
|
2024-01-04 12:46:57 +08:00
|
|
|
|
cellValue.id = cellId;
|
2024-01-04 17:33:54 +08:00
|
|
|
|
if ((cellValue.type === "date" && typeof cellValue.date === "string") ||
|
|
|
|
|
|
(cellValue.type === "relation" && typeof cellValue.relation === "string")) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-05-17 23:35:36 +08:00
|
|
|
|
if (columns && (type === "select" || type === "mSelect")) {
|
2024-05-17 18:02:15 +08:00
|
|
|
|
const operations = mergeAddOption(columns.find(e => e.id === colId), cellValue, avID);
|
|
|
|
|
|
doOperations.push(...operations.doOperations);
|
|
|
|
|
|
undoOperations.push(...operations.undoOperations);
|
|
|
|
|
|
}
|
2024-01-04 12:46:57 +08:00
|
|
|
|
if (objEquals(cellValue, oldValue)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-12-23 16:21:59 +08:00
|
|
|
|
|
|
|
|
|
|
doOperations.push({
|
|
|
|
|
|
action: "updateAttrViewCell",
|
|
|
|
|
|
id: cellId,
|
|
|
|
|
|
avID,
|
|
|
|
|
|
keyID: colId,
|
|
|
|
|
|
rowID,
|
|
|
|
|
|
data: cellValue
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2023-12-15 12:04:18 +08:00
|
|
|
|
undoOperations.push({
|
|
|
|
|
|
action: "updateAttrViewCell",
|
|
|
|
|
|
id: cellId,
|
|
|
|
|
|
avID,
|
|
|
|
|
|
keyID: colId,
|
|
|
|
|
|
rowID,
|
2023-12-27 00:18:49 +08:00
|
|
|
|
data: oldValue
|
2023-12-15 12:04:18 +08:00
|
|
|
|
});
|
2024-05-17 23:35:36 +08:00
|
|
|
|
if (isCustomAttr) {
|
2023-12-25 21:31:32 +08:00
|
|
|
|
item.innerHTML = genAVValueHTML(cellValue);
|
2024-05-17 23:35:36 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
updateAttrViewCellAnimation(item, cellValue);
|
2023-12-15 12:04:18 +08:00
|
|
|
|
}
|
2023-12-17 16:24:11 +08:00
|
|
|
|
});
|
2025-05-09 20:27:53 +08:00
|
|
|
|
if (getOperations) {
|
|
|
|
|
|
return {doOperations, undoOperations};
|
|
|
|
|
|
}
|
2023-12-15 12:04:18 +08:00
|
|
|
|
if (doOperations.length > 0) {
|
|
|
|
|
|
doOperations.push({
|
|
|
|
|
|
action: "doUpdateUpdated",
|
|
|
|
|
|
id,
|
|
|
|
|
|
data: dayjs().format("YYYYMMDDHHmmss"),
|
2023-12-17 16:24:11 +08:00
|
|
|
|
});
|
2023-12-15 12:04:18 +08:00
|
|
|
|
undoOperations.push({
|
|
|
|
|
|
action: "doUpdateUpdated",
|
|
|
|
|
|
id,
|
|
|
|
|
|
data: nodeElement.getAttribute("updated"),
|
2023-12-17 16:24:11 +08:00
|
|
|
|
});
|
2023-12-15 12:04:18 +08:00
|
|
|
|
transaction(protyle, doOperations, undoOperations);
|
|
|
|
|
|
}
|
2024-01-31 11:02:32 +08:00
|
|
|
|
return {text: text.substring(0, text.length - 2), json};
|
2023-12-17 16:24:11 +08:00
|
|
|
|
};
|
2023-12-18 20:47:22 +08:00
|
|
|
|
|
2024-01-26 20:34:11 +08:00
|
|
|
|
export const renderCellAttr = (cellElement: Element, value: IAVCellValue) => {
|
|
|
|
|
|
if (value.type === "checkbox") {
|
|
|
|
|
|
if (value.checkbox.checked) {
|
|
|
|
|
|
cellElement.classList.add("av__cell-check");
|
|
|
|
|
|
cellElement.classList.remove("av__cell-uncheck");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cellElement.classList.remove("av__cell-check");
|
|
|
|
|
|
cellElement.classList.add("av__cell-uncheck");
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (value.type === "block") {
|
|
|
|
|
|
if (value.isDetached) {
|
|
|
|
|
|
cellElement.setAttribute("data-detached", "true");
|
2024-06-20 20:26:57 +08:00
|
|
|
|
} else {
|
2025-08-10 12:10:39 +08:00
|
|
|
|
cellElement.querySelector(".av__celltext").setAttribute("data-id", value.block.id);
|
2024-06-20 20:26:57 +08:00
|
|
|
|
cellElement.removeAttribute("data-detached");
|
2024-01-26 20:34:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-29 15:44:18 +08:00
|
|
|
|
};
|
2024-01-26 20:34:11 +08:00
|
|
|
|
|
2025-06-14 09:48:25 +08:00
|
|
|
|
export const renderCell = (cellValue: IAVCellValue, rowIndex = 0, showIcon = true, type: TAVView = "table") => {
|
2023-12-18 20:47:22 +08:00
|
|
|
|
let text = "";
|
2024-05-22 22:56:06 +08:00
|
|
|
|
if ("template" === cellValue.type) {
|
|
|
|
|
|
text = `<span class="av__celltext">${cellValue ? (cellValue.template.content || "") : ""}</span>`;
|
|
|
|
|
|
} else if ("text" === cellValue.type) {
|
|
|
|
|
|
text = `<span class="av__celltext">${cellValue ? Lute.EscapeHTMLStr(cellValue.text.content || "") : ""}</span>`;
|
2024-03-28 10:05:06 +08:00
|
|
|
|
} else if (["email", "phone"].includes(cellValue.type)) {
|
2024-05-22 22:56:06 +08:00
|
|
|
|
text = `<span class="av__celltext av__celltext--url" data-type="${cellValue.type}">${cellValue ? Lute.EscapeHTMLStr(cellValue[cellValue.type as "email"].content || "") : ""}</span>`;
|
2024-03-28 10:05:06 +08:00
|
|
|
|
} else if ("url" === cellValue.type) {
|
2024-03-29 09:47:40 +08:00
|
|
|
|
text = renderCellURL(cellValue?.url?.content || "");
|
2023-12-18 20:47:22 +08:00
|
|
|
|
} else if (cellValue.type === "block") {
|
2024-05-20 23:16:56 +08:00
|
|
|
|
// 不可使用换行 https://github.com/siyuan-note/siyuan/issues/11365
|
2023-12-18 20:47:22 +08:00
|
|
|
|
if (cellValue?.isDetached) {
|
2025-01-12 17:39:25 +08:00
|
|
|
|
text = `<span class="av__celltext">${Lute.EscapeHTMLStr(cellValue.block.content || "")}</span><span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.more}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
} else {
|
2025-06-14 09:48:25 +08:00
|
|
|
|
text = `<span class="b3-menu__avemoji${showIcon ? "" : " fn__none"}" data-unicode="${cellValue.block.icon || ""}">${unicode2Emoji(cellValue.block.icon || window.siyuan.storage[Constants.LOCAL_IMAGES].file)}</span><span data-type="block-ref" data-id="${cellValue.block.id}" data-subtype="s" class="av__celltext av__celltext--ref">${Lute.EscapeHTMLStr(cellValue.block.content)}</span><span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.update}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else if (cellValue.type === "number") {
|
2024-01-14 12:09:42 +08:00
|
|
|
|
text = `<span class="av__celltext" data-content="${cellValue?.number.isNotEmpty ? cellValue?.number.content : ""}">${cellValue?.number.formattedContent || cellValue?.number.content || ""}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
} else if (cellValue.type === "mSelect" || cellValue.type === "select") {
|
2024-11-15 17:19:43 +08:00
|
|
|
|
cellValue?.mSelect?.forEach((item, index) => {
|
|
|
|
|
|
if (cellValue.type === "select" && index > 0) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-11-18 16:23:38 +08:00
|
|
|
|
text += `<span class="b3-chip" style="background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">${escapeHtml(item.content)}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
} else if (cellValue.type === "date") {
|
|
|
|
|
|
const dataValue = cellValue ? cellValue.date : null;
|
|
|
|
|
|
text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
|
|
|
|
|
|
if (dataValue && dataValue.isNotEmpty) {
|
|
|
|
|
|
text += dayjs(dataValue.content).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (dataValue && dataValue.hasEndDate && dataValue.isNotEmpty && dataValue.isNotEmpty2) {
|
|
|
|
|
|
text += `<svg class="av__cellicon"><use xlink:href="#iconForward"></use></svg>${dayjs(dataValue.content2).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
text += "</span>";
|
|
|
|
|
|
} else if (["created", "updated"].includes(cellValue.type)) {
|
|
|
|
|
|
const dataValue = cellValue ? cellValue[cellValue.type as "date"] : null;
|
|
|
|
|
|
text = `<span class="av__celltext" data-value='${JSON.stringify(dataValue)}'>`;
|
|
|
|
|
|
if (dataValue && dataValue.isNotEmpty) {
|
|
|
|
|
|
text += dayjs(dataValue.content).format("YYYY-MM-DD HH:mm");
|
|
|
|
|
|
}
|
|
|
|
|
|
text += "</span>";
|
2024-04-15 00:49:48 +08:00
|
|
|
|
} else if (["lineNumber"].includes(cellValue.type)) {
|
|
|
|
|
|
// 渲染行号
|
|
|
|
|
|
text = `<span class="av__celltext" data-value='${rowIndex + 1}'>${rowIndex + 1}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
} else if (cellValue.type === "mAsset") {
|
|
|
|
|
|
cellValue?.mAsset?.forEach((item) => {
|
|
|
|
|
|
if (item.type === "image") {
|
2025-07-09 17:29:07 +08:00
|
|
|
|
text += `<img loading="lazy" class="av__cellassetimg ariaLabel" aria-label="${item.content}" src="${getCompressURL(item.content)}">`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
} else {
|
2024-05-21 00:23:05 +08:00
|
|
|
|
text += `<span class="b3-chip av__celltext--url ariaLabel" aria-label="${escapeAttr(item.content)}" data-name="${escapeAttr(item.name)}" data-url="${escapeAttr(item.content)}">${item.name || item.content}</span>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else if (cellValue.type === "checkbox") {
|
2025-06-14 09:48:25 +08:00
|
|
|
|
text += `<div class="fn__flex"><svg class="av__checkbox"><use xlink:href="#icon${cellValue?.checkbox?.checked ? "Check" : "Uncheck"}"></use></svg>`;
|
2025-07-30 12:08:15 +08:00
|
|
|
|
if (type === "gallery" && cellValue?.checkbox?.content) {
|
|
|
|
|
|
text += `<span class="fn__space"></span>${cellValue?.checkbox?.content}`;
|
2025-06-14 09:48:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
text += "</div>";
|
2023-12-30 22:07:24 +08:00
|
|
|
|
} else if (cellValue.type === "rollup") {
|
2024-01-08 23:23:59 +08:00
|
|
|
|
cellValue?.rollup?.contents?.forEach((item) => {
|
2025-08-06 11:33:24 +08:00
|
|
|
|
const rollupText = ["template", "select", "mSelect", "mAsset", "checkbox", "relation"].includes(item.type) ? renderCell(item, rowIndex, showIcon, type) : renderRollup(item);
|
2024-01-03 23:24:33 +08:00
|
|
|
|
if (rollupText) {
|
2025-01-04 22:31:24 +08:00
|
|
|
|
text += rollupText + ", ";
|
2024-01-01 17:44:30 +08:00
|
|
|
|
}
|
2023-12-30 22:07:24 +08:00
|
|
|
|
});
|
2024-01-03 23:24:33 +08:00
|
|
|
|
if (text && text.endsWith(", ")) {
|
|
|
|
|
|
text = text.substring(0, text.length - 2);
|
|
|
|
|
|
}
|
2023-12-24 16:54:15 +08:00
|
|
|
|
} else if (cellValue.type === "relation") {
|
2025-08-11 23:45:35 +08:00
|
|
|
|
cellValue?.relation?.contents?.forEach((item, index) => {
|
2024-03-07 17:44:25 +08:00
|
|
|
|
if (item && item.block) {
|
2025-08-11 23:45:35 +08:00
|
|
|
|
const rowID = cellValue.relation.blockIDs[index];
|
2025-01-04 22:31:24 +08:00
|
|
|
|
if (item?.isDetached) {
|
2025-08-12 00:59:39 +08:00
|
|
|
|
text += `<span data-row-id="${rowID}" class="av__cell--relation"><span class="b3-menu__avemoji${showIcon ? "" : " fn__none"}">➖</span><span class="av__celltext">${Lute.EscapeHTMLStr(item.block.content || window.siyuan.languages.untitled)}</span></span>`;
|
2025-01-04 22:31:24 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// data-block-id 用于更新 emoji
|
2025-08-12 00:59:39 +08:00
|
|
|
|
text += `<span data-row-id="${rowID}" class="av__cell--relation" data-block-id="${item.block.id}"><span class="b3-menu__avemoji${showIcon ? "" : " fn__none"}" data-unicode="${item.block.icon || ""}">${unicode2Emoji(item.block.icon || window.siyuan.storage[Constants.LOCAL_IMAGES].file)}</span><span data-type="block-ref" data-id="${item.block.id}" data-subtype="s" class="av__celltext av__celltext--ref">${Lute.EscapeHTMLStr(item.block.content || window.siyuan.languages.untitled)}</span></span>`;
|
2025-01-04 22:31:24 +08:00
|
|
|
|
}
|
2024-03-07 17:44:25 +08:00
|
|
|
|
}
|
2023-12-25 21:31:32 +08:00
|
|
|
|
});
|
2024-03-07 17:44:25 +08:00
|
|
|
|
if (text && text.endsWith(", ")) {
|
|
|
|
|
|
text = text.substring(0, text.length - 2);
|
|
|
|
|
|
}
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
2024-04-15 00:49:48 +08:00
|
|
|
|
|
2025-07-10 16:48:00 +08:00
|
|
|
|
if ((["text", "template", "url", "email", "phone", "date", "created", "updated"].includes(cellValue.type) && cellValue[cellValue.type as "url"]?.content) ||
|
2024-05-15 17:01:48 +08:00
|
|
|
|
cellValue.type === "lineNumber" ||
|
2025-07-10 16:48:00 +08:00
|
|
|
|
(cellValue.type === "number" && cellValue.number?.isNotEmpty) ||
|
2024-05-15 17:01:48 +08:00
|
|
|
|
(cellValue.type === "block" && cellValue.block?.content)) {
|
2023-12-18 20:47:22 +08:00
|
|
|
|
text += `<span ${cellValue.type !== "number" ? "" : 'style="right:auto;left:5px"'} data-type="copy" class="block__icon"><svg><use xlink:href="#iconCopy"></use></svg></span>`;
|
|
|
|
|
|
}
|
|
|
|
|
|
return text;
|
2023-12-19 11:19:31 +08:00
|
|
|
|
};
|
2023-12-18 20:47:22 +08:00
|
|
|
|
|
2024-01-01 21:33:11 +08:00
|
|
|
|
const renderRollup = (cellValue: IAVCellValue) => {
|
2024-01-01 23:08:28 +08:00
|
|
|
|
let text = "";
|
2024-01-01 21:00:52 +08:00
|
|
|
|
if (["text"].includes(cellValue.type)) {
|
2024-01-01 17:30:03 +08:00
|
|
|
|
text = cellValue ? (cellValue[cellValue.type as "text"].content || "") : "";
|
2024-03-28 10:05:06 +08:00
|
|
|
|
} else if (["email", "phone"].includes(cellValue.type)) {
|
|
|
|
|
|
const emailContent = cellValue ? cellValue[cellValue.type as "email"].content : "";
|
|
|
|
|
|
if (emailContent) {
|
|
|
|
|
|
text = `<span class="av__celltext av__celltext--url" data-type="${cellValue.type}">${emailContent}</span>`;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if ("url" === cellValue.type) {
|
2024-03-29 09:47:40 +08:00
|
|
|
|
const urlContent = cellValue?.url?.content || "";
|
2024-01-01 17:51:02 +08:00
|
|
|
|
if (urlContent) {
|
2024-03-28 10:05:06 +08:00
|
|
|
|
text = renderCellURL(urlContent);
|
2024-01-01 17:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else if (cellValue.type === "block") {
|
|
|
|
|
|
if (cellValue?.isDetached) {
|
2025-08-10 12:10:39 +08:00
|
|
|
|
text = `<span class="av__celltext">${Lute.EscapeHTMLStr(cellValue.block?.content || window.siyuan.languages.untitled)}</span>`;
|
2024-01-01 17:20:22 +08:00
|
|
|
|
} else {
|
2025-01-12 17:53:14 +08:00
|
|
|
|
text = `<span data-type="block-ref" data-id="${cellValue.block?.id}" data-subtype="s" class="av__celltext av__celltext--ref">${Lute.EscapeHTMLStr(cellValue.block?.content || window.siyuan.languages.untitled)}</span>`;
|
2024-01-01 17:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else if (cellValue.type === "number") {
|
2024-01-01 17:44:30 +08:00
|
|
|
|
text = cellValue?.number.formattedContent || cellValue?.number.content.toString() || "";
|
2025-08-22 21:00:43 +08:00
|
|
|
|
} else if (["date", "updated", "created"].includes(cellValue.type)) {
|
2025-08-23 11:19:11 +08:00
|
|
|
|
const dataValue = cellValue ? cellValue[cellValue.type as "date"] : null;
|
2024-04-07 10:43:56 +08:00
|
|
|
|
if (dataValue.formattedContent) {
|
2024-04-07 23:58:24 +08:00
|
|
|
|
text = dataValue.formattedContent;
|
2024-04-07 10:43:56 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
if (dataValue && dataValue.isNotEmpty) {
|
|
|
|
|
|
text = dayjs(dataValue.content).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (dataValue && dataValue.hasEndDate && dataValue.isNotEmpty && dataValue.isNotEmpty2) {
|
|
|
|
|
|
text = `<svg class="av__cellicon"><use xlink:href="#iconForward"></use></svg>${dayjs(dataValue.content2).format(dataValue.isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}`;
|
|
|
|
|
|
}
|
2024-01-01 17:20:22 +08:00
|
|
|
|
}
|
2024-01-01 17:44:30 +08:00
|
|
|
|
if (text) {
|
|
|
|
|
|
text = `<span class="av__celltext">${text}</span>`;
|
|
|
|
|
|
}
|
2024-01-01 17:20:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
return text;
|
2024-01-01 23:08:28 +08:00
|
|
|
|
};
|
2024-01-01 17:20:22 +08:00
|
|
|
|
|
2023-12-18 20:47:22 +08:00
|
|
|
|
export const updateHeaderCell = (cellElement: HTMLElement, headerValue: {
|
|
|
|
|
|
icon?: string,
|
|
|
|
|
|
name?: string,
|
|
|
|
|
|
pin?: boolean,
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
if (typeof headerValue.icon !== "undefined") {
|
|
|
|
|
|
cellElement.dataset.icon = headerValue.icon;
|
2023-12-19 11:19:31 +08:00
|
|
|
|
cellElement.querySelector(".av__cellheadericon").outerHTML = headerValue.icon ? unicode2Emoji(headerValue.icon, "av__cellheadericon", true) : `<svg class="av__cellheadericon"><use xlink:href="#${getColIconByType(cellElement.dataset.dtype as TAVCol)}"></use></svg>`;
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (typeof headerValue.name !== "undefined") {
|
|
|
|
|
|
cellElement.querySelector(".av__celltext").textContent = headerValue.name;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (typeof headerValue.pin !== "undefined") {
|
2023-12-19 11:19:31 +08:00
|
|
|
|
const textElement = cellElement.querySelector(".av__celltext");
|
2023-12-18 20:47:22 +08:00
|
|
|
|
if (headerValue.pin) {
|
2024-01-14 12:09:42 +08:00
|
|
|
|
if (!cellElement.querySelector(".av__cellheadericon--pin")) {
|
|
|
|
|
|
textElement.insertAdjacentHTML("afterend", '<svg class="av__cellheadericon av__cellheadericon--pin"><use xlink:href="#iconPin"></use></svg>');
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2024-01-14 16:38:45 +08:00
|
|
|
|
cellElement.querySelector(".av__cellheadericon--pin")?.remove();
|
2023-12-18 20:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-19 11:19:31 +08:00
|
|
|
|
};
|
2024-01-13 22:34:46 +08:00
|
|
|
|
|
|
|
|
|
|
export const getPositionByCellElement = (cellElement: HTMLElement) => {
|
|
|
|
|
|
let rowElement = hasClosestByClassName(cellElement, "av__row");
|
|
|
|
|
|
if (!rowElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
let rowIndex = -1;
|
|
|
|
|
|
while (rowElement) {
|
|
|
|
|
|
rowElement = rowElement.previousElementSibling as HTMLElement;
|
|
|
|
|
|
rowIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
let celIndex = -2;
|
|
|
|
|
|
while (cellElement) {
|
|
|
|
|
|
cellElement = cellElement.previousElementSibling as HTMLElement;
|
2024-01-14 18:02:14 +08:00
|
|
|
|
if (cellElement && cellElement.classList.contains("av__colsticky")) {
|
|
|
|
|
|
cellElement = cellElement.lastElementChild as HTMLElement;
|
|
|
|
|
|
}
|
2024-01-13 22:34:46 +08:00
|
|
|
|
celIndex++;
|
|
|
|
|
|
}
|
|
|
|
|
|
return {rowIndex, celIndex};
|
2024-01-14 16:38:45 +08:00
|
|
|
|
};
|
2024-01-14 22:06:03 +08:00
|
|
|
|
|
|
|
|
|
|
export const dragFillCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, originData: {
|
|
|
|
|
|
[key: string]: IAVCellValue[]
|
2025-08-12 01:23:47 +08:00
|
|
|
|
}, originCellIds: string[], activeElement: Element) => {
|
2024-01-14 22:06:03 +08:00
|
|
|
|
nodeElement.querySelector(".av__drag-fill")?.remove();
|
|
|
|
|
|
const newData: { [key: string]: Array<IAVCellValue & { colId?: string, element?: HTMLElement }> } = {};
|
|
|
|
|
|
nodeElement.querySelectorAll(".av__cell--active").forEach((item: HTMLElement) => {
|
|
|
|
|
|
if (originCellIds.includes(item.dataset.id)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const rowElement = hasClosestByClassName(item, "av__row");
|
|
|
|
|
|
if (!rowElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!newData[rowElement.dataset.id]) {
|
|
|
|
|
|
newData[rowElement.dataset.id] = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
const value: IAVCellValue & {
|
|
|
|
|
|
colId?: string,
|
|
|
|
|
|
element?: HTMLElement
|
2024-01-16 10:56:55 +08:00
|
|
|
|
} = genCellValueByElement(getTypeByCellElement(item), item);
|
2024-01-14 22:06:03 +08:00
|
|
|
|
value.colId = item.dataset.colId;
|
|
|
|
|
|
value.element = item;
|
|
|
|
|
|
newData[rowElement.dataset.id].push(value);
|
2024-01-16 10:56:55 +08:00
|
|
|
|
});
|
2024-01-14 22:06:03 +08:00
|
|
|
|
const doOperations: IOperation[] = [];
|
|
|
|
|
|
const undoOperations: IOperation[] = [];
|
2024-01-16 10:56:55 +08:00
|
|
|
|
const avID = nodeElement.dataset.avId;
|
2024-01-14 22:06:03 +08:00
|
|
|
|
const originKeys = Object.keys(originData);
|
2025-08-12 01:23:47 +08:00
|
|
|
|
const showIcon = activeElement.querySelector(".b3-menu__avemoji") ? true : false;
|
2024-01-14 22:06:03 +08:00
|
|
|
|
Object.keys(newData).forEach((rowID, index) => {
|
|
|
|
|
|
newData[rowID].forEach((item, cellIndex) => {
|
2024-04-16 00:18:04 +08:00
|
|
|
|
if (["rollup", "template", "created", "updated"].includes(item.type) ||
|
|
|
|
|
|
(item.type === "block" && item.element.getAttribute("data-detached") !== "true")) {
|
2024-01-14 22:06:03 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-02-16 11:58:05 +08:00
|
|
|
|
// https://ld246.com/article/1707975507571 数据库下拉填充数据后异常
|
|
|
|
|
|
const data = JSON.parse(JSON.stringify(originData[originKeys[index % originKeys.length]][cellIndex]));
|
2024-01-14 22:34:24 +08:00
|
|
|
|
data.id = item.id;
|
2024-01-16 10:56:55 +08:00
|
|
|
|
const keyID = item.colId;
|
2024-01-14 22:34:24 +08:00
|
|
|
|
if (data.type === "block") {
|
|
|
|
|
|
data.isDetached = true;
|
|
|
|
|
|
delete data.block.id;
|
|
|
|
|
|
}
|
2024-01-14 22:06:03 +08:00
|
|
|
|
doOperations.push({
|
|
|
|
|
|
action: "updateAttrViewCell",
|
|
|
|
|
|
id: item.id,
|
|
|
|
|
|
avID,
|
2024-01-14 22:34:24 +08:00
|
|
|
|
keyID,
|
2024-01-14 22:06:03 +08:00
|
|
|
|
rowID,
|
|
|
|
|
|
data
|
|
|
|
|
|
});
|
2025-08-12 01:23:47 +08:00
|
|
|
|
item.element.innerHTML = renderCell(data, 0, showIcon);
|
2024-01-26 20:34:11 +08:00
|
|
|
|
renderCellAttr(item.element, data);
|
2024-01-14 22:34:24 +08:00
|
|
|
|
delete item.colId;
|
|
|
|
|
|
delete item.element;
|
2024-01-14 22:06:03 +08:00
|
|
|
|
undoOperations.push({
|
|
|
|
|
|
action: "updateAttrViewCell",
|
|
|
|
|
|
id: item.id,
|
|
|
|
|
|
avID,
|
2024-01-14 22:34:24 +08:00
|
|
|
|
keyID,
|
2024-01-14 22:06:03 +08:00
|
|
|
|
rowID,
|
|
|
|
|
|
data: item
|
|
|
|
|
|
});
|
2024-01-16 10:56:55 +08:00
|
|
|
|
});
|
2024-01-14 22:06:03 +08:00
|
|
|
|
});
|
|
|
|
|
|
focusBlock(nodeElement);
|
2024-01-14 22:42:11 +08:00
|
|
|
|
if (doOperations.length > 0) {
|
|
|
|
|
|
transaction(protyle, doOperations, undoOperations);
|
|
|
|
|
|
}
|
2024-01-16 10:56:55 +08:00
|
|
|
|
};
|
2024-03-22 11:08:21 +08:00
|
|
|
|
|
|
|
|
|
|
export const addDragFill = (cellElement: Element) => {
|
|
|
|
|
|
if (!cellElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
cellElement.classList.add("av__cell--active");
|
2024-04-07 23:33:02 +08:00
|
|
|
|
if (!cellElement.querySelector(".av__drag-fill")) {
|
2025-08-11 23:17:13 +08:00
|
|
|
|
const cellType = cellElement.getAttribute("data-dtype") as TAVCol;
|
|
|
|
|
|
if (["template", "rollup", "lineNumber", "created", "updated"].includes(cellType)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-04-07 23:33:02 +08:00
|
|
|
|
cellElement.insertAdjacentHTML("beforeend", `<div aria-label="${window.siyuan.languages.dragFill}" class="av__drag-fill ariaLabel"></div>`);
|
|
|
|
|
|
}
|
2024-03-22 16:58:25 +08:00
|
|
|
|
};
|
2025-06-15 11:38:51 +08:00
|
|
|
|
|
|
|
|
|
|
export const cellValueIsEmpty = (value: IAVCellValue) => {
|
|
|
|
|
|
if (value.type === "checkbox") {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2025-06-27 11:56:52 +08:00
|
|
|
|
if (["text", "block", "url", "phone", "email", "template"].includes(value.type)) {
|
2025-06-15 11:38:51 +08:00
|
|
|
|
return !value[value.type as "text"]?.content;
|
|
|
|
|
|
}
|
2025-06-27 11:56:52 +08:00
|
|
|
|
if (value.type === "number") {
|
|
|
|
|
|
return !value.number?.isNotEmpty;
|
|
|
|
|
|
}
|
2025-06-15 11:38:51 +08:00
|
|
|
|
if (["mSelect", "mAsset", "select"].includes(value.type)) {
|
2025-06-22 23:51:04 +08:00
|
|
|
|
if (value[(value.type === "select" ? "mSelect" : value.type) as "mSelect"]?.length > 0) {
|
2025-06-15 11:38:51 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (["date", "created", "updated"].includes(value.type)) {
|
|
|
|
|
|
return !value[value.type as "date"]?.isNotEmpty &&
|
|
|
|
|
|
!value[value.type as "date"]?.isNotEmpty2;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "relation") {
|
|
|
|
|
|
if (value.relation?.blockIDs && value.relation.blockIDs.length > 0) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (value.type === "rollup") {
|
|
|
|
|
|
if (value.rollup?.contents && value.rollup.contents.length > 0) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|