Vanessa 2025-06-12 18:33:46 +08:00
parent 5521034036
commit a566c823ce
7 changed files with 183 additions and 12 deletions

View file

@ -325,7 +325,7 @@
height: 100%;
&--fit {
background-size: contain;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
@ -354,6 +354,22 @@
flex: 1;
transition: background 100ms ease-out;
}
&-add {
border: 1px solid var(--b3-border-color);
border-radius: var(--b3-border-radius);
display: flex;
justify-content: center;
align-items: center;
color: var(--b3-theme-on-surface);
cursor: pointer;
transition: background 100ms ease-out, color 100ms ease-out;
&:hover {
background-color: var(--b3-list-hover);
color: var(--b3-theme-on-background);
}
}
}
&__layout {

View file

@ -199,7 +199,10 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
event.stopPropagation();
return true;
} else if (type === "av-add-bottom") {
insertRows(blockElement, protyle, 1, blockElement.querySelector(".av__row--util").previousElementSibling.getAttribute("data-id") || "");
insertRows(blockElement, protyle, 1,
blockElement.querySelector(".av__row--util")?.previousElementSibling?.getAttribute("data-id") ||
target.previousElementSibling?.getAttribute("data-id") || undefined
);
event.preventDefault();
event.stopPropagation();
return true;

View file

@ -0,0 +1,133 @@
import {showMessage} from "../../../../dialog/message";
import {
genCellValueByElement,
getTypeByCellElement,
renderCell,
renderCellAttr
} from "../cell";
import {fetchPost} from "../../../../util/fetch";
import {setPage} from "../row";
export const insertGalleryItemAnimation = (options: {
blockElement: HTMLElement;
protyle: IProtyle;
srcIDs: string[];
previousId: string;
}) => {
if ((options.blockElement.querySelector('[data-type="av-search"]') as HTMLInputElement).value !== "") {
showMessage(window.siyuan.languages.insertRowTip);
return;
}
const avId = options.blockElement.getAttribute("data-av-id");
const sideItemElement = options.previousId ? options.blockElement.querySelector(`.av__gallery-item[data-id="${options.previousId}"]`) : options.blockElement.querySelector(".av__gallery-item");
let html = "";
let needUpdate = "";
if (options.blockElement.querySelector('.av__views [data-type="av-sort"]').classList.contains("block__icon--active") &&
!options.blockElement.querySelector('[data-type="av-load-more"]').classList.contains("fn__none")) {
needUpdate = ' data-need-update="true"';
}
options.srcIDs.forEach((id) => {
html += `<div class="av__gallery-item"${needUpdate} data-type="ghost" data-id="${id}">
<div class="av__gallery-cover"><span style="width: 100%;height: 100%;border-radius: var(--b3-border-radius) var(--b3-border-radius) 0 0;" class="av__pulse"></span></div>
<div class="av__gallery-fields"><span style="margin: 8px;" class="av__pulse"></span></div>
</div>`;
});
if (options.previousId) {
sideItemElement.insertAdjacentHTML("afterend", html);
} else {
options.blockElement.querySelector(".av__gallery").insertAdjacentHTML("afterbegin", html);
}
const currentItemElement = options.blockElement.querySelector(`.av__gallery-item[data-id="${options.srcIDs[0]}"]`);
fetchPost("/api/av/getAttributeViewFilterSort", {
id: avId,
blockID: options.blockElement.getAttribute("data-node-id")
}, (response) => {
// https://github.com/siyuan-note/siyuan/issues/10517
let hideTextCell = false;
response.data.filters.find((item: IAVFilter) => {
const itemCellElement = options.blockElement.querySelector(`.av__cell[data-field-id="${item.column}"]`);
if (!itemCellElement) {
return;
}
const filterType = itemCellElement.getAttribute("data-dtype");
if (item.value && filterType !== item.value.type) {
return;
}
if (["relation", "rollup", "template"].includes(filterType)) {
hideTextCell = true;
return true;
}
// 根据后台计算出显示与否的结果进行标识,以便于在 refreshAV 中更新 UI
if (["created", "updated"].includes(filterType)) {
currentItemElement.setAttribute("data-need-update", "true");
} else {
response.data.sorts.find((sortItem: IAVSort) => {
if (sortItem.column === item.column) {
currentItemElement.setAttribute("data-need-update", "true");
return true;
}
});
}
// 当空或非空外,需要根据值进行判断
let isRenderValue = true;
if (item.operator !== "Is empty" && item.operator !== "Is not empty") {
switch (item.value.type) {
case "select":
case "mSelect":
if (!item.value.mSelect || item.value.mSelect.length === 0) {
isRenderValue = false;
}
break;
case "block":
if (!item.value.block || !item.value.block.content) {
isRenderValue = false;
}
break;
case "number":
if (!item.value.number || !item.value.number.isNotEmpty) {
isRenderValue = false;
}
break;
case "date":
case "created":
case "updated":
if (!item.value[item.value.type] || !item.value[item.value.type].isNotEmpty) {
isRenderValue = false;
}
break;
case "mAsset":
if (!item.value.mAsset || item.value.mAsset.length === 0) {
isRenderValue = false;
}
break;
case "checkbox":
if (!item.value.checkbox) {
isRenderValue = false;
}
break;
case "text":
case "url":
case "phone":
case "email":
if (!item.value[item.value.type] || !item.value[item.value.type].content) {
isRenderValue = false;
}
break;
}
}
if (sideItemElement.classList.contains("av__row") && isRenderValue) {
const sideItemCellElement = sideItemElement.querySelector(`.av__cell[data-field-id="${item.column}"]`) as HTMLElement;
const cellElement = currentItemElement.querySelector(`.av__cell[data-field-id="${item.column}"]`);
const cellValue = genCellValueByElement(getTypeByCellElement(sideItemCellElement), sideItemCellElement);
cellElement.innerHTML = renderCell(cellValue);
renderCellAttr(cellElement, cellValue);
}
});
if (hideTextCell) {
currentItemElement.remove();
showMessage(window.siyuan.languages.insertRowTip);
}
setPage(options.blockElement);
});
};

View file

@ -68,7 +68,7 @@ export const renderGallery = (options: {
let galleryHTML = "";
// body
view.cards.forEach((item: IAVGalleryItem, rowIndex: number) => {
galleryHTML += `<div class="av__gallery-item${selectItemIds.includes(item.id) ? " av__gallery-item--select" : ""}">`;
galleryHTML += `<div data-id="${item.id}" class="av__gallery-item${selectItemIds.includes(item.id) ? " av__gallery-item--select" : ""}">`;
if (view.coverFrom !== 0) {
if (item.coverURL) {
if (item.coverURL.startsWith("background")) {
@ -92,7 +92,7 @@ export const renderGallery = (options: {
if (cell.valueType === "checkbox") {
checkClass = cell.value?.checkbox?.checked ? " av__cell-check" : " av__cell-uncheck";
}
galleryHTML += `<div class="av__cell${checkClass}" data-id="${cell.id}"
galleryHTML += `<div class="av__cell${checkClass}" data-id="${cell.id}" data-field-id="${view.fields[fieldsIndex].id}"
${cell.valueType === "block" ? 'data-block-id="' + (cell.value.block.id || "") + '"' : ""}
data-dtype="${cell.valueType}"
${cell.value?.isDetached ? ' data-detached="true"' : ""}
@ -101,6 +101,7 @@ ${cell.color ? `color:${cell.color};` : ""}">${renderCell(cell.value, rowIndex)}
});
galleryHTML += "</div></div>";
});
galleryHTML += `<div class="av__gallery-add" data-type="av-add-bottom"><svg class="svg"><use xlink:href="#iconAdd"></use></svg><span class="fn__space"></span>${window.siyuan.languages.newCol}</div>`;
let tabHTML = "";
let viewData: IAVView;
response.data.views.forEach((item: IAVView) => {
@ -164,6 +165,13 @@ ${cell.color ? `color:${cell.color};` : ""}">${renderCell(cell.value, rowIndex)}
${view.hideAttrViewName ? " av__gallery--top" : ""}">
${galleryHTML}
</div>
<div class="av__row--util av__readonly--show">
<button class="b3-button${view.cardCount > view.cards.length ? "" : " fn__none"}" data-type="av-load-more">
<svg><use xlink:href="#iconArrowDown"></use></svg>
<span>${window.siyuan.languages.loadMore}</span>
<svg data-type="set-page-size" data-size="${view.pageSize}"><use xlink:href="#iconMore"></use></svg>
</button>
</div>
<div class="av__cursor" contenteditable="true">${Constants.ZWSP}</div>
</div>`;
} else {

View file

@ -1,4 +1,5 @@
import {transaction} from "../../wysiwyg/transaction";
import {Constants} from "../../../constants";
export const getLayoutHTML = (data: IAV) => {
let html = "";
@ -74,6 +75,12 @@ export const getLayoutHTML = (data: IAV) => {
<input data-type="toggle-view-title" type="checkbox" class="b3-switch b3-switch--menu" ${view.hideAttrViewName ? "" : "checked"}>
</label>
${html}
<button class="b3-menu__item" data-type="set-page-size" data-size="${view.pageSize}">
<span class="fn__flex-center">${window.siyuan.languages.entryNum}</span>
<span class="fn__flex-1"></span>
<span class="b3-menu__accelerator">${view.pageSize === Constants.SIZE_DATABASE_MAZ_SIZE ? window.siyuan.languages.all : view.pageSize}</span>
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
</button>
</div>`;
};

View file

@ -14,6 +14,7 @@ import {fetchPost} from "../../../util/fetch";
import {showMessage} from "../../../dialog/message";
import * as dayjs from "dayjs";
import {Constants} from "../../../constants";
import {insertGalleryItemAnimation} from "./gallery/item";
export const selectRow = (checkElement: Element, type: "toggle" | "select" | "unselect" | "unselectAll") => {
const rowElement = hasClosestByClassName(checkElement, "av__row");
@ -81,7 +82,7 @@ export const updateHeader = (rowElement: HTMLElement) => {
avHeadElement.style.position = "sticky";
};
const setPage = (blockElement: Element) => {
export const setPage = (blockElement: Element) => {
const pageSize = parseInt(blockElement.getAttribute("data-page-size"));
if (pageSize) {
const currentCount = blockElement.querySelectorAll(".av__row:not(.av__row--header)").length;
@ -477,6 +478,15 @@ export const insertRows = (blockElement: HTMLElement, protyle: IProtyle, count:
id: blockElement.dataset.nodeId,
data: blockElement.getAttribute("updated")
}]);
insertAttrViewBlockAnimation(protyle, blockElement, srcIDs, previousID, avID);
if (blockElement.getAttribute("data-av-type") === "gallery") {
insertGalleryItemAnimation({
blockElement,
protyle,
srcIDs,
previousId: previousID
});
} else {
insertAttrViewBlockAnimation(protyle, blockElement, srcIDs, previousID, avID);
}
blockElement.setAttribute("updated", newUpdated);
};

View file

@ -219,12 +219,6 @@ export const getViewHTML = (data: IAV) => {
<span class="b3-menu__accelerator">${view.sorts.length}</span>
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
</button>
<button class="b3-menu__item" data-type="set-page-size" data-size="${view.pageSize}">
<svg class="b3-menu__icon"></svg>
<span class="b3-menu__label">${window.siyuan.languages.entryNum}</span>
<span class="b3-menu__accelerator">${view.pageSize === Constants.SIZE_DATABASE_MAZ_SIZE ? window.siyuan.languages.all : view.pageSize}</span>
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
</button>
<button class="b3-menu__separator"></button>
<button class="b3-menu__item" data-type="duplicate-view">
<svg class="b3-menu__icon">