mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-19 16:10:12 +01:00
This commit is contained in:
parent
092c58f629
commit
70e6a3182d
23 changed files with 382 additions and 136 deletions
|
|
@ -55,6 +55,10 @@
|
|||
--b3-tooltips-color: var(--b3-theme-background-light);
|
||||
--b3-tooltips-shadow: 0 2px 8px rgba(0, 0, 0, .1);
|
||||
|
||||
/* av */
|
||||
--b3-av-hover: #e8e8e9;
|
||||
--b3-av-background-hl: #e8eefc;
|
||||
|
||||
/* 为空提示 */
|
||||
--b3-empty-color: var(--b3-theme-on-surface-light);
|
||||
|
||||
|
|
@ -92,11 +96,11 @@
|
|||
--b3-font-background5: #e2e3e4;
|
||||
--b3-font-background6: #acd0fc;
|
||||
--b3-font-background7: #fdeed6;
|
||||
--b3-font-background8: rgba(255, 193, 153, 0.5);
|
||||
--b3-font-background8: #fae1cf;
|
||||
--b3-font-background9: #fdd5e7;
|
||||
--b3-font-background10: #e6c7e6;
|
||||
--b3-font-background11: #def0d9;
|
||||
--b3-font-background12: rgba(253, 198, 200, 0.5);
|
||||
--b3-font-background12: #fae3e4;
|
||||
--b3-font-background13: var(--b3-theme-on-background);
|
||||
|
||||
/* 动画效果 */
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@
|
|||
--b3-tooltips-color: var(--b3-theme-on-surface-light);
|
||||
--b3-tooltips-shadow: 0 2px 8px rgba(0, 0, 0, .3);
|
||||
|
||||
/* av */
|
||||
--b3-av-hover: #2a2a2a;
|
||||
--b3-av-background-hl: #28324e;
|
||||
|
||||
/* 为空提示 */
|
||||
--b3-empty-color: var(--b3-theme-on-surface);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
&__pulse {
|
||||
width: 70%;
|
||||
height: 23px;
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--b3-border-color);
|
||||
|
|
@ -29,10 +30,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover .av__row--footer > .av__calc--show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&__header {
|
||||
top: -43px;
|
||||
z-index: 2;
|
||||
|
|
@ -61,7 +58,7 @@
|
|||
bottom: 0;
|
||||
height: 30px;
|
||||
padding: 0 5px;
|
||||
background-color: var(--b3-theme-background);
|
||||
background-color: var(--av-background);
|
||||
}
|
||||
|
||||
&__gutters {
|
||||
|
|
@ -116,7 +113,9 @@
|
|||
}
|
||||
|
||||
&--select {
|
||||
background-color: var(--b3-theme-primary-lightest);
|
||||
.av__cell {
|
||||
background-color: var(--b3-av-hover);
|
||||
}
|
||||
|
||||
.av__firstcol svg {
|
||||
opacity: 1;
|
||||
|
|
@ -124,39 +123,45 @@
|
|||
}
|
||||
|
||||
&--header {
|
||||
z-index: 1;
|
||||
z-index: 3;
|
||||
|
||||
.av__cell {
|
||||
padding: 0;
|
||||
transition: background 20ms ease-in 0s;
|
||||
display: flex;
|
||||
overflow: inherit; // 保证列宽和顺序调整的拖拽点样式
|
||||
|
||||
&:hover {
|
||||
background-color: var(--b3-list-icon-hover);
|
||||
background-color: var(--b3-av-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--header,
|
||||
&--footer {
|
||||
background-color: var(--b3-theme-background);
|
||||
background-color: var(--av-background);
|
||||
}
|
||||
|
||||
&--footer {
|
||||
display: flex;
|
||||
border-top: 1px solid var(--b3-theme-surface-lighter);
|
||||
color: var(--b3-theme-on-surface);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
&:hover > .av__calc,
|
||||
&.av__row--show > .av__calc {
|
||||
&:hover .av__calc,
|
||||
&.av__row--show .av__calc {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
& > .av__calc {
|
||||
transition: opacity 150ms linear, background 20ms ease-in 0s;
|
||||
.av__colsticky {
|
||||
background-color: var(--av-background); // 保证盯住时无计算结果的列不被覆盖
|
||||
}
|
||||
|
||||
.av__calc {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 5px 5px 7px;
|
||||
padding: 5px;
|
||||
border-right: 1px;
|
||||
flex-direction: row-reverse;
|
||||
box-sizing: border-box;
|
||||
|
|
@ -181,29 +186,32 @@
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--b3-list-icon-hover);
|
||||
background-color: var(--b3-av-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--add {
|
||||
color: var(--b3-theme-on-surface);
|
||||
padding: 5px 5px 5px 7px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: background 20ms ease-in 0s;
|
||||
font-size: 87.5%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
.av__colsticky {
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
color: var(--b3-theme-on-surface);
|
||||
margin-right: 5px;
|
||||
padding: 10px 10px 10px 5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--b3-list-icon-hover);
|
||||
background-color: var(--b3-av-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -300,6 +308,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
&__colsticky {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
|
||||
&.av__firstcol,
|
||||
& > div {
|
||||
background-color: var(--av-background);
|
||||
}
|
||||
}
|
||||
|
||||
&__widthdrag {
|
||||
position: absolute;
|
||||
cursor: col-resize;
|
||||
|
|
@ -382,7 +402,30 @@
|
|||
.protyle-wysiwyg--select,
|
||||
.protyle-wysiwyg--hl {
|
||||
.av__row--header,
|
||||
.av__row--footer {
|
||||
.av__row--footer,
|
||||
.av__row--footer .av__colsticky,
|
||||
.av__row--select .av__cell,
|
||||
.av__colsticky.av__firstcol,
|
||||
.av__colsticky > div,
|
||||
.av__counter {
|
||||
background-color: var(--b3-av-background-hl);
|
||||
}
|
||||
}
|
||||
|
||||
.dragover__top,
|
||||
.dragover__bottom {
|
||||
.av__colsticky {
|
||||
z-index: 0;
|
||||
|
||||
& > div {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dragover__bottom + .av__row,
|
||||
.av__row:has(+ .dragover__top) {
|
||||
.av__colsticky > div {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
.block__icons {
|
||||
min-height: auto;
|
||||
padding: 4px 8px;
|
||||
font-size: 100%;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.b3-text-field--text {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const initBlockPopover = (app: App) => {
|
|||
if (aElement) {
|
||||
let tip = aElement.getAttribute("aria-label") || aElement.getAttribute("data-inline-memo-content");
|
||||
if (aElement.classList.contains("av__celltext")) {
|
||||
if (aElement.scrollWidth > aElement.parentElement.clientWidth - 11) {
|
||||
if (aElement.offsetWidth > aElement.parentElement.clientWidth - 11) {
|
||||
if (aElement.querySelector(".av__cellicon")) {
|
||||
tip = `${aElement.firstChild.textContent} ➡️ ${aElement.lastChild.textContent}`;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1270,15 +1270,20 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => {
|
|||
}
|
||||
}
|
||||
|
||||
if (window.siyuan.dialogs.length > 0) {
|
||||
window.siyuan.dialogs[window.siyuan.dialogs.length - 1].destroy();
|
||||
// 需放在 menus 后,否则资源列中添加资源会先关闭菜单
|
||||
// 需放在 dialog 前,否则属性面板中修改日期会先关闭 dialog,只剩修改界面
|
||||
const avElement = document.querySelector(".av__panel");
|
||||
if (avElement) {
|
||||
const selectCellElement = document.querySelector(".av__cell--select")
|
||||
if (selectCellElement) {
|
||||
focusBlock(hasClosestBlock(selectCellElement) as HTMLElement);
|
||||
}
|
||||
avElement.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
// 需放在 menus 后,否则资源列中添加资源会先关闭菜单
|
||||
const avElement = document.querySelector(".av__panel");
|
||||
if (avElement) {
|
||||
avElement.remove();
|
||||
if (window.siyuan.dialogs.length > 0) {
|
||||
window.siyuan.dialogs[window.siyuan.dialogs.length - 1].destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {getEventName, isCtrl, updateHotkeyTip} from "../protyle/util/compatibility";
|
||||
import {getEventName, updateHotkeyTip} from "../protyle/util/compatibility";
|
||||
import {setPosition} from "../util/setPosition";
|
||||
import {hasClosestByClassName} from "../protyle/util/hasClosest";
|
||||
import {isMobile} from "../util/functions";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../
|
|||
import {transaction} from "../../wysiwyg/transaction";
|
||||
import {openEditorTab} from "../../../menus/util";
|
||||
import {copySubMenu} from "../../../menus/commonMenuItem";
|
||||
import {openCalcMenu, popTextCell} from "./cell";
|
||||
import {getTypeByCellElement, openCalcMenu, popTextCell} from "./cell";
|
||||
import {getColIconByType, showColMenu} from "./col";
|
||||
import {insertAttrViewBlockAnimation, updateHeader} from "./row";
|
||||
import {emitOpenMenu} from "../../../plugin/EventBus";
|
||||
|
|
@ -70,7 +70,10 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
|
|||
|
||||
const gutterElement = hasClosestByClassName(event.target, "ariaLabel");
|
||||
if (gutterElement && gutterElement.parentElement.classList.contains("av__gutters")) {
|
||||
const rowElement = gutterElement.parentElement.parentElement;
|
||||
const rowElement = hasClosestByClassName(gutterElement, "av__row");
|
||||
if (!rowElement) {
|
||||
return
|
||||
}
|
||||
if (gutterElement.dataset.action === "add") {
|
||||
const avID = blockElement.getAttribute("data-av-id");
|
||||
const srcIDs = [Lute.NewNodeID()];
|
||||
|
|
@ -200,16 +203,24 @@ 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")) {
|
||||
const type = cellElement.parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
||||
if (cellElement && !hasClosestByClassName(cellElement, "av__row--header")) {
|
||||
const scrollElement = hasClosestByClassName(cellElement, "av__scroll")
|
||||
if (!scrollElement) {
|
||||
return
|
||||
}
|
||||
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
||||
if (!rowElement) {
|
||||
return;
|
||||
}
|
||||
const type = getTypeByCellElement(cellElement);
|
||||
if (type === "updated" || type === "created" || (type === "block" && !cellElement.getAttribute("data-detached"))) {
|
||||
selectRow(cellElement.parentElement.querySelector(".av__firstcol"), "toggle");
|
||||
selectRow(rowElement.querySelector(".av__firstcol"), "toggle");
|
||||
} else {
|
||||
cellElement.parentElement.parentElement.querySelectorAll(".av__row--select").forEach(item => {
|
||||
scrollElement.querySelectorAll(".av__row--select").forEach(item => {
|
||||
item.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck");
|
||||
item.classList.remove("av__row--select");
|
||||
});
|
||||
updateHeader(cellElement.parentElement);
|
||||
updateHeader(rowElement);
|
||||
popTextCell(protyle, [cellElement]);
|
||||
}
|
||||
event.preventDefault();
|
||||
|
|
@ -307,7 +318,7 @@ export const avContextmenu = (protyle: IProtyle, rowElement: HTMLElement, positi
|
|||
updateHeader(blockElement.querySelector(".av__row"));
|
||||
}
|
||||
});
|
||||
if (rowIds.length === 1) {
|
||||
if (rowIds.length === 1 && !rowElements[0].querySelector('[data-detached="true"]')) {
|
||||
menu.addSeparator();
|
||||
openEditorTab(protyle.app, rowIds[0]);
|
||||
menu.addItem({
|
||||
|
|
@ -410,8 +421,7 @@ export const updateAVName = (protyle: IProtyle, blockElement: Element) => {
|
|||
};
|
||||
|
||||
export const updateAttrViewCellAnimation = (cellElement: HTMLElement) => {
|
||||
cellElement.style.opacity = "0.38";
|
||||
cellElement.style.backgroundColor = "var(--b3-theme-surface-light)";
|
||||
cellElement.style.backgroundColor = "var(--b3-av-hover)";
|
||||
};
|
||||
|
||||
export const removeAttrViewColAnimation = (blockElement: Element, id: string) => {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {previewImage} from "../../preview/image";
|
|||
import {genAVValueHTML} from "./blockAttr";
|
||||
import {hideMessage, showMessage} from "../../../dialog/message";
|
||||
import {fetchPost} from "../../../util/fetch";
|
||||
import {hasClosestByClassName} from "../../util/hasClosest";
|
||||
|
||||
export const bindAssetEvent = (options: {
|
||||
protyle: IProtyle,
|
||||
|
|
@ -49,7 +50,7 @@ export const bindAssetEvent = (options: {
|
|||
|
||||
export const getAssetHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
|
||||
const cellId = cellElements[0].dataset.id;
|
||||
const rowId = cellElements[0].parentElement.dataset.id;
|
||||
const rowId = (hasClosestByClassName(cellElements[0], "av__row") as HTMLElement).dataset.id;
|
||||
let cellData: IAVCell;
|
||||
data.rows.find(row => {
|
||||
if (row.id === rowId) {
|
||||
|
|
@ -112,7 +113,7 @@ export const updateAssetCell = (options: {
|
|||
removeContent?: string
|
||||
}) => {
|
||||
let cellIndex: number;
|
||||
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
Array.from((hasClosestByClassName(options.cellElements[0], "av__row") as HTMLElement).querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
||||
cellIndex = index;
|
||||
return true;
|
||||
|
|
@ -124,7 +125,7 @@ export const updateAssetCell = (options: {
|
|||
let newValue: IAVCellAssetValue[] = [];
|
||||
options.cellElements.forEach((item, elementIndex) => {
|
||||
let cellData: IAVCell;
|
||||
const rowID = item.parentElement.dataset.id;
|
||||
const rowID = (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id;
|
||||
options.data.view.rows.find(row => {
|
||||
if (row.id === rowID) {
|
||||
if (typeof cellIndex === "number") {
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ export const renderAVAttribute = (element: HTMLElement, id: string, protyle?: IP
|
|||
<span>${table.avName || window.siyuan.languages.database}</span>
|
||||
</div>`;
|
||||
table.keyValues?.forEach(item => {
|
||||
html += `<div class="block__icons" data-id="${id}">
|
||||
html += `<div class="block__icons av__row" data-id="${id}">
|
||||
<div class="block__logo">
|
||||
<svg><use xlink:href="#${getColIconByType(item.key.type)}"></use></svg>
|
||||
<span>${item.key.name}</span>
|
||||
|
|
|
|||
|
|
@ -175,9 +175,13 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
|||
if (!blockElement) {
|
||||
return;
|
||||
}
|
||||
calcElement.parentElement.classList.add("av__row--show");
|
||||
const rowElement = hasClosestByClassName(calcElement, "av__row--footer");
|
||||
if (!rowElement) {
|
||||
return;
|
||||
}
|
||||
rowElement.classList.add("av__row--show");
|
||||
const menu = new Menu("av-calc", () => {
|
||||
calcElement.parentElement.classList.remove("av__row--show");
|
||||
rowElement.classList.remove("av__row--show");
|
||||
});
|
||||
if (menu.isOpen) {
|
||||
return;
|
||||
|
|
@ -346,14 +350,28 @@ export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
|||
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
||||
};
|
||||
|
||||
export const cellScrollIntoView = (blockElement: HTMLElement, cellRect: DOMRect, onlyHeight = true) => {
|
||||
export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Element, onlyHeight = true) => {
|
||||
const cellRect = cellElement.getBoundingClientRect();
|
||||
if (!onlyHeight) {
|
||||
const avScrollElement = blockElement.querySelector(".av__scroll");
|
||||
if (avScrollElement) {
|
||||
const avScrollRect = avScrollElement.getBoundingClientRect();
|
||||
if (avScrollRect.left > cellRect.left) {
|
||||
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
|
||||
} else if (avScrollRect.right < cellRect.right) {
|
||||
if (avScrollRect.right < cellRect.right) {
|
||||
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.right - avScrollRect.right;
|
||||
} else {
|
||||
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
||||
if (rowElement) {
|
||||
const stickyElement = rowElement.querySelector(".av__colsticky");
|
||||
if (stickyElement) {
|
||||
const stickyRight = stickyElement.getBoundingClientRect().right
|
||||
if (stickyRight > cellRect.left) {
|
||||
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - stickyRight;
|
||||
}
|
||||
} else if (avScrollRect.left > cellRect.left) {
|
||||
avScrollElement.scrollLeft = avScrollElement.scrollLeft + cellRect.left - avScrollRect.left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!blockElement.querySelector(".av__header")) {
|
||||
|
|
@ -377,9 +395,17 @@ export const cellScrollIntoView = (blockElement: HTMLElement, cellRect: DOMRect,
|
|||
}
|
||||
};
|
||||
|
||||
export const getTypeByCellElement = (cellElement: Element) => {
|
||||
const scrollElement = hasClosestByClassName(cellElement, "av__scroll")
|
||||
if (!scrollElement) {
|
||||
return;
|
||||
}
|
||||
return scrollElement.querySelector(".av__row--header").querySelector(`[data-col-id="${cellElement.getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
||||
}
|
||||
|
||||
export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type?: TAVCol) => {
|
||||
if (!type) {
|
||||
type = cellElements[0].parentElement.parentElement.firstElementChild.querySelector(`[data-col-id="${cellElements[0].getAttribute("data-col-id")}"]`).getAttribute("data-dtype") as TAVCol;
|
||||
type = getTypeByCellElement(cellElements[0])
|
||||
}
|
||||
if (type === "updated" || type === "created") {
|
||||
return;
|
||||
|
|
@ -396,7 +422,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
|
|||
contentElement.scrollTop = contentElement.scrollTop + cellRect.top - 110;
|
||||
}
|
||||
/// #else
|
||||
cellScrollIntoView(blockElement, cellRect);
|
||||
cellScrollIntoView(blockElement, cellElements[0], false);
|
||||
/// #endif
|
||||
}
|
||||
cellRect = cellElements[0].getBoundingClientRect();
|
||||
|
|
@ -406,14 +432,17 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
|
|||
html = `<textarea ${style} class="b3-text-field">${cellElements[0].firstElementChild.textContent}</textarea>`;
|
||||
} else if (type === "number") {
|
||||
html = `<input type="number" value="${cellElements[0].firstElementChild.getAttribute("data-content")}" ${style} class="b3-text-field">`;
|
||||
} else if (["select", "mSelect"].includes(type) && blockElement) {
|
||||
} else if (blockElement) {
|
||||
if (["select", "mSelect"].includes(type)) {
|
||||
openMenuPanel({protyle, blockElement, type: "select", cellElements});
|
||||
return;
|
||||
} else if (type === "mAsset" && blockElement) {
|
||||
} else if (type === "mAsset") {
|
||||
openMenuPanel({protyle, blockElement, type: "asset", cellElements});
|
||||
return;
|
||||
} else if (type === "date" && blockElement) {
|
||||
} else if (type === "date") {
|
||||
openMenuPanel({protyle, blockElement, type: "date", cellElements});
|
||||
}
|
||||
if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
|
||||
cellElements[0].classList.add("av__cell--select");
|
||||
}
|
||||
return;
|
||||
}
|
||||
window.siyuan.menus.menu.remove();
|
||||
|
|
@ -459,12 +488,16 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
|
|||
};
|
||||
|
||||
const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElement[]) => {
|
||||
const rowElement = hasClosestByClassName(cellElements[0], "av__row");
|
||||
if (!rowElement) {
|
||||
return;
|
||||
}
|
||||
if (!document.contains(cellElements[0]) && cellElements.length === 1) {
|
||||
// 原始 cell 已被更新
|
||||
const avid = cellElements[0].parentElement.dataset.avid;
|
||||
const avid = rowElement.dataset.avid;
|
||||
if (avid) {
|
||||
// 新增行后弹出的输入框
|
||||
const previousId = cellElements[0].parentElement.dataset.previousId;
|
||||
const previousId = rowElement.dataset.previousId;
|
||||
cellElements[0] = protyle.wysiwyg.element.querySelector(previousId ? `[data-av-id="${avid}"] .av__row[data-id="${previousId}"]` : `[data-av-id="${avid}"] .av__row--header`).nextElementSibling.querySelector('[data-detached="true"]');
|
||||
} else {
|
||||
// 修改单元格后立即修改其他单元格
|
||||
|
|
@ -474,7 +507,7 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
|
|||
}
|
||||
}
|
||||
}
|
||||
if (cellElements.length === 1 && cellElements[0].dataset.detached === "true" && !cellElements[0].parentElement.dataset.id) {
|
||||
if (cellElements.length === 1 && cellElements[0].dataset.detached === "true" && !rowElement.dataset.id) {
|
||||
return;
|
||||
}
|
||||
const blockElement = hasClosestBlock(cellElements[0]);
|
||||
|
|
@ -514,10 +547,16 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
|
|||
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
|
||||
};
|
||||
const oldValue: { content: string | number, isNotEmpty?: boolean } = {
|
||||
const oldValue: {
|
||||
content: string | number,
|
||||
isNotEmpty?: boolean
|
||||
} = {
|
||||
content: type === "block" ? item.firstElementChild.textContent.trim() : item.textContent.trim()
|
||||
};
|
||||
if (type === "number") {
|
||||
|
|
|
|||
|
|
@ -577,6 +577,26 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
|
|||
}]);
|
||||
}
|
||||
});
|
||||
}
|
||||
const isPin = cellElement.dataset.pin === "true"
|
||||
menu.addItem({
|
||||
icon: "iconPin",
|
||||
label: isPin ? window.siyuan.languages.unfreezeCol : window.siyuan.languages.freezeCol,
|
||||
click() {
|
||||
transaction(protyle, [{
|
||||
action: "setAttrViewColPin",
|
||||
id: colId,
|
||||
avID,
|
||||
data: !isPin
|
||||
}], [{
|
||||
action: "setAttrViewColPin",
|
||||
id: colId,
|
||||
avID,
|
||||
data: isPin
|
||||
}]);
|
||||
}
|
||||
});
|
||||
if (type !== "block") {
|
||||
menu.addItem({
|
||||
icon: "iconCopy",
|
||||
label: window.siyuan.languages.duplicate,
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ import {transaction} from "../../wysiwyg/transaction";
|
|||
import * as dayjs from "dayjs";
|
||||
import {updateAttrViewCellAnimation} from "./action";
|
||||
import {genAVValueHTML} from "./blockAttr";
|
||||
import {hasClosestByClassName} from "../../util/hasClosest";
|
||||
|
||||
export const getDateHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
|
||||
let hasEndDate = true;
|
||||
let cellValue: IAVCell;
|
||||
cellElements.forEach((cellElement) => {
|
||||
data.rows.find(row => {
|
||||
if (cellElement.parentElement.dataset.id === row.id) {
|
||||
if ((hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id === row.id) {
|
||||
row.cells.find(cell => {
|
||||
if (cell.id === cellElement.dataset.id) {
|
||||
if (!cell.value || !cell.value.date || !cell.value.date.hasEndDate) {
|
||||
|
|
@ -141,7 +142,7 @@ export const setDateValue = (options: {
|
|||
value: IAVCellDateValue
|
||||
}) => {
|
||||
let cellIndex: number;
|
||||
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
Array.from((hasClosestByClassName(options.cellElements[0], "av__row") as HTMLElement).querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
||||
cellIndex = index;
|
||||
return true;
|
||||
|
|
@ -153,7 +154,7 @@ export const setDateValue = (options: {
|
|||
options.cellElements.forEach(item => {
|
||||
let cellData: IAVCell;
|
||||
let oldValue;
|
||||
const rowID = item.parentElement.dataset.id;
|
||||
const rowID = (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id;
|
||||
options.data.view.rows.find(row => {
|
||||
if (row.id === rowID) {
|
||||
if (typeof cellIndex === "number") {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {matchHotKey} from "../../util/hotKey";
|
|||
import {selectRow} from "./row";
|
||||
import {cellScrollIntoView, popTextCell} from "./cell";
|
||||
import {avContextmenu} from "./action";
|
||||
import {hasClosestByClassName} from "../../util/hasClosest";
|
||||
|
||||
export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyle: IProtyle) => {
|
||||
if (!nodeElement.classList.contains("av") || !window.siyuan.menus.menu.element.classList.contains("fn__none")) {
|
||||
|
|
@ -17,9 +18,13 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
|
|||
}
|
||||
const selectCellElement = nodeElement.querySelector(".av__cell--select") as HTMLElement;
|
||||
if (selectCellElement) {
|
||||
const rowElement = hasClosestByClassName(selectCellElement, "av__row");
|
||||
if (!rowElement) {
|
||||
return false;
|
||||
}
|
||||
if (event.key === "Escape") {
|
||||
selectCellElement.classList.remove("av__cell--select");
|
||||
selectRow(selectCellElement.parentElement.querySelector(".av__firstcol"), "select");
|
||||
selectRow(rowElement.querySelector(".av__firstcol"), "select");
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -30,57 +35,64 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
|
|||
}
|
||||
let newCellElement;
|
||||
if (event.key === "ArrowLeft") {
|
||||
const previousRowElement = selectCellElement.parentElement.previousElementSibling;
|
||||
if (selectCellElement.previousElementSibling && selectCellElement.previousElementSibling.classList.contains("av__cell")) {
|
||||
const previousRowElement = rowElement.previousElementSibling;
|
||||
if (selectCellElement.previousElementSibling && !selectCellElement.previousElementSibling.classList.contains("av__firstcol")) {
|
||||
if (selectCellElement.previousElementSibling.classList.contains("av__cell")) {
|
||||
newCellElement = selectCellElement.previousElementSibling;
|
||||
} else {
|
||||
newCellElement = selectCellElement.previousElementSibling.lastElementChild;
|
||||
}
|
||||
} else if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
|
||||
newCellElement = previousRowElement.lastElementChild.previousElementSibling;
|
||||
const previousCellElements = previousRowElement.querySelectorAll(".av__cell")
|
||||
newCellElement = previousCellElements[previousCellElements.length - 1];
|
||||
}
|
||||
if (newCellElement) {
|
||||
selectCellElement.classList.remove("av__cell--select");
|
||||
newCellElement.classList.add("av__cell--select");
|
||||
cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
|
||||
cellScrollIntoView(nodeElement, newCellElement, false);
|
||||
}
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
if (event.key === "ArrowRight") {
|
||||
const nextRowElement = selectCellElement.parentElement.nextElementSibling;
|
||||
const nextRowElement = rowElement.nextElementSibling;
|
||||
if (selectCellElement.nextElementSibling && selectCellElement.nextElementSibling.classList.contains("av__cell")) {
|
||||
newCellElement = selectCellElement.nextElementSibling;
|
||||
} else if (!selectCellElement.nextElementSibling && selectCellElement.parentElement.nextElementSibling) {
|
||||
newCellElement = selectCellElement.parentElement.nextElementSibling;
|
||||
} else if (nextRowElement && !nextRowElement.classList.contains("av__row--footer")) {
|
||||
newCellElement = nextRowElement.querySelector(".av__cell");
|
||||
}
|
||||
if (newCellElement) {
|
||||
selectCellElement.classList.remove("av__cell--select");
|
||||
newCellElement.classList.add("av__cell--select");
|
||||
cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
|
||||
cellScrollIntoView(nodeElement, newCellElement, false);
|
||||
}
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
if (event.key === "ArrowUp") {
|
||||
const previousRowElement = selectCellElement.parentElement.previousElementSibling;
|
||||
const previousRowElement = rowElement.previousElementSibling;
|
||||
if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
|
||||
newCellElement = previousRowElement.querySelector(`.av__cell[data-col-id="${selectCellElement.dataset.colId}"]`);
|
||||
}
|
||||
if (newCellElement) {
|
||||
selectCellElement.classList.remove("av__cell--select");
|
||||
newCellElement.classList.add("av__cell--select");
|
||||
cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
|
||||
cellScrollIntoView(nodeElement, newCellElement);
|
||||
}
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
if (event.key === "ArrowDown") {
|
||||
const nextRowElement = selectCellElement.parentElement.nextElementSibling;
|
||||
const nextRowElement = rowElement.nextElementSibling;
|
||||
if (nextRowElement && !nextRowElement.classList.contains("av__row--footer")) {
|
||||
newCellElement = nextRowElement.querySelector(`.av__cell[data-col-id="${selectCellElement.dataset.colId}"]`);
|
||||
}
|
||||
if (newCellElement) {
|
||||
selectCellElement.classList.remove("av__cell--select");
|
||||
newCellElement.classList.add("av__cell--select");
|
||||
cellScrollIntoView(nodeElement, newCellElement.getBoundingClientRect());
|
||||
cellScrollIntoView(nodeElement, newCellElement);
|
||||
}
|
||||
event.preventDefault();
|
||||
return true;
|
||||
|
|
@ -115,7 +127,7 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
|
|||
selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll");
|
||||
if (previousRowElement && !previousRowElement.classList.contains("av__row--header")) {
|
||||
selectRow(previousRowElement.querySelector(".av__firstcol"), "select");
|
||||
cellScrollIntoView(nodeElement, previousRowElement.getBoundingClientRect(), true);
|
||||
cellScrollIntoView(nodeElement, previousRowElement);
|
||||
} else {
|
||||
nodeElement.classList.add("protyle-wysiwyg--select");
|
||||
}
|
||||
|
|
@ -127,7 +139,7 @@ export const avKeydown = (event: KeyboardEvent, nodeElement: HTMLElement, protyl
|
|||
selectRow(selectRowElements[0].querySelector(".av__firstcol"), "unselectAll");
|
||||
if (nextRowElement && !nextRowElement.classList.contains("av__row--add")) {
|
||||
selectRow(nextRowElement.querySelector(".av__firstcol"), "select");
|
||||
cellScrollIntoView(nodeElement, nextRowElement.getBoundingClientRect(), true);
|
||||
cellScrollIntoView(nodeElement, nextRowElement);
|
||||
} else {
|
||||
nodeElement.classList.add("protyle-wysiwyg--select");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import * as dayjs from "dayjs";
|
|||
import {unicode2Emoji} from "../../../emoji";
|
||||
import {focusBlock} from "../../util/selection";
|
||||
import {isMac} from "../../util/compatibility";
|
||||
import {hasClosestByClassName} from "../../util/hasClosest";
|
||||
|
||||
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
|
||||
let avElements: Element[] = [];
|
||||
|
|
@ -45,20 +46,41 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) =
|
|||
let selectCellId = "";
|
||||
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
|
||||
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", {
|
||||
id: e.getAttribute("data-av-id"),
|
||||
}, (response) => {
|
||||
const data = response.data.view as IAVTable;
|
||||
// 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) {
|
||||
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"};
|
||||
${column.wrap ? "" : "white-space: nowrap;"}">
|
||||
<div draggable="true" class="av__cellheader">
|
||||
|
|
@ -67,8 +89,14 @@ ${column.wrap ? "" : "white-space: nowrap;"}">
|
|||
</div>
|
||||
<div class="av__widthdrag"></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 || ""}"
|
||||
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">
|
||||
<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">
|
||||
<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>
|
||||
</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) => {
|
||||
if (data.columns[index].hidden) {
|
||||
return;
|
||||
|
|
@ -144,13 +177,11 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
|
|||
});
|
||||
if (!text) {
|
||||
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 (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}"
|
||||
|
|
@ -161,6 +192,10 @@ ${cell.bgColor ? `background-color:${cell.bgColor};` : ""}
|
|||
white-space: ${data.columns[index].wrap ? "pre-wrap" : "nowrap"};
|
||||
${cell.valueType !== "number" ? "" : "flex-direction: row-reverse;"}
|
||||
${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
||||
|
||||
if (pinIndex === index) {
|
||||
tableHTML += '</div>'
|
||||
}
|
||||
});
|
||||
tableHTML += "<div></div></div>";
|
||||
});
|
||||
|
|
@ -172,7 +207,7 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|||
</div>`;
|
||||
});
|
||||
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="layout-tab-bar fn__flex">
|
||||
${tabHTML}
|
||||
|
|
@ -199,10 +234,12 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|||
<div style="float: left;">
|
||||
${tableHTML}
|
||||
<div class="av__row--add">
|
||||
<div class="av__colsticky">
|
||||
<svg><use xlink:href="#iconAdd"></use></svg>
|
||||
${window.siyuan.languages.addAttr}
|
||||
</div>
|
||||
<div class="av__row--footer"><div style="width: 24px"></div>${calcHTML}</div>
|
||||
</div>
|
||||
<div class="av__row--footer">${calcHTML}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
@ -223,8 +260,10 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
|||
if (newCellElement) {
|
||||
newCellElement.classList.add("av__cell--select");
|
||||
}
|
||||
if (!document.querySelector(".av__panel")) {
|
||||
focusBlock(e);
|
||||
}
|
||||
}
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
|
|
@ -270,7 +309,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation, isUndo: bool
|
|||
avRender(item, protyle, () => {
|
||||
// https://github.com/siyuan-note/siyuan/issues/9599
|
||||
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");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,27 +1,36 @@
|
|||
import {hasClosestBlock} from "../../util/hasClosest";
|
||||
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
|
||||
import {focusBlock} from "../../util/selection";
|
||||
|
||||
export const selectRow = (checkElement: Element, type: "toggle" | "select" | "unselect" | "unselectAll") => {
|
||||
const rowElement = checkElement.parentElement;
|
||||
const rowElement = hasClosestByClassName(checkElement, "av__row");
|
||||
if (!rowElement) {
|
||||
return
|
||||
}
|
||||
const useElement = checkElement.querySelector("use");
|
||||
if (rowElement.classList.contains("av__row--header") || type === "unselectAll") {
|
||||
if ("#iconCheck" === useElement.getAttribute("xlink:href")) {
|
||||
rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => {
|
||||
item.querySelector("use").setAttribute("xlink:href", "#iconUncheck");
|
||||
item.parentElement.classList.remove("av__row--select");
|
||||
const rowItemElement = hasClosestByClassName(item, "av__row");
|
||||
if (rowItemElement) {
|
||||
rowItemElement.classList.remove("av__row--select");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rowElement.parentElement.querySelectorAll(".av__firstcol").forEach(item => {
|
||||
item.querySelector("use").setAttribute("xlink:href", "#iconCheck");
|
||||
item.parentElement.classList.add("av__row--select");
|
||||
const rowItemElement = hasClosestByClassName(item, "av__row");
|
||||
if (rowItemElement) {
|
||||
rowItemElement.classList.add("av__row--select");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (type === "select" || (useElement.getAttribute("xlink:href") === "#iconUncheck" && type === "toggle")) {
|
||||
checkElement.parentElement.classList.add("av__row--select");
|
||||
rowElement.classList.add("av__row--select");
|
||||
useElement.setAttribute("xlink:href", "#iconCheck");
|
||||
} else if (type === "unselect" || (useElement.getAttribute("xlink:href") === "#iconCheck" && type === "toggle")) {
|
||||
checkElement.parentElement.classList.remove("av__row--select");
|
||||
rowElement.classList.remove("av__row--select");
|
||||
useElement.setAttribute("xlink:href", "#iconUncheck");
|
||||
}
|
||||
}
|
||||
|
|
@ -60,15 +69,21 @@ export const updateHeader = (rowElement: HTMLElement) => {
|
|||
|
||||
export const insertAttrViewBlockAnimation = (blockElement: Element, size: number, previousId: string, avId?: string) => {
|
||||
const previousElement = blockElement.querySelector(`.av__row[data-id="${previousId}"]`) || blockElement.querySelector(".av__row--header");
|
||||
let colHTML = "";
|
||||
previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement) => {
|
||||
let colHTML = '<div style="width: 24px"></div>';
|
||||
const pinIndex = previousElement.querySelectorAll(".av__colsticky .av__cell").length - 1;
|
||||
if (pinIndex > -1) {
|
||||
colHTML = `<div class="av__colsticky"><div style="width: 24px"></div>`;
|
||||
}
|
||||
previousElement.querySelectorAll(".av__cell").forEach((item: HTMLElement, index) => {
|
||||
colHTML += `<div class="av__cell" style="width: ${item.style.width}" ${(item.getAttribute("data-block-id") || item.dataset.dtype === "block") ? ' data-detached="true"' : ""}><span class="av__pulse"></span></div>`;
|
||||
if (pinIndex === index) {
|
||||
colHTML += `</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
let html = "";
|
||||
new Array(size).fill(1).forEach(() => {
|
||||
html += `<div class="av__row" data-avid="${avId}" data-previous-id="${previousId}">
|
||||
<div style="width: 24px"></div>
|
||||
${colHTML}
|
||||
</div>`;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const removeCellOption = (protyle: IProtyle, data: IAV, cellElements: HTM
|
|||
const undoOperations: IOperation[] = [];
|
||||
let newData: IAVCellSelectValue[];
|
||||
cellElements.forEach((item, elementIndex) => {
|
||||
const rowID = item.parentElement.dataset.id;
|
||||
const rowID = (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id;
|
||||
const cellId = item.dataset.id;
|
||||
let cellData: IAVCell;
|
||||
data.view.rows.find(row => {
|
||||
|
|
@ -157,7 +157,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
|
|||
} else {
|
||||
cellElements.forEach((cellElement: HTMLMediaElement) => {
|
||||
data.view.rows.find(row => {
|
||||
if (row.id === cellElement.parentElement.dataset.id) {
|
||||
if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
|
||||
row.cells.find(cell => {
|
||||
if (cell.id === cellElement.dataset.id) {
|
||||
cell.value.mSelect.find((item) => {
|
||||
|
|
@ -235,7 +235,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
|
|||
} else {
|
||||
cellElements.forEach((cellElement: HTMLElement) => {
|
||||
data.view.rows.find(row => {
|
||||
if (row.id === cellElement.parentElement.dataset.id) {
|
||||
if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
|
||||
row.cells.find(cell => {
|
||||
if (cell.id === cellElement.dataset.id) {
|
||||
cell.value.mSelect.find((item, index) => {
|
||||
|
|
@ -314,7 +314,7 @@ export const setColOption = (protyle: IProtyle, data: IAV, target: HTMLElement,
|
|||
} else {
|
||||
cellElements.forEach((cellElement: HTMLElement) => {
|
||||
data.view.rows.find(row => {
|
||||
if (row.id === cellElement.parentElement.dataset.id) {
|
||||
if (row.id === (hasClosestByClassName(cellElement, "av__row") as HTMLElement).dataset.id) {
|
||||
row.cells.find(cell => {
|
||||
if (cell.id === cellElement.dataset.id) {
|
||||
cell.value.mSelect.find((item) => {
|
||||
|
|
@ -394,8 +394,6 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE
|
|||
addColOptionOrCell(protyle, data, cellElements, currentElement, menuElement);
|
||||
} else if (event.key === "Backspace" && inputElement.value === "") {
|
||||
removeCellOption(protyle, data, cellElements, inputElement.previousElementSibling as HTMLElement);
|
||||
} else if (event.key === "Escape") {
|
||||
menuElement.parentElement.remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -413,14 +411,18 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
|
|||
return;
|
||||
}
|
||||
|
||||
const colId = cellElements[0].dataset.colId;
|
||||
const rowElement = hasClosestByClassName(cellElements[0], "av__row");
|
||||
if (!rowElement) {
|
||||
return;
|
||||
}
|
||||
let cellIndex: number;
|
||||
Array.from(cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
Array.from(rowElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||
if (item.dataset.id === cellElements[0].dataset.id) {
|
||||
cellIndex = index;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
const colId = cellElements[0].dataset.colId;
|
||||
let colData: IAVColumn;
|
||||
data.view.columns.find((item: IAVColumn) => {
|
||||
if (item.id === colId) {
|
||||
|
|
@ -436,8 +438,12 @@ export const addColOptionOrCell = (protyle: IProtyle, data: IAV, cellElements: H
|
|||
const cellUndoOperations: IOperation[] = [];
|
||||
let newValue: IAVCellSelectValue[];
|
||||
cellElements.forEach((item, index) => {
|
||||
const itemRowElement = hasClosestByClassName(item, "av__row");
|
||||
if (!itemRowElement) {
|
||||
return;
|
||||
}
|
||||
let cellData: IAVCell;
|
||||
const rowID = item.parentElement.dataset.id;
|
||||
const rowID = itemRowElement.dataset.id;
|
||||
data.view.rows.find(row => {
|
||||
if (row.id === rowID) {
|
||||
if (typeof cellIndex === "number") {
|
||||
|
|
@ -553,7 +559,8 @@ export const getSelectHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
|
|||
|
||||
let allUniqueOptions: IAVCellSelectValue[] = [];
|
||||
data.rows.find(row => {
|
||||
if (cellElements[0].parentElement.dataset.id === row.id) {
|
||||
const rowElement = hasClosestByClassName(cellElements[0], "av__row");
|
||||
if (rowElement && rowElement.dataset.id === row.id) {
|
||||
row.cells.find(cell => {
|
||||
if (cell.id === cellElements[0].dataset.id) {
|
||||
if (cell.value && cell.value.mSelect) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
|||
const scrollRect = item.querySelector(".av__scroll").getBoundingClientRect()
|
||||
const headerElement = item.querySelector(".av__row--header") as HTMLElement;
|
||||
if (headerElement) {
|
||||
const distance = elementRect.top - scrollRect.top;
|
||||
const distance = Math.floor(elementRect.top - scrollRect.top);
|
||||
if (distance > 0 && distance < scrollRect.height) {
|
||||
headerElement.style.transform = `translateY(${distance}px)`;
|
||||
} else {
|
||||
|
|
@ -37,7 +37,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
|||
const footerElement = item.querySelector(".av__row--footer") as HTMLElement;
|
||||
if (footerElement) {
|
||||
if (footerElement.querySelector(".av__calc--ashow")) {
|
||||
const distance = elementRect.bottom - scrollRect.bottom;
|
||||
const distance = Math.floor(elementRect.bottom - footerElement.parentElement.getBoundingClientRect().bottom);
|
||||
if (distance < 0 && -distance < scrollRect.height) {
|
||||
footerElement.style.transform = `translateY(${distance}px)`;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -216,10 +216,16 @@ export const fontEvent = (protyle: IProtyle, nodeElements: Element[], type?: str
|
|||
e.style.textShadow = "";
|
||||
e.style.backgroundColor = "";
|
||||
e.style.fontSize = "";
|
||||
if (e.classList.contains("av")) {
|
||||
e.querySelector(".av__container").setAttribute("style", "--av-background:--b3-theme-background");
|
||||
}
|
||||
} else if (type === "style1") {
|
||||
const colorList = color.split(Constants.ZWSP);
|
||||
e.style.backgroundColor = colorList[0];
|
||||
e.style.color = colorList[1];
|
||||
if (e.classList.contains("av")) {
|
||||
e.querySelector(".av__container").setAttribute("style", `--av-background:${colorList[0]}`);
|
||||
}
|
||||
} else if (type === "style2") {
|
||||
e.style.webkitTextStroke = "0.2px var(--b3-theme-on-background)";
|
||||
e.style.webkitTextFillColor = "transparent";
|
||||
|
|
@ -229,6 +235,9 @@ export const fontEvent = (protyle: IProtyle, nodeElements: Element[], type?: str
|
|||
e.style.color = color;
|
||||
} else if (type === "backgroundColor") {
|
||||
e.style.backgroundColor = color;
|
||||
if (e.classList.contains("av")) {
|
||||
e.querySelector(".av__container").setAttribute("style", `--av-background:${color}`);
|
||||
}
|
||||
} else if (type === "fontSize") {
|
||||
e.style.fontSize = color;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -852,15 +852,39 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
|
|||
const blockElement = hasClosestBlock(targetElement);
|
||||
if (blockElement) {
|
||||
const avID = blockElement.getAttribute("data-av-id");
|
||||
let previousID = "";
|
||||
if (targetClass.includes("dragover__left")) {
|
||||
if (targetElement.previousElementSibling) {
|
||||
if (targetElement.previousElementSibling.classList.contains("av__colsticky")) {
|
||||
previousID = targetElement.previousElementSibling.lastElementChild.getAttribute("data-col-id")
|
||||
} else {
|
||||
previousID = targetElement.previousElementSibling.getAttribute("data-col-id")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
previousID = targetElement.getAttribute("data-col-id")
|
||||
}
|
||||
let oldPreviousID = "";
|
||||
const rowElement = hasClosestByClassName(targetElement, "av__row");
|
||||
if (rowElement) {
|
||||
const oldPreviousElement = rowElement.querySelector(`[data-col-id="${gutterTypes[2]}"`)?.previousElementSibling
|
||||
if (oldPreviousElement) {
|
||||
if (oldPreviousElement.classList.contains("av__colsticky")) {
|
||||
oldPreviousID = oldPreviousElement.lastElementChild.getAttribute("data-col-id")
|
||||
} else {
|
||||
oldPreviousID = oldPreviousElement.getAttribute("data-col-id")
|
||||
}
|
||||
}
|
||||
}
|
||||
transaction(protyle, [{
|
||||
action: "sortAttrViewCol",
|
||||
avID,
|
||||
previousID: (targetClass.includes("dragover__left") ? targetElement.previousElementSibling?.getAttribute("data-col-id") : targetElement.getAttribute("data-col-id")) || "",
|
||||
previousID,
|
||||
id: gutterTypes[2],
|
||||
}], [{
|
||||
action: "sortAttrViewCol",
|
||||
avID,
|
||||
previousID: targetElement.parentElement.querySelector(`[data-col-id="${gutterTypes[2]}"`).previousElementSibling?.getAttribute("data-col-id") || "",
|
||||
previousID: oldPreviousID,
|
||||
id: gutterTypes[2],
|
||||
}]);
|
||||
}
|
||||
|
|
@ -1111,9 +1135,15 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => {
|
|||
if (gutterType && gutterType.startsWith(`${Constants.SIYUAN_DROP_GUTTER}NodeAttributeView${Constants.ZWSP}Col${Constants.ZWSP}`.toLowerCase())) {
|
||||
// 表头只能拖拽到当前 av 的表头中
|
||||
targetElement = hasClosestByClassName(event.target, "av__cell");
|
||||
if (targetElement && !targetElement.parentElement.isSameNode(window.siyuan.dragElement.parentElement)) {
|
||||
if (targetElement) {
|
||||
const targetRowElement = hasClosestByClassName(targetElement, "av__row--header")
|
||||
const dragRowElement = hasClosestByClassName(window.siyuan.dragElement, "av__row--header")
|
||||
if (!targetRowElement || !dragRowElement ||
|
||||
(targetRowElement && dragRowElement && !targetRowElement.isSameNode(dragRowElement))
|
||||
) {
|
||||
targetElement = false;
|
||||
}
|
||||
}
|
||||
} else if (targetElement && gutterType && gutterType.startsWith(`${Constants.SIYUAN_DROP_GUTTER}NodeAttributeView${Constants.ZWSP}Row${Constants.ZWSP}`.toLowerCase())) {
|
||||
// 行只能拖拽当前 av 中
|
||||
if (!targetElement.classList.contains("av__row") || !targetElement.parentElement.isSameNode(window.siyuan.dragElement.parentElement)) {
|
||||
|
|
|
|||
|
|
@ -384,9 +384,12 @@ export class WYSIWYG {
|
|||
let newWidth: string;
|
||||
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
|
||||
newWidth = Math.max(oldWidth + (moveEvent.clientX - event.clientX), 58) + "px";
|
||||
dragElement.parentElement.parentElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
||||
const scrollElement = hasClosestByClassName(dragElement, "av__scroll")
|
||||
if (scrollElement) {
|
||||
scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
||||
(item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
documentSelf.onmouseup = () => {
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
|
|||
"updateAttrViewColOption", "updateAttrViewCell", "sortAttrViewRow", "sortAttrViewCol", "setAttrViewColHidden",
|
||||
"setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrViewName", "setAttrViewFilters",
|
||||
"setAttrViewSorts", "setAttrViewColCalc", "removeAttrViewCol", "updateAttrViewColNumberFormat", "removeAttrViewBlock",
|
||||
"replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon"].includes(operation.action)) {
|
||||
"replaceAttrViewBlock", "updateAttrViewColTemplate", "setAttrViewColIcon", "setAttrViewColPin"].includes(operation.action)) {
|
||||
refreshAV(protyle, operation, isUndo);
|
||||
} else if (operation.action === "doUpdateUpdated") {
|
||||
updateElements.forEach(item => {
|
||||
|
|
|
|||
4
app/src/types/index.d.ts
vendored
4
app/src/types/index.d.ts
vendored
|
|
@ -27,6 +27,7 @@ type TOperation =
|
|||
| "updateAttrViewColTemplate"
|
||||
| "sortAttrViewRow"
|
||||
| "sortAttrViewCol"
|
||||
| "setAttrViewColPin"
|
||||
| "setAttrViewColHidden"
|
||||
| "setAttrViewColWrap"
|
||||
| "setAttrViewColWidth"
|
||||
|
|
@ -1029,11 +1030,12 @@ interface IAVSort {
|
|||
}
|
||||
|
||||
interface IAVColumn {
|
||||
width: number,
|
||||
width: string,
|
||||
icon: string,
|
||||
id: string,
|
||||
name: string,
|
||||
wrap: boolean,
|
||||
pin: boolean,
|
||||
hidden: boolean,
|
||||
type: TAVCol,
|
||||
numberFormat: string,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue