mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 09:30:14 +01:00
This commit is contained in:
parent
e6fb2fe2d2
commit
22c4a1554b
4 changed files with 77 additions and 57 deletions
|
|
@ -110,7 +110,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
|
||||||
|
|
||||||
const cellElement = hasClosestByClassName(event.target, "av__cell");
|
const cellElement = hasClosestByClassName(event.target, "av__cell");
|
||||||
if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) {
|
if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) {
|
||||||
popTextCell(protyle, cellElement);
|
popTextCell(protyle, [cellElement]);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -197,7 +197,7 @@ export const avContextmenu = (protyle: IProtyle, event: MouseEvent & { detail: a
|
||||||
icon: getColIconByType(cellElement.getAttribute("data-dtype") as TAVCol),
|
icon: getColIconByType(cellElement.getAttribute("data-dtype") as TAVCol),
|
||||||
label: cellElement.textContent.trim(),
|
label: cellElement.textContent.trim(),
|
||||||
click() {
|
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}"]`)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -281,18 +281,19 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
||||||
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[]) => {
|
||||||
const type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
const type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
||||||
const cellRect = cellElement.getBoundingClientRect();
|
const cellRect = cellElements[0].getBoundingClientRect();
|
||||||
let html = "";
|
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 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") {
|
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") {
|
} 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) {
|
} else if (["select", "mSelect"].includes(type) && blockElement) {
|
||||||
openMenuPanel(protyle, blockElement, "select", {cellElement});
|
// TODO
|
||||||
|
openMenuPanel(protyle, blockElement, "select", {cellElement: cellElements[0]});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.siyuan.menus.menu.remove();
|
window.siyuan.menus.menu.remove();
|
||||||
|
|
@ -305,14 +306,14 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
||||||
inputElement.select();
|
inputElement.select();
|
||||||
inputElement.focus();
|
inputElement.focus();
|
||||||
inputElement.addEventListener("blur", () => {
|
inputElement.addEventListener("blur", () => {
|
||||||
updateCellValue(protyle, cellElement, type);
|
updateCellValue(protyle, type, cellElements);
|
||||||
});
|
});
|
||||||
inputElement.addEventListener("keydown", (event) => {
|
inputElement.addEventListener("keydown", (event) => {
|
||||||
if (event.isComposing) {
|
if (event.isComposing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.key === "Escape" || event.key === "Enter") {
|
if (event.key === "Escape" || event.key === "Enter") {
|
||||||
updateCellValue(protyle, cellElement, type);
|
updateCellValue(protyle, type, cellElements);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
@ -325,25 +326,29 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVCol) => {
|
const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElement[]) => {
|
||||||
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
const blockElement = hasClosestBlock(cellElements[0]);
|
||||||
if (!rowElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const blockElement = hasClosestBlock(rowElement);
|
|
||||||
if (!blockElement) {
|
if (!blockElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rowID = rowElement.getAttribute("data-id");
|
|
||||||
const avMaskElement = document.querySelector(".av__mask");
|
const avMaskElement = document.querySelector(".av__mask")
|
||||||
const cellId = cellElement.getAttribute("data-id");
|
const doOperations: IOperation[] = []
|
||||||
const colId = cellElement.getAttribute("data-col-id");
|
const undoOperations: IOperation[] = []
|
||||||
const avID = blockElement.getAttribute("data-av-id");
|
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 } = {
|
const inputValue: { content: string | number, isNotEmpty?: boolean } = {
|
||||||
content: (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
|
content: (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
|
||||||
};
|
};
|
||||||
const oldValue: { content: string | number, isNotEmpty?: boolean } = {
|
const oldValue: { content: string | number, isNotEmpty?: boolean } = {
|
||||||
content: cellElement.textContent.trim()
|
content: item.textContent.trim()
|
||||||
};
|
};
|
||||||
if (type === "number") {
|
if (type === "number") {
|
||||||
oldValue.content = parseFloat(oldValue.content as string);
|
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.content = parseFloat(inputValue.content as string);
|
||||||
inputValue.isNotEmpty = !!inputValue.content;
|
inputValue.isNotEmpty = !!inputValue.content;
|
||||||
}
|
}
|
||||||
transaction(protyle, [{
|
doOperations.push({
|
||||||
action: "updateAttrViewCell",
|
action: "updateAttrViewCell",
|
||||||
id: cellId,
|
id: cellId,
|
||||||
avID,
|
avID,
|
||||||
|
|
@ -360,7 +365,8 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
|
||||||
data: {
|
data: {
|
||||||
[type]: inputValue
|
[type]: inputValue
|
||||||
}
|
}
|
||||||
}], [{
|
})
|
||||||
|
undoOperations.push({
|
||||||
action: "updateAttrViewCell",
|
action: "updateAttrViewCell",
|
||||||
id: cellId,
|
id: cellId,
|
||||||
avID,
|
avID,
|
||||||
|
|
@ -369,7 +375,9 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
|
||||||
data: {
|
data: {
|
||||||
[type]: oldValue
|
[type]: oldValue
|
||||||
}
|
}
|
||||||
}]);
|
})
|
||||||
|
})
|
||||||
|
transaction(protyle, doOperations, undoOperations);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
avMaskElement.remove();
|
avMaskElement.remove();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,16 @@ import {transaction} from "../../wysiwyg/transaction";
|
||||||
import {fetchPost} from "../../../util/fetch";
|
import {fetchPost} from "../../../util/fetch";
|
||||||
import {getDefaultOperatorByType, setFilter} from "./filter";
|
import {getDefaultOperatorByType, setFilter} from "./filter";
|
||||||
import {genCellValue} from "./cell";
|
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) => {
|
export const getColIconByType = (type: TAVCol) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -95,7 +105,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
|
||||||
icon: "iconEdit",
|
icon: "iconEdit",
|
||||||
label: window.siyuan.languages.edit,
|
label: window.siyuan.languages.edit,
|
||||||
click() {
|
click() {
|
||||||
|
openMenuPanel(protyle, blockElement, "edit", {cellElement});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import {transaction} from "../../wysiwyg/transaction";
|
import {transaction} from "../../wysiwyg/transaction";
|
||||||
import {fetchPost} from "../../../util/fetch";
|
import {fetchPost} from "../../../util/fetch";
|
||||||
import {addCol} from "./addCol";
|
import {addCol} from "./addCol";
|
||||||
import {getColIconByType} from "./col";
|
import {getColIconByType, getEditHTML} from "./col";
|
||||||
import {setPosition} from "../../../util/setPosition";
|
import {setPosition} from "../../../util/setPosition";
|
||||||
import {hasClosestByAttribute} from "../../util/hasClosest";
|
import {hasClosestByAttribute} from "../../util/hasClosest";
|
||||||
import {bindSelectEvent, getSelectHTML, addSelectColAndCell, setSelectCol, removeSelectCell} from "./select";
|
import {bindSelectEvent, getSelectHTML, addSelectColAndCell, setSelectCol, removeSelectCell} from "./select";
|
||||||
|
|
@ -10,7 +10,7 @@ import {addSort, bindSortsEvent, getSortsHTML} from "./sort";
|
||||||
|
|
||||||
export const openMenuPanel = (protyle: IProtyle,
|
export const openMenuPanel = (protyle: IProtyle,
|
||||||
blockElement: HTMLElement,
|
blockElement: HTMLElement,
|
||||||
type: "select" | "properties" | "config" | "sorts" | "filters" = "config",
|
type: "select" | "properties" | "config" | "sorts" | "filters" | "edit" = "config",
|
||||||
options?: any) => {
|
options?: any) => {
|
||||||
let avPanelElement = document.querySelector(".av__panel");
|
let avPanelElement = document.querySelector(".av__panel");
|
||||||
if (avPanelElement) {
|
if (avPanelElement) {
|
||||||
|
|
@ -32,6 +32,8 @@ export const openMenuPanel = (protyle: IProtyle,
|
||||||
html = getFiltersHTML(data.view);
|
html = getFiltersHTML(data.view);
|
||||||
} else if (type === "select") {
|
} else if (type === "select") {
|
||||||
html = getSelectHTML(data.view, options);
|
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">
|
document.body.insertAdjacentHTML("beforeend", `<div class="av__panel">
|
||||||
|
|
@ -41,7 +43,7 @@ export const openMenuPanel = (protyle: IProtyle,
|
||||||
avPanelElement = document.querySelector(".av__panel");
|
avPanelElement = document.querySelector(".av__panel");
|
||||||
const menuElement = avPanelElement.lastElementChild as HTMLElement;
|
const menuElement = avPanelElement.lastElementChild as HTMLElement;
|
||||||
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
||||||
if (options && options.cellElement) {
|
if (type === "select") {
|
||||||
const cellRect = options.cellElement.getBoundingClientRect();
|
const cellRect = options.cellElement.getBoundingClientRect();
|
||||||
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
||||||
bindSelectEvent(protyle, data, menuElement, options);
|
bindSelectEvent(protyle, data, menuElement, options);
|
||||||
|
|
@ -49,9 +51,10 @@ export const openMenuPanel = (protyle: IProtyle,
|
||||||
menuElement.querySelector("input").focus();
|
menuElement.querySelector("input").focus();
|
||||||
} else {
|
} else {
|
||||||
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
}
|
if (type === "sorts") {
|
||||||
|
|
||||||
bindSortsEvent(protyle, menuElement, data);
|
bindSortsEvent(protyle, menuElement, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
avPanelElement.addEventListener("dragstart", (event) => {
|
avPanelElement.addEventListener("dragstart", (event) => {
|
||||||
window.siyuan.dragElement = event.target as HTMLElement;
|
window.siyuan.dragElement = event.target as HTMLElement;
|
||||||
window.siyuan.dragElement.style.opacity = ".1";
|
window.siyuan.dragElement.style.opacity = ".1";
|
||||||
|
|
@ -244,7 +247,6 @@ export const openMenuPanel = (protyle: IProtyle,
|
||||||
window.siyuan.dragElement = undefined;
|
window.siyuan.dragElement = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
avPanelElement.addEventListener("click", (event) => {
|
avPanelElement.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let target = event.target as HTMLElement;
|
let target = event.target as HTMLElement;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue