This commit is contained in:
Vanessa 2023-07-09 23:55:29 +08:00
parent 9c0aef93db
commit f4a8de4a14
7 changed files with 75 additions and 76 deletions

View file

@ -30,7 +30,6 @@ import {resize} from "./util/resize";
import {getDocByScroll} from "./scroll/saveScroll"; import {getDocByScroll} from "./scroll/saveScroll";
import {App} from "../index"; import {App} from "../index";
import {insertHTML} from "./util/insertHTML"; import {insertHTML} from "./util/insertHTML";
import {showColMenu} from "./render/av/col";
import {avRender} from "./render/av/render"; import {avRender} from "./render/av/render";
export class Protyle { export class Protyle {

View file

@ -6,7 +6,7 @@ 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 type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
const cellRect = cellElement.getBoundingClientRect(); const cellRect = cellElement.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(cellElement);
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">${cellElement.textContent}</textarea>`;
@ -58,8 +58,8 @@ const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVC
const cellId = cellElement.getAttribute("data-id"); const cellId = cellElement.getAttribute("data-id");
const avId = blockElement.getAttribute("data-av-id"); const avId = blockElement.getAttribute("data-av-id");
const rowId = rowElement.getAttribute("data-id"); const rowId = rowElement.getAttribute("data-id");
let inputValue: string | number = (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value let inputValue: string | number = (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value;
let oldValue: string | number = cellElement.textContent.trim() let oldValue: string | number = cellElement.textContent.trim();
if (type === "number") { if (type === "number") {
inputValue = parseFloat(inputValue); inputValue = parseFloat(inputValue);
oldValue = parseFloat(oldValue); oldValue = parseFloat(oldValue);

View file

@ -2,7 +2,7 @@ import {hasClosestBlock} from "../../util/hasClosest";
import {Menu} from "../../../plugin/Menu"; import {Menu} from "../../../plugin/Menu";
import {transaction} from "../../wysiwyg/transaction"; import {transaction} from "../../wysiwyg/transaction";
import {fetchPost} from "../../../util/fetch"; import {fetchPost} from "../../../util/fetch";
import {setFilter} from "./openMenuPanel"; import {setFilter} from "./filter";
export const getColIconByType = (type: TAVCol) => { export const getColIconByType = (type: TAVCol) => {
switch (type) { switch (type) {

View file

@ -22,14 +22,14 @@ export const setFilter = (options: {
cellValue = { cellValue = {
content: parseFloat(textElement.value), content: parseFloat(textElement.value),
isNotEmpty: true isNotEmpty: true
} };
} else { } else {
cellValue = {} cellValue = {};
} }
} else { } else {
cellValue = { cellValue = {
content: textElement.value content: textElement.value
} };
} }
filter.value[colType] = cellValue; filter.value[colType] = cellValue;
filter.operator = (window.siyuan.menus.menu.element.querySelector(".b3-select") as HTMLSelectElement).value as TAVFilterOperator; filter.operator = (window.siyuan.menus.menu.element.querySelector(".b3-select") as HTMLSelectElement).value as TAVFilterOperator;
@ -128,9 +128,9 @@ export const addFilter = (options: {
icon: getColIconByType(column.type), icon: getColIconByType(column.type),
click: () => { click: () => {
const oldFilters = Object.assign([], options.data.filters); const oldFilters = Object.assign([], options.data.filters);
let cellValue = {} let cellValue = {};
if (column.type !== "number") { if (column.type !== "number") {
cellValue = {content: ""} cellValue = {content: ""};
} }
options.data.filters.push({ options.data.filters.push({
column: column.id, column: column.id,

View file

@ -5,7 +5,7 @@ import {getColIconByType} 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, setSelectOption} from "./select"; import {bindSelectEvent, getSelectHTML, setSelectOption} from "./select";
import {addFilter, getFiltersHTML} from "./filter"; import {addFilter, getFiltersHTML, setFilter} from "./filter";
import {addSort, bindSortsEvent, getSortsHTML} from "./sort"; import {addSort, bindSortsEvent, getSortsHTML} from "./sort";
export const openMenuPanel = (protyle: IProtyle, export const openMenuPanel = (protyle: IProtyle,
@ -80,17 +80,17 @@ export const openMenuPanel = (protyle: IProtyle,
} }
const sourceId = sourceElement.dataset.id; const sourceId = sourceElement.dataset.id;
const targetId = targetElement.dataset.id; const targetId = targetElement.dataset.id;
const isTop = targetElement.classList.contains("dragover__top") const isTop = targetElement.classList.contains("dragover__top");
if (type !== "columns") { if (type !== "columns") {
const changeData = (type === "sorts" ? data.sorts : data.filters) as IAVFilter[] const changeData = (type === "sorts" ? data.sorts : data.filters) as IAVFilter[];
const oldData = Object.assign([], changeData); const oldData = Object.assign([], changeData);
let targetFilter: IAVFilter let targetFilter: IAVFilter;
changeData.find((filter, index: number) => { changeData.find((filter, index: number) => {
if (filter.column === sourceId) { if (filter.column === sourceId) {
targetFilter = changeData.splice(index, 1)[0]; targetFilter = changeData.splice(index, 1)[0];
return true; return true;
} }
}) });
changeData.find((filter, index: number) => { changeData.find((filter, index: number) => {
if (filter.column === targetId) { if (filter.column === targetId) {
if (isTop) { if (isTop) {
@ -100,7 +100,7 @@ export const openMenuPanel = (protyle: IProtyle,
} }
return true; return true;
} }
}) });
transaction(protyle, [{ transaction(protyle, [{
action: "setAttrView", action: "setAttrView",
@ -132,13 +132,13 @@ export const openMenuPanel = (protyle: IProtyle,
previousID: sourceElement.previousElementSibling?.getAttribute("data-id") || "", previousID: sourceElement.previousElementSibling?.getAttribute("data-id") || "",
id: sourceId, id: sourceId,
}]); }]);
let column: IAVColumn let column: IAVColumn;
data.columns.find((item, index: number) => { data.columns.find((item, index: number) => {
if (item.id === sourceId) { if (item.id === sourceId) {
column = data.columns.splice(index, 1)[0]; column = data.columns.splice(index, 1)[0];
return true; return true;
} }
}) });
data.columns.find((item, index: number) => { data.columns.find((item, index: number) => {
if (item.id === targetId) { if (item.id === targetId) {
if (isTop) { if (isTop) {
@ -148,10 +148,10 @@ export const openMenuPanel = (protyle: IProtyle,
} }
return true; return true;
} }
}) });
menuElement.innerHTML = getPropertiesHTML(data) menuElement.innerHTML = getPropertiesHTML(data);
}); });
let dragoverElement: HTMLElement let dragoverElement: HTMLElement;
avPanelElement.addEventListener("dragover", (event: DragEvent) => { avPanelElement.addEventListener("dragover", (event: DragEvent) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
const targetElement = hasClosestByAttribute(target, "data-id", null); const targetElement = hasClosestByAttribute(target, "data-id", null);
@ -177,9 +177,9 @@ export const openMenuPanel = (protyle: IProtyle,
targetElement.classList.remove("dragover__top", "dragover__bottom"); targetElement.classList.remove("dragover__top", "dragover__bottom");
} }
}); });
avPanelElement.addEventListener("dragend", (event) => { avPanelElement.addEventListener("dragend", () => {
if (window.siyuan.dragElement) { if (window.siyuan.dragElement) {
window.siyuan.dragElement.style.opacity = "" window.siyuan.dragElement.style.opacity = "";
window.siyuan.dragElement = undefined; window.siyuan.dragElement = undefined;
} }
}); });
@ -432,7 +432,7 @@ export const openMenuPanel = (protyle: IProtyle,
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (type === "editOption") { } else if (type === "editOption") {
setSelectOption(protyle, data, options, target) setSelectOption(protyle, data, options, target);
event.stopPropagation(); event.stopPropagation();
break; break;
} }

View file

@ -65,7 +65,7 @@ ${column.wrap ? "" : "white-space: nowrap;"}">
if (cell.value?.select.content) { if (cell.value?.select.content) {
text = `<span class="av__celltext"><span class="b3-chip b3-chip--middle" style="background-color:var(--b3-font-background${cell.value.select.color});color:var(--b3-font-color${cell.value.select.color})">${cell.value.select.content}</span></span>`; text = `<span class="av__celltext"><span class="b3-chip b3-chip--middle" style="background-color:var(--b3-font-background${cell.value.select.color});color:var(--b3-font-color${cell.value.select.color})">${cell.value.select.content}</span></span>`;
} else { } else {
text = `<span class="av__celltext"></span>`; text = "<span class=\"av__celltext\"></span>";
} }
} else if (cell.valueType === "mSelect") { } else if (cell.valueType === "mSelect") {
text = `<span class="av__celltext">${cell.value?.mSelect.content || ""}</span>`; text = `<span class="av__celltext">${cell.value?.mSelect.content || ""}</span>`;

View file

@ -26,7 +26,7 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[
if (key === item.name) { if (key === item.name) {
hasMatch = true; hasMatch = true;
} }
}) });
} }
if (!hasMatch && key) { if (!hasMatch && key) {
const colorIndex = (options?.length || 0) % 13 + 1; const colorIndex = (options?.length || 0) % 13 + 1;
@ -37,10 +37,10 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[
</span> </span>
</div> </div>
<span class="b3-menu__accelerator">Enter</span> <span class="b3-menu__accelerator">Enter</span>
</button>` </button>`;
} }
return html; return html;
} };
export const setSelectOption = (protyle: IProtyle, data: IAV, options: { export const setSelectOption = (protyle: IProtyle, data: IAV, options: {
cellElement: HTMLElement; cellElement: HTMLElement;
@ -64,33 +64,33 @@ export const setSelectOption = (protyle: IProtyle, data: IAV, options: {
newName: name newName: name
}, },
}]); }]);
}) });
if (menu.isOpen) { if (menu.isOpen) {
return; return;
} }
const menuElement = hasClosestByClassName(target, "b3-menu"); const menuElement = hasClosestByClassName(target, "b3-menu");
if (!menuElement) { if (!menuElement) {
return return;
} }
const color = target.parentElement.dataset.color; const color = target.parentElement.dataset.color;
const colId = options.cellElement.dataset.colId; const colId = options.cellElement.dataset.colId;
menu.addItem({ menu.addItem({
iconHTML: "", iconHTML: "",
label: `<input class="b3-text-field" style="margin: 4px 0" value="${name}">` label: `<input class="b3-text-field" style="margin: 4px 0" value="${name}">`
}) });
menu.addItem({ menu.addItem({
label: window.siyuan.languages.delete, label: window.siyuan.languages.delete,
icon: "iconTrashcan", icon: "iconTrashcan",
click() { click() {
confirmDialog(window.siyuan.languages.deleteOpConfirm, window.siyuan.languages.confirmDelete, () => { confirmDialog(window.siyuan.languages.deleteOpConfirm, window.siyuan.languages.confirmDelete, () => {
let colOptions: { name: string, color: string }[] = [] let colOptions: { name: string, color: string }[] = [];
data.columns.find(column => { data.columns.find(column => {
if (column.id === colId) { if (column.id === colId) {
colOptions = column.options; colOptions = column.options;
return true; return true;
} }
}) });
const newName = target.parentElement.dataset.name const newName = target.parentElement.dataset.name;
transaction(protyle, [{ transaction(protyle, [{
action: "removeAttrViewColOption", action: "removeAttrViewColOption",
id: colId, id: colId,
@ -107,15 +107,15 @@ export const setSelectOption = (protyle: IProtyle, data: IAV, options: {
colOptions.splice(index, 1); colOptions.splice(index, 1);
return true; return true;
} }
}) });
menuElement.innerHTML = getSelectHTML(data, options); menuElement.innerHTML = getSelectHTML(data, options);
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);
}) });
} }
}) });
menu.addSeparator() menu.addSeparator();
Array.from(Array(13).keys()).forEach(index => { Array.from(Array(13).keys()).forEach(index => {
menu.addItem({ menu.addItem({
current: parseInt(color) === index + 1, current: parseInt(color) === index + 1,
@ -140,87 +140,87 @@ export const setSelectOption = (protyle: IProtyle, data: IAV, options: {
}, },
}]); }]);
} }
}) });
}) });
const rect = target.getBoundingClientRect(); const rect = target.getBoundingClientRect();
menu.open({ menu.open({
x: rect.left, x: rect.left,
y: rect.bottom, y: rect.bottom,
h: rect.height, h: rect.height,
}) });
const inputElement = window.siyuan.menus.menu.element.querySelector("input"); const inputElement = window.siyuan.menus.menu.element.querySelector("input");
inputElement.select(); inputElement.select();
} };
export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLElement, options: { export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLElement, options: {
cellElement: HTMLElement cellElement: HTMLElement
}) => { }) => {
const inputElement = menuElement.querySelector("input"); const inputElement = menuElement.querySelector("input");
const rowId = options.cellElement.parentElement.dataset.id const rowId = options.cellElement.parentElement.dataset.id;
const colId = options.cellElement.dataset.colId; const colId = options.cellElement.dataset.colId;
const cellId = options.cellElement.dataset.id const cellId = options.cellElement.dataset.id;
let colData: IAVColumn; let colData: IAVColumn;
data.columns.find((item: IAVColumn) => { data.columns.find((item: IAVColumn) => {
if (item.id === colId) { if (item.id === colId) {
colData = item; colData = item;
return; return;
} }
}) });
if (!colData.options) { if (!colData.options) {
colData.options = []; colData.options = [];
} }
let cellData: IAVCell let cellData: IAVCell;
data.rows.find(row => { data.rows.find(row => {
if (row.id === rowId) { if (row.id === rowId) {
row.cells.find(cell => { row.cells.find(cell => {
if (cell.id === cellId) { if (cell.id === cellId) {
cellData = cell cellData = cell;
return true; return true;
} }
}) });
return true; return true;
} }
}) });
inputElement.addEventListener("input", (event: InputEvent) => { inputElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) { if (event.isComposing) {
return return;
} }
menuElement.lastElementChild.innerHTML = filterSelectHTML(inputElement.value, colData.options); menuElement.lastElementChild.innerHTML = filterSelectHTML(inputElement.value, colData.options);
}) });
inputElement.addEventListener("compositionend", (event: InputEvent) => { inputElement.addEventListener("compositionend", (event: InputEvent) => {
if (event.isComposing) { if (event.isComposing) {
return return;
} }
menuElement.lastElementChild.innerHTML = filterSelectHTML(inputElement.value, colData.options); menuElement.lastElementChild.innerHTML = filterSelectHTML(inputElement.value, colData.options);
}) });
inputElement.addEventListener("keydown", (event: KeyboardEvent) => { inputElement.addEventListener("keydown", (event: KeyboardEvent) => {
if (event.isComposing) { if (event.isComposing) {
return return;
} }
let currentElement = upDownHint(menuElement.lastElementChild, event, "b3-menu__item--current"); let currentElement = upDownHint(menuElement.lastElementChild, event, "b3-menu__item--current");
if (event.key === "Enter") { if (event.key === "Enter") {
if (!currentElement) { if (!currentElement) {
currentElement = menuElement.querySelector(".b3-menu__item--current"); currentElement = menuElement.querySelector(".b3-menu__item--current");
} }
let oldValue let oldValue;
if (colData.type !== "select") { if (colData.type !== "select") {
oldValue = Object.assign([], cellData.value.mSelect.content); oldValue = Object.assign([], cellData.value.mSelect.content);
cellData.value.mSelect.content.push({ cellData.value.mSelect.content.push({
color: currentElement.dataset.color, color: currentElement.dataset.color,
content: currentElement.dataset.name content: currentElement.dataset.name
}) });
} else { } else {
oldValue = Object.assign({}, cellData.value.select); oldValue = Object.assign({}, cellData.value.select);
cellData.value.select = { cellData.value.select = {
color: currentElement.dataset.color, color: currentElement.dataset.color,
content: currentElement.dataset.name content: currentElement.dataset.name
} };
} }
if (currentElement.querySelector(".b3-menu__accelerator")) { if (currentElement.querySelector(".b3-menu__accelerator")) {
colData.options.push({ colData.options.push({
color: currentElement.dataset.color, color: currentElement.dataset.color,
name: currentElement.dataset.name name: currentElement.dataset.name
}) });
transaction(protyle, [{ transaction(protyle, [{
action: "updateAttrViewColOptions", action: "updateAttrViewColOptions",
id: colId, id: colId,
@ -261,44 +261,44 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE
menuElement.parentElement.remove(); menuElement.parentElement.remove();
} }
} }
}) });
} };
export const getSelectHTML = (data: IAV, options: { cellElement: HTMLElement }) => { export const getSelectHTML = (data: IAV, options: { cellElement: HTMLElement }) => {
const cellId = options.cellElement.dataset.id const cellId = options.cellElement.dataset.id;
const colId = options.cellElement.dataset["colId"] const colId = options.cellElement.dataset["colId"];
const colData = data.columns.find(item => { const colData = data.columns.find(item => {
if (item.id === colId) { if (item.id === colId) {
return item return item;
} }
}) });
let selectedHTML = "" let selectedHTML = "";
data.rows.find(row => { data.rows.find(row => {
if (options.cellElement.parentElement.dataset.id === row.id) { if (options.cellElement.parentElement.dataset.id === row.id) {
row.cells.find(cell => { row.cells.find(cell => {
if (cell.id === cellId && cell.value) { if (cell.id === cellId && cell.value) {
if (colData.type === "mSelect") { if (colData.type === "mSelect") {
cell.value.mSelect?.content.forEach((value: string) => { cell.value.mSelect?.content.forEach((value: string) => {
let colorIndex = "" let colorIndex = "";
colData.options.find(option => { colData.options.find(option => {
if (option.name === value) { if (option.name === value) {
colorIndex = option.color colorIndex = option.color;
} }
}) });
selectedHTML += `<div class="b3-chip" style="background-color:var(--b3-font-background${colorIndex});color:var(--b3-font-color${colorIndex})">${value}<svg class="b3-chip__close" data-type="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>` selectedHTML += `<div class="b3-chip" style="background-color:var(--b3-font-background${colorIndex});color:var(--b3-font-color${colorIndex})">${value}<svg class="b3-chip__close" data-type="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>`;
}) });
} else { } else {
selectedHTML += `<div class="b3-chip" style="background-color:var(--b3-font-background${cell.value.select.color})";color:var(--b3-font-color${cell.value.select.color})>${options.cellElement.textContent.trim()}<svg class="b3-chip__close" data-type="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>` selectedHTML += `<div class="b3-chip" style="background-color:var(--b3-font-background${cell.value.select.color})";color:var(--b3-font-color${cell.value.select.color})>${options.cellElement.textContent.trim()}<svg class="b3-chip__close" data-type="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>`;
} }
return true; return true;
} }
}) });
return true return true;
} }
}) });
return `<div class="b3-chips"> return `<div class="b3-chips">
${selectedHTML} ${selectedHTML}
<input class="b3-text-field fn__block"> <input class="b3-text-field fn__block">
</div> </div>
<div>${filterSelectHTML("", colData.options)}</div>` <div>${filterSelectHTML("", colData.options)}</div>`;
} };