Vanessa 2023-07-17 12:54:24 +08:00
parent e6fb2fe2d2
commit 22c4a1554b
4 changed files with 77 additions and 57 deletions

View file

@ -110,7 +110,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
const cellElement = hasClosestByClassName(event.target, "av__cell");
if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) {
popTextCell(protyle, cellElement);
popTextCell(protyle, [cellElement]);
event.preventDefault();
event.stopPropagation();
return true;
@ -197,7 +197,7 @@ export const avContextmenu = (protyle: IProtyle, event: MouseEvent & { detail: a
icon: getColIconByType(cellElement.getAttribute("data-dtype") as TAVCol),
label: cellElement.textContent.trim(),
click() {
popTextCell(protyle, rowElement.querySelector(`.av__cell[data-col-id="${cellElement.dataset.colId}"]`));
popTextCell(protyle, Array.from(blockElement.querySelectorAll(`.av__row--select:not(.av__row--header) .av__cell[data-col-id="${cellElement.dataset.colId}"]`)));
}
});
});

View file

@ -281,18 +281,19 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
};
export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
const type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
const cellRect = cellElement.getBoundingClientRect();
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[]) => {
const type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
const cellRect = cellElements[0].getBoundingClientRect();
let html = "";
const style = `style="position:absolute;left: ${cellRect.left}px;top: ${cellRect.top}px;width:${Math.max(cellRect.width, 200)}px;height: ${cellRect.height}px"`;
const blockElement = hasClosestBlock(cellElement);
const blockElement = hasClosestBlock(cellElements[0]);
if (type === "block" || type === "text") {
html = `<textarea ${style} class="b3-text-field">${cellElement.textContent}</textarea>`;
html = `<textarea ${style} class="b3-text-field">${cellElements[0].textContent}</textarea>`;
} else if (type === "number") {
html = `<input type="number" value="${cellElement.textContent}" ${style} class="b3-text-field">`;
html = `<input type="number" value="${cellElements[0].textContent}" ${style} class="b3-text-field">`;
} else if (["select", "mSelect"].includes(type) && blockElement) {
openMenuPanel(protyle, blockElement, "select", {cellElement});
// TODO
openMenuPanel(protyle, blockElement, "select", {cellElement: cellElements[0]});
return;
}
window.siyuan.menus.menu.remove();
@ -305,14 +306,14 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
inputElement.select();
inputElement.focus();
inputElement.addEventListener("blur", () => {
updateCellValue(protyle, cellElement, type);
updateCellValue(protyle, type, cellElements);
});
inputElement.addEventListener("keydown", (event) => {
if (event.isComposing) {
return;
}
if (event.key === "Escape" || event.key === "Enter") {
updateCellValue(protyle, cellElement, type);
updateCellValue(protyle, type, cellElements);
event.preventDefault();
event.stopPropagation();
}
@ -325,25 +326,29 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
});
};
const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVCol) => {
const rowElement = hasClosestByClassName(cellElement, "av__row");
if (!rowElement) {
return;
}
const blockElement = hasClosestBlock(rowElement);
const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElement[]) => {
const blockElement = hasClosestBlock(cellElements[0]);
if (!blockElement) {
return;
}
const rowID = rowElement.getAttribute("data-id");
const avMaskElement = document.querySelector(".av__mask");
const cellId = cellElement.getAttribute("data-id");
const colId = cellElement.getAttribute("data-col-id");
const avMaskElement = document.querySelector(".av__mask")
const doOperations: IOperation[] = []
const undoOperations: IOperation[] = []
const avID = blockElement.getAttribute("data-av-id");
cellElements.forEach((item) => {
const rowElement = hasClosestByClassName(item, "av__row");
if (!rowElement) {
return;
}
const rowID = rowElement.getAttribute("data-id");
const cellId = item.getAttribute("data-id");
const colId = item.getAttribute("data-col-id");
const inputValue: { content: string | number, isNotEmpty?: boolean } = {
content: (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
};
const oldValue: { content: string | number, isNotEmpty?: boolean } = {
content: cellElement.textContent.trim()
content: item.textContent.trim()
};
if (type === "number") {
oldValue.content = parseFloat(oldValue.content as string);
@ -351,7 +356,7 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
inputValue.content = parseFloat(inputValue.content as string);
inputValue.isNotEmpty = !!inputValue.content;
}
transaction(protyle, [{
doOperations.push({
action: "updateAttrViewCell",
id: cellId,
avID,
@ -360,7 +365,8 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
data: {
[type]: inputValue
}
}], [{
})
undoOperations.push({
action: "updateAttrViewCell",
id: cellId,
avID,
@ -369,7 +375,9 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
data: {
[type]: oldValue
}
}]);
})
})
transaction(protyle, doOperations, undoOperations);
setTimeout(() => {
avMaskElement.remove();
});

View file

@ -4,6 +4,16 @@ import {transaction} from "../../wysiwyg/transaction";
import {fetchPost} from "../../../util/fetch";
import {getDefaultOperatorByType, setFilter} from "./filter";
import {genCellValue} from "./cell";
import {openMenuPanel} from "./openMenuPanel";
export const getEditHTML = (options: {
protyle: IProtyle,
blockElement: HTMLElement,
cellElement: HTMLElement,
data: IAV
}) => {
// TODO
}
export const getColIconByType = (type: TAVCol) => {
switch (type) {
@ -95,7 +105,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
icon: "iconEdit",
label: window.siyuan.languages.edit,
click() {
openMenuPanel(protyle, blockElement, "edit", {cellElement});
}
});
}

View file

@ -1,7 +1,7 @@
import {transaction} from "../../wysiwyg/transaction";
import {fetchPost} from "../../../util/fetch";
import {addCol} from "./addCol";
import {getColIconByType} from "./col";
import {getColIconByType, getEditHTML} from "./col";
import {setPosition} from "../../../util/setPosition";
import {hasClosestByAttribute} from "../../util/hasClosest";
import {bindSelectEvent, getSelectHTML, addSelectColAndCell, setSelectCol, removeSelectCell} from "./select";
@ -10,7 +10,7 @@ import {addSort, bindSortsEvent, getSortsHTML} from "./sort";
export const openMenuPanel = (protyle: IProtyle,
blockElement: HTMLElement,
type: "select" | "properties" | "config" | "sorts" | "filters" = "config",
type: "select" | "properties" | "config" | "sorts" | "filters" | "edit" = "config",
options?: any) => {
let avPanelElement = document.querySelector(".av__panel");
if (avPanelElement) {
@ -32,6 +32,8 @@ export const openMenuPanel = (protyle: IProtyle,
html = getFiltersHTML(data.view);
} else if (type === "select") {
html = getSelectHTML(data.view, options);
} else if (type === "edit") {
html = getEditHTML({protyle, data, blockElement, cellElement: options.cellElement});
}
document.body.insertAdjacentHTML("beforeend", `<div class="av__panel">
@ -41,7 +43,7 @@ export const openMenuPanel = (protyle: IProtyle,
avPanelElement = document.querySelector(".av__panel");
const menuElement = avPanelElement.lastElementChild as HTMLElement;
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
if (options && options.cellElement) {
if (type === "select") {
const cellRect = options.cellElement.getBoundingClientRect();
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
bindSelectEvent(protyle, data, menuElement, options);
@ -49,9 +51,10 @@ export const openMenuPanel = (protyle: IProtyle,
menuElement.querySelector("input").focus();
} else {
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
}
if (type === "sorts") {
bindSortsEvent(protyle, menuElement, data);
}
}
avPanelElement.addEventListener("dragstart", (event) => {
window.siyuan.dragElement = event.target as HTMLElement;
window.siyuan.dragElement.style.opacity = ".1";
@ -244,7 +247,6 @@ export const openMenuPanel = (protyle: IProtyle,
window.siyuan.dragElement = undefined;
}
});
avPanelElement.addEventListener("click", (event) => {
event.preventDefault();
let target = event.target as HTMLElement;