|
@@ -6,6 +6,7 @@ import * as dayjs from "dayjs";
|
|
import {unicode2Emoji} from "../../../emoji";
|
|
import {unicode2Emoji} from "../../../emoji";
|
|
import {focusBlock} from "../../util/selection";
|
|
import {focusBlock} from "../../util/selection";
|
|
import {isMac} from "../../util/compatibility";
|
|
import {isMac} from "../../util/compatibility";
|
|
|
|
+import {hasClosestByClassName} from "../../util/hasClosest";
|
|
|
|
|
|
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
|
|
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
|
|
let avElements: Element[] = [];
|
|
let avElements: Element[] = [];
|
|
@@ -45,20 +46,41 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) =
|
|
let selectCellId = "";
|
|
let selectCellId = "";
|
|
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
|
|
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
|
|
if (selectCellElement) {
|
|
if (selectCellElement) {
|
|
- selectCellId = selectCellElement.parentElement.dataset.id + Constants.ZWSP + selectCellElement.getAttribute("data-col-id");
|
|
|
|
|
|
+ selectCellId = (hasClosestByClassName(selectCellElement, "av__row") as HTMLElement).dataset.id + Constants.ZWSP + selectCellElement.getAttribute("data-col-id");
|
|
}
|
|
}
|
|
fetchPost("/api/av/renderAttributeView", {
|
|
fetchPost("/api/av/renderAttributeView", {
|
|
id: e.getAttribute("data-av-id"),
|
|
id: e.getAttribute("data-av-id"),
|
|
}, (response) => {
|
|
}, (response) => {
|
|
const data = response.data.view as IAVTable;
|
|
const data = response.data.view as IAVTable;
|
|
// header
|
|
// header
|
|
- let tableHTML = '<div class="av__row av__row--header"><div class="av__firstcol"><svg style="height: 32px"><use xlink:href="#iconUncheck"></use></svg></div>';
|
|
|
|
- let calcHTML = "";
|
|
|
|
- data.columns.forEach((column: IAVColumn) => {
|
|
|
|
|
|
+ let tableHTML = '<div class="av__row av__row--header"><div class="av__firstcol av__colsticky"><svg><use xlink:href="#iconUncheck"></use></svg></div>';
|
|
|
|
+ let calcHTML = '<div style="width: 24px"></div>';
|
|
|
|
+ let pinIndex = -1;
|
|
|
|
+ let pinMaxIndex = -1;
|
|
|
|
+ let indexWidth = 0;
|
|
|
|
+ const eWidth = e.clientWidth;
|
|
|
|
+ data.columns.forEach((item, index) => {
|
|
|
|
+ if (!item.hidden) {
|
|
|
|
+ if (item.pin) {
|
|
|
|
+ pinIndex = index;
|
|
|
|
+ }
|
|
|
|
+ if (indexWidth < eWidth - 200) {
|
|
|
|
+ indexWidth += parseInt(item.width) || 200;
|
|
|
|
+ pinMaxIndex = index;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ pinIndex = Math.min(pinIndex, pinMaxIndex);
|
|
|
|
+ if (pinIndex > -1) {
|
|
|
|
+ tableHTML = '<div class="av__row av__row--header"><div class="av__colsticky"><div class="av__firstcol"><svg><use xlink:href="#iconUncheck"></use></svg></div>'
|
|
|
|
+ calcHTML = '<div class="av__colsticky"><div style="width: 24px"></div>'
|
|
|
|
+ }
|
|
|
|
+ data.columns.forEach((column: IAVColumn, index: number) => {
|
|
if (column.hidden) {
|
|
if (column.hidden) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- tableHTML += `<div class="av__cell" data-col-id="${column.id}" data-icon="${column.icon}" data-dtype="${column.type}"
|
|
|
|
|
|
+ tableHTML += `<div class="av__cell" data-col-id="${column.id}"
|
|
|
|
+data-icon="${column.icon}" data-dtype="${column.type}" data-pin="${column.pin}"
|
|
style="width: ${column.width || "200px"};
|
|
style="width: ${column.width || "200px"};
|
|
${column.wrap ? "" : "white-space: nowrap;"}">
|
|
${column.wrap ? "" : "white-space: nowrap;"}">
|
|
<div draggable="true" class="av__cellheader">
|
|
<div draggable="true" class="av__cellheader">
|
|
@@ -67,8 +89,14 @@ ${column.wrap ? "" : "white-space: nowrap;"}">
|
|
</div>
|
|
</div>
|
|
<div class="av__widthdrag"></div>
|
|
<div class="av__widthdrag"></div>
|
|
</div>`;
|
|
</div>`;
|
|
|
|
+ if (pinIndex === index) {
|
|
|
|
+ tableHTML += '</div>'
|
|
|
|
+ }
|
|
calcHTML += `<div class="av__calc${calcHTML ? "" : " av__calc--show"}${column.calc && column.calc.operator !== "" ? " av__calc--ashow" : ""}" data-col-id="${column.id}" data-dtype="${column.type}" data-operator="${column.calc?.operator || ""}"
|
|
calcHTML += `<div class="av__calc${calcHTML ? "" : " av__calc--show"}${column.calc && column.calc.operator !== "" ? " av__calc--ashow" : ""}" data-col-id="${column.id}" data-dtype="${column.type}" data-operator="${column.calc?.operator || ""}"
|
|
style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use xlink:href="#iconDown"></use></svg>' + window.siyuan.languages.calc}</div>`;
|
|
style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use xlink:href="#iconDown"></use></svg>' + window.siyuan.languages.calc}</div>`;
|
|
|
|
+ if (pinIndex === index) {
|
|
|
|
+ calcHTML += '</div>'
|
|
|
|
+ }
|
|
});
|
|
});
|
|
tableHTML += `<div class="block__icons" style="min-height: auto">
|
|
tableHTML += `<div class="block__icons" style="min-height: auto">
|
|
<div class="block__icon block__icon--show" data-type="av-header-add"><svg><use xlink:href="#iconAdd"></use></svg></div>
|
|
<div class="block__icon block__icon--show" data-type="av-header-add"><svg><use xlink:href="#iconAdd"></use></svg></div>
|
|
@@ -82,8 +110,13 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
|
|
<div class="av__gutters">
|
|
<div class="av__gutters">
|
|
<button class="ariaLabel" data-action="add" data-position="right" aria-label="${isMac() ? window.siyuan.languages.addBelowAbove : window.siyuan.languages.addBelowAbove.replace("⌥", "Alt+")}"><svg><use xlink:href="#iconAdd"></use></svg></button>
|
|
<button class="ariaLabel" data-action="add" data-position="right" aria-label="${isMac() ? window.siyuan.languages.addBelowAbove : window.siyuan.languages.addBelowAbove.replace("⌥", "Alt+")}"><svg><use xlink:href="#iconAdd"></use></svg></button>
|
|
<button class="ariaLabel" draggable="true" data-position="right" aria-label="${window.siyuan.languages.rowTip}"><svg><use xlink:href="#iconDrag"></use></svg></button>
|
|
<button class="ariaLabel" draggable="true" data-position="right" aria-label="${window.siyuan.languages.rowTip}"><svg><use xlink:href="#iconDrag"></use></svg></button>
|
|
-</div>
|
|
|
|
-<div class="av__firstcol"><svg><use xlink:href="#iconUncheck"></use></svg></div>`;
|
|
|
|
|
|
+</div>`;
|
|
|
|
+ if (pinIndex > -1) {
|
|
|
|
+ tableHTML += '<div class="av__colsticky"><div class="av__firstcol"><svg><use xlink:href="#iconUncheck"></use></svg></div>'
|
|
|
|
+ } else {
|
|
|
|
+ tableHTML += `<div class="av__firstcol av__colsticky"><svg><use xlink:href="#iconUncheck"></use></svg></div>`
|
|
|
|
+ }
|
|
|
|
+
|
|
row.cells.forEach((cell, index) => {
|
|
row.cells.forEach((cell, index) => {
|
|
if (data.columns[index].hidden) {
|
|
if (data.columns[index].hidden) {
|
|
return;
|
|
return;
|
|
@@ -144,13 +177,11 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
|
|
});
|
|
});
|
|
if (!text) {
|
|
if (!text) {
|
|
text = '<span class="av__celltext"></span>';
|
|
text = '<span class="av__celltext"></span>';
|
|
- } else {
|
|
|
|
- text = `<span class="av__celltext">${text}</span>`;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cell.valueType)) {
|
|
if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cell.valueType)) {
|
|
if (cell.value && cell.value[cell.valueType as "url"].content) {
|
|
if (cell.value && cell.value[cell.valueType as "url"].content) {
|
|
- text += `<span ${cell.valueType !== "number" ? "" : 'style="right:auto;left:5px"'} data-type="copy" class="b3-tooltips b3-tooltips__n block__icon" aria-label="${window.siyuan.languages.copy}"><svg><use xlink:href="#iconCopy"></use></svg></span>`;
|
|
|
|
|
|
+ text += `<span ${cell.valueType !== "number" ? "" : 'style="right:auto;left:5px"'} data-type="copy" class="block__icon"><svg><use xlink:href="#iconCopy"></use></svg></span>`;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tableHTML += `<div class="av__cell" data-id="${cell.id}" data-col-id="${data.columns[index].id}"
|
|
tableHTML += `<div class="av__cell" data-id="${cell.id}" data-col-id="${data.columns[index].id}"
|
|
@@ -161,6 +192,10 @@ ${cell.bgColor ? `background-color:${cell.bgColor};` : ""}
|
|
white-space: ${data.columns[index].wrap ? "pre-wrap" : "nowrap"};
|
|
white-space: ${data.columns[index].wrap ? "pre-wrap" : "nowrap"};
|
|
${cell.valueType !== "number" ? "" : "flex-direction: row-reverse;"}
|
|
${cell.valueType !== "number" ? "" : "flex-direction: row-reverse;"}
|
|
${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|
${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|
|
|
+
|
|
|
|
+ if (pinIndex === index) {
|
|
|
|
+ tableHTML += '</div>'
|
|
|
|
+ }
|
|
});
|
|
});
|
|
tableHTML += "<div></div></div>";
|
|
tableHTML += "<div></div></div>";
|
|
});
|
|
});
|
|
@@ -172,7 +207,7 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|
</div>`;
|
|
</div>`;
|
|
});
|
|
});
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
- e.firstElementChild.outerHTML = `<div class="av__container">
|
|
|
|
|
|
+ e.firstElementChild.outerHTML = `<div class="av__container" style="--av-background:${e.style.backgroundColor || "var(--b3-theme-background)"}">
|
|
<div class="av__header">
|
|
<div class="av__header">
|
|
<div class="layout-tab-bar fn__flex">
|
|
<div class="layout-tab-bar fn__flex">
|
|
${tabHTML}
|
|
${tabHTML}
|
|
@@ -199,10 +234,12 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|
<div style="float: left;">
|
|
<div style="float: left;">
|
|
${tableHTML}
|
|
${tableHTML}
|
|
<div class="av__row--add">
|
|
<div class="av__row--add">
|
|
- <svg><use xlink:href="#iconAdd"></use></svg>
|
|
|
|
- ${window.siyuan.languages.addAttr}
|
|
|
|
|
|
+ <div class="av__colsticky">
|
|
|
|
+ <svg><use xlink:href="#iconAdd"></use></svg>
|
|
|
|
+ ${window.siyuan.languages.addAttr}
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- <div class="av__row--footer"><div style="width: 24px"></div>${calcHTML}</div>
|
|
|
|
|
|
+ <div class="av__row--footer">${calcHTML}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>`;
|
|
</div>`;
|
|
@@ -223,7 +260,9 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|
if (newCellElement) {
|
|
if (newCellElement) {
|
|
newCellElement.classList.add("av__cell--select");
|
|
newCellElement.classList.add("av__cell--select");
|
|
}
|
|
}
|
|
- focusBlock(e);
|
|
|
|
|
|
+ if (!document.querySelector(".av__panel")) {
|
|
|
|
+ focusBlock(e);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
if (cb) {
|
|
if (cb) {
|
|
cb();
|
|
cb();
|
|
@@ -270,7 +309,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation, isUndo: bool
|
|
avRender(item, protyle, () => {
|
|
avRender(item, protyle, () => {
|
|
// https://github.com/siyuan-note/siyuan/issues/9599
|
|
// https://github.com/siyuan-note/siyuan/issues/9599
|
|
if (!isUndo && operation.action === "insertAttrViewBlock" && operation.isDetached) {
|
|
if (!isUndo && operation.action === "insertAttrViewBlock" && operation.isDetached) {
|
|
- popTextCell(protyle, [item.querySelector(`.av__row[data-id="${operation.srcIDs[0]}"] > .av__cell[data-detached="true"]`)], "block");
|
|
|
|
|
|
+ popTextCell(protyle, [item.querySelector(`.av__row[data-id="${operation.srcIDs[0]}"] .av__cell[data-detached="true"]`)], "block");
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|