diff --git a/app/appearance/themes/daylight/theme.css b/app/appearance/themes/daylight/theme.css
index 83ba4aa45..2280ddd3d 100644
--- a/app/appearance/themes/daylight/theme.css
+++ b/app/appearance/themes/daylight/theme.css
@@ -188,6 +188,8 @@
/* 数据库 */
--b3-av-gallery-shadow: rgba(0, 0, 0, 0.04) 0px 2px 4px 0px, var(--b3-border-color) 0px 0px 0px 1px;
+ --b3-av-kanban-border: var(--b3-border-color);
+ --b3-av-kanban-content-hover-bg: var(--b3-theme-surface);
/* 嵌入块 */
--b3-embed-background: transparent;
diff --git a/app/appearance/themes/midnight/theme.css b/app/appearance/themes/midnight/theme.css
index 5ae17ec88..bcb848592 100644
--- a/app/appearance/themes/midnight/theme.css
+++ b/app/appearance/themes/midnight/theme.css
@@ -187,6 +187,8 @@
/* 数据库 */
--b3-av-gallery-shadow: rgba(0, 0, 0, 0.04) 0px 2px 4px 0px, var(--b3-border-color) 0px 0px 0px 1px;
+ --b3-av-kanban-border: var(--b3-border-color);
+ --b3-av-kanban-content-hover-bg: var(--b3-theme-surface);
/* 嵌入块 */
--b3-embed-background: transparent;
diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss
index 64d749328..ca0c27782 100644
--- a/app/src/assets/scss/business/_av.scss
+++ b/app/src/assets/scss/business/_av.scss
@@ -976,7 +976,7 @@
&__kanban {
overflow: auto;
gap: 16px;
- padding: 0 1px 16px;
+ padding: 16px 1px;
display: flex;
&-group {
@@ -985,6 +985,12 @@
border-radius: var(--b3-border-radius);
background-color: var(--b3-av-kanban-bg);
+ &:hover {
+ .av__group-icon {
+ opacity: 1;
+ }
+ }
+
&--small {
width: 180px;
}
@@ -993,6 +999,10 @@
width: 320px;
}
+ .av__group-icon {
+ opacity: 0;
+ }
+
.av__group-title {
padding-top: 0;
}
diff --git a/app/src/protyle/render/av/gallery/render.ts b/app/src/protyle/render/av/gallery/render.ts
index 1042ce2e7..556e32419 100644
--- a/app/src/protyle/render/av/gallery/render.ts
+++ b/app/src/protyle/render/av/gallery/render.ts
@@ -12,6 +12,7 @@ import {processRender} from "../../../util/processCode";
import {getColIconByType, getColNameByType} from "../col";
import {getCompressURL} from "../../../../util/image";
import {getPageSize} from "../groups";
+import {renderKanban} from "../kanban/render";
interface IIds {
groupId: string,
@@ -146,7 +147,7 @@ const renderGroupGallery = (options: ITableOptions) => {
afterRenderGallery(options);
};
-const afterRenderGallery = (options: ITableOptions) => {
+export const afterRenderGallery = (options: ITableOptions) => {
const view = options.data.view as IAVGallery;
if (view.coverFrom === 1 || view.coverFrom === 3) {
processRender(options.blockElement);
@@ -324,8 +325,13 @@ export const renderGallery = async (options: {
data = response.data;
}
if (data.viewType === "table") {
- options.blockElement.setAttribute("data-av-type", "table");
- avRender(options.blockElement, options.protyle, options.cb, options.renderAll);
+ options.blockElement.setAttribute("data-av-type", data.viewType);
+ avRender(options.blockElement, options.protyle, options.cb, options.renderAll, data);
+ return;
+ }
+ if (data.viewType === "kanban") {
+ options.blockElement.setAttribute("data-av-type", data.viewType);
+ renderKanban({blockElement: options.blockElement, protyle:options.protyle, cb:options.cb, renderAll:options.renderAll, data});
return;
}
const view: IAVGallery = data.view as IAVGallery;
@@ -368,109 +374,3 @@ export const renderGallery = async (options: {
options.blockElement.querySelector(".av__gallery").classList.add("av__gallery--top");
}
};
-
-export const renderKanban = async (options: {
- blockElement: HTMLElement,
- protyle: IProtyle,
- cb?: (data: IAV) => void,
- renderAll: boolean,
- data?: IAV,
-}) => {
- const searchInputElement = options.blockElement.querySelector('[data-type="av-search"]') as HTMLInputElement;
- const editIds: IIds[] = [];
- options.blockElement.querySelectorAll(".av__gallery-fields--edit").forEach(item => {
- editIds.push({
- groupId: (hasClosestByClassName(item, "av__body") as HTMLElement).dataset.groupId || "",
- fieldId: item.parentElement.getAttribute("data-id"),
- });
- });
- const selectItemIds: IIds[] = [];
- options.blockElement.querySelectorAll(".av__gallery-item--select").forEach(galleryItem => {
- const fieldId = galleryItem.getAttribute("data-id");
- if (fieldId) {
- selectItemIds.push({
- groupId: (hasClosestByClassName(galleryItem, "av__body") as HTMLElement).dataset.groupId || "",
- fieldId
- });
- }
- });
- const pageSizes: { [key: string]: string } = {};
- options.blockElement.querySelectorAll(".av__body").forEach((item: HTMLElement) => {
- pageSizes[item.dataset.groupId || "unGroup"] = item.dataset.pageSize;
- });
- const resetData = {
- isSearching: searchInputElement && document.activeElement === searchInputElement,
- query: searchInputElement?.value || "",
- alignSelf: options.blockElement.style.alignSelf,
- oldOffset: options.protyle.contentElement.scrollTop,
- editIds,
- selectItemIds,
- pageSizes,
- };
- if (options.blockElement.firstElementChild.innerHTML === "") {
- options.blockElement.style.alignSelf = "";
- options.blockElement.firstElementChild.outerHTML = `
-
-
-
-
`;
- }
- const created = options.protyle.options.history?.created;
- const snapshot = options.protyle.options.history?.snapshot;
-
- let data: IAV = options.data;
- if (!data) {
- const avPageSize = getPageSize(options.blockElement);
- const response = await fetchSyncPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), {
- id: options.blockElement.getAttribute("data-av-id"),
- created,
- snapshot,
- pageSize: avPageSize.unGroupPageSize,
- groupPaging: avPageSize.groupPageSize,
- viewID: options.blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW) || "",
- query: resetData.query.trim()
- });
- data = response.data;
- }
- if (data.viewType === "table") {
- options.blockElement.setAttribute("data-av-type", "table");
- avRender(options.blockElement, options.protyle, options.cb, options.renderAll);
- return;
- }
- const view: IAVGallery = data.view as IAVGallery;
- let bodyHTML = "";
- view.groups.forEach((group: IAVGallery) => {
- if (group.groupHidden === 0) {
- let selectBg;
- if (["mSelect", "select"].includes(group.groupValue.type)) {
- selectBg = getComputedStyle(document.documentElement).getPropertyValue(`--b3-font-background${group.groupValue.mSelect[0].color}`);
- }
- bodyHTML += `
- ${getGroupTitleHTML(group, group.cards.length)}
-
${getGalleryHTML(group)}
-
`;
- }
- });
- if (options.renderAll) {
- options.blockElement.firstElementChild.outerHTML = `
- ${genTabHeaderHTML(data, resetData.isSearching || !!resetData.query, !options.protyle.disabled && !hasClosestByAttribute(options.blockElement, "data-type", "NodeBlockQueryEmbed"))}
-
- ${bodyHTML}
-
-
${Constants.ZWSP}
-
`;
- } else {
- options.blockElement.querySelector(".av__kanban").innerHTML = bodyHTML;
- }
- afterRenderGallery({
- resetData,
- renderAll: options.renderAll,
- data,
- cb: options.cb,
- protyle: options.protyle,
- blockElement: options.blockElement,
- });
- if (view.hideAttrViewName) {
- options.blockElement.querySelector(".av__gallery").classList.add("av__gallery--top");
- }
-};
diff --git a/app/src/protyle/render/av/kanban/render.ts b/app/src/protyle/render/av/kanban/render.ts
new file mode 100644
index 000000000..3c9237c77
--- /dev/null
+++ b/app/src/protyle/render/av/kanban/render.ts
@@ -0,0 +1,243 @@
+import {hasClosestByAttribute, hasClosestByClassName} from "../../../util/hasClosest";
+import {getPageSize} from "../groups";
+import {fetchSyncPost} from "../../../../util/fetch";
+import {Constants} from "../../../../constants";
+import {avRender, genTabHeaderHTML} from "../render";
+import {afterRenderGallery, renderGallery} from "../gallery/render";
+import {escapeAttr, escapeHtml} from "../../../../util/escape";
+import {getCompressURL} from "../../../../util/image";
+import {cellValueIsEmpty, renderCell} from "../cell";
+import {getColIconByType, getColNameByType} from "../col";
+import {unicode2Emoji} from "../../../../emoji";
+
+interface IIds {
+ groupId: string,
+ fieldId: string,
+}
+
+const getKanbanTitleHTML = (group: IAVView, counter: number) => {
+ let nameHTML = "";
+ if (["mSelect", "select"].includes(group.groupValue.type)) {
+ group.groupValue.mSelect.forEach((item) => {
+ nameHTML += `${escapeHtml(item.content)}`;
+ });
+ } else if (group.groupValue.type === "checkbox") {
+ nameHTML = ``;
+ } else {
+ nameHTML = group.name;
+ }
+ // av__group-name 为第三方需求,本应用内没有使用,但不能移除 https://github.com/siyuan-note/siyuan/issues/15736
+ return `
+ ${nameHTML}
+ ${counter === 0 ? '' : `${counter}`}
+
+
+
`;
+};
+
+const getKanbanHTML = (data: IAVKanban) => {
+ let galleryHTML = "";
+ // body
+ data.cards.forEach((item: IAVGalleryItem, rowIndex: number) => {
+ galleryHTML += ``;
+ if (data.coverFrom !== 0) {
+ const coverClass = "av__gallery-cover av__gallery-cover--" + data.cardAspectRatio;
+ if (item.coverURL) {
+ if (item.coverURL.startsWith("background")) {
+ galleryHTML += `
`;
+ } else {
+ galleryHTML += `
`;
+ }
+ } else if (item.coverContent) {
+ galleryHTML += `
`;
+ } else {
+ galleryHTML += `
`;
+ }
+ }
+ galleryHTML += '
';
+ item.values.forEach((cell, fieldsIndex) => {
+ if (data.fields[fieldsIndex].hidden) {
+ return;
+ }
+ let checkClass = "";
+ if (cell.valueType === "checkbox") {
+ checkClass = cell.value?.checkbox?.checked ? " av__cell-check" : " av__cell-uncheck";
+ }
+ const isEmpty = cellValueIsEmpty(cell.value);
+ // NOTE: innerHTML 中不能换行否则 https://github.com/siyuan-note/siyuan/issues/15132
+ let ariaLabel = escapeAttr(data.fields[fieldsIndex].name) || getColNameByType(data.fields[fieldsIndex].type);
+ if (data.fields[fieldsIndex].desc) {
+ ariaLabel += escapeAttr(`
${data.fields[fieldsIndex].desc}
`);
+ }
+
+ if (cell.valueType === "checkbox" && !data.displayFieldName) {
+ cell.value.checkbox.content = data.fields[fieldsIndex].name || getColNameByType(data.fields[fieldsIndex].type);
+ }
+ const cellHTML = `
${renderCell(cell.value, rowIndex, data.showIcon, "gallery")}
`;
+ if (data.displayFieldName) {
+ galleryHTML += `
+
+ ${data.fields[fieldsIndex].icon ? unicode2Emoji(data.fields[fieldsIndex].icon, undefined, true) : ``}${Lute.EscapeHTMLStr(data.fields[fieldsIndex].name)}
+ ${data.fields[fieldsIndex].desc ? `` : ""}
+
+ ${cellHTML}
+
`;
+ } else {
+ galleryHTML += `
+
+ ${data.fields[fieldsIndex].icon ? unicode2Emoji(data.fields[fieldsIndex].icon, undefined, true) : ``}${window.siyuan.languages.edit} ${Lute.EscapeHTMLStr(data.fields[fieldsIndex].name)}
+
+ ${cellHTML}
+
`;
+ }
+ });
+ galleryHTML += `
+
+
+
+
+
`;
+ });
+ galleryHTML += `${window.siyuan.languages.newRow}
`;
+ return `
+ ${galleryHTML}
+
+
+
+
`;
+};
+
+export const renderKanban = async (options: {
+ blockElement: HTMLElement,
+ protyle: IProtyle,
+ cb?: (data: IAV) => void,
+ renderAll: boolean,
+ data?: IAV,
+}) => {
+ const searchInputElement = options.blockElement.querySelector('[data-type="av-search"]') as HTMLInputElement;
+ const editIds: IIds[] = [];
+ options.blockElement.querySelectorAll(".av__gallery-fields--edit").forEach(item => {
+ editIds.push({
+ groupId: (hasClosestByClassName(item, "av__body") as HTMLElement).dataset.groupId || "",
+ fieldId: item.parentElement.getAttribute("data-id"),
+ });
+ });
+ const selectItemIds: IIds[] = [];
+ options.blockElement.querySelectorAll(".av__gallery-item--select").forEach(galleryItem => {
+ const fieldId = galleryItem.getAttribute("data-id");
+ if (fieldId) {
+ selectItemIds.push({
+ groupId: (hasClosestByClassName(galleryItem, "av__body") as HTMLElement).dataset.groupId || "",
+ fieldId
+ });
+ }
+ });
+ const pageSizes: { [key: string]: string } = {};
+ options.blockElement.querySelectorAll(".av__body").forEach((item: HTMLElement) => {
+ pageSizes[item.dataset.groupId || "unGroup"] = item.dataset.pageSize;
+ });
+ const resetData = {
+ isSearching: searchInputElement && document.activeElement === searchInputElement,
+ query: searchInputElement?.value || "",
+ alignSelf: options.blockElement.style.alignSelf,
+ oldOffset: options.protyle.contentElement.scrollTop,
+ editIds,
+ selectItemIds,
+ pageSizes,
+ };
+ if (options.blockElement.firstElementChild.innerHTML === "") {
+ options.blockElement.style.alignSelf = "";
+ options.blockElement.firstElementChild.outerHTML = `
+
+
+
+
`;
+ }
+ const created = options.protyle.options.history?.created;
+ const snapshot = options.protyle.options.history?.snapshot;
+
+ let data: IAV = options.data;
+ if (!data) {
+ const avPageSize = getPageSize(options.blockElement);
+ const response = await fetchSyncPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), {
+ id: options.blockElement.getAttribute("data-av-id"),
+ created,
+ snapshot,
+ pageSize: avPageSize.unGroupPageSize,
+ groupPaging: avPageSize.groupPageSize,
+ viewID: options.blockElement.getAttribute(Constants.CUSTOM_SY_AV_VIEW) || "",
+ query: resetData.query.trim()
+ });
+ data = response.data;
+ }
+ if (data.viewType === "table") {
+ options.blockElement.setAttribute("data-av-type", "table");
+ avRender(options.blockElement, options.protyle, options.cb, options.renderAll, data);
+ return;
+ }
+ if (data.viewType === "gallery") {
+ options.blockElement.setAttribute("data-av-type", data.viewType);
+ renderGallery({blockElement: options.blockElement, protyle:options.protyle, cb:options.cb, renderAll:options.renderAll, data});
+ return;
+ }
+ const view: IAVGallery = data.view as IAVKanban;
+ let bodyHTML = "";
+ let isSelectGroup = true;
+ view.groups.forEach((group: IAVKanban) => {
+ if (group.groupHidden === 0) {
+ let selectBg = "";
+ if (group.fillColBackgroundColor) {
+ let color = ""
+ if (["mSelect", "select"].includes(group.groupValue.type)) {
+ isSelectGroup = true;
+ color = getComputedStyle(document.documentElement).getPropertyValue(`--b3-font-background${group.groupValue.mSelect[0].color}`);
+ }
+ if (isSelectGroup) {
+ if (!color) {
+ color = getComputedStyle(document.documentElement).getPropertyValue("--b3-border-color");
+ }
+ selectBg = `style="--b3-av-kanban-border:${color};--b3-av-kanban-bg:${color}29;--b3-av-kanban-content-bg:${color}47;--b3-av-kanban-content-hover-bg:${color}5c;"`;
+ }
+ }
+ bodyHTML += `
+ ${getKanbanTitleHTML(group, group.cards.length)}
+
${getKanbanHTML(group)}
+
`;
+ }
+ });
+ if (options.renderAll) {
+ options.blockElement.firstElementChild.outerHTML = `
+ ${genTabHeaderHTML(data, resetData.isSearching || !!resetData.query, !options.protyle.disabled && !hasClosestByAttribute(options.blockElement, "data-type", "NodeBlockQueryEmbed"))}
+
+ ${bodyHTML}
+
+
${Constants.ZWSP}
+
`;
+ } else {
+ options.blockElement.querySelector(".av__kanban").innerHTML = bodyHTML;
+ }
+ afterRenderGallery({
+ resetData,
+ renderAll: options.renderAll,
+ data,
+ cb: options.cb,
+ protyle: options.protyle,
+ blockElement: options.blockElement,
+ });
+ if (view.hideAttrViewName) {
+ options.blockElement.querySelector(".av__gallery").classList.add("av__gallery--top");
+ }
+};
diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts
index 7b6fedefd..9bd15bf5e 100644
--- a/app/src/protyle/render/av/render.ts
+++ b/app/src/protyle/render/av/render.ts
@@ -1,4 +1,4 @@
-import {fetchPost} from "../../../util/fetch";
+import {fetchSyncPost} from "../../../util/fetch";
import {getColIconByType} from "./col";
import {Constants} from "../../../constants";
import {addDragFill, cellScrollIntoView, popTextCell, renderCell} from "./cell";
@@ -13,12 +13,13 @@ import {escapeAriaLabel, escapeAttr, escapeHtml} from "../../../util/escape";
import {electronUndo} from "../../undo";
import {isInAndroid, isInHarmony, isInIOS} from "../../util/compatibility";
import {isMobile} from "../../../util/functions";
-import {renderKanban, renderGallery} from "./gallery/render";
+import {renderGallery} from "./gallery/render";
import {getFieldsByData, getViewIcon} from "./view";
import {openMenuPanel} from "./openMenuPanel";
import {getPageSize} from "./groups";
import {clearSelect} from "../../util/clearSelect";
import {showMessage} from "../../../dialog/message";
+import {renderKanban} from "./kanban/render";
interface IIds {
groupId: string,
@@ -250,7 +251,7 @@ export const getGroupTitleHTML = (group: IAVView, counter: number) => {
${nameHTML}
- ${counter === 0 ? '' : `${counter}`}
+ ${counter === 0 ? '' : `${counter}`}
`;
};
@@ -442,7 +443,7 @@ const afterRenderTable = (options: ITableOptions) => {
});
};
-export const avRender = (element: Element, protyle: IProtyle, cb?: (data: IAV) => void, renderAll = true) => {
+export const avRender = async (element: Element, protyle: IProtyle, cb?: (data: IAV) => void, renderAll = true, data?: IAV) => {
let avElements: Element[] = [];
if (element.getAttribute("data-type") === "NodeAttributeView") {
// 编辑器内代码块编辑渲染
@@ -453,97 +454,98 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: (data: IAV) =
if (avElements.length === 0) {
return;
}
- if (avElements.length > 0) {
- avElements.forEach((e: HTMLElement) => {
- e.removeAttribute("data-rendering");
- if (e.getAttribute("data-render") === "true" || hasClosestByClassName(e, "av__gallery-content")) {
- return;
- }
- if (isMobile() || isInIOS() || isInAndroid() || isInHarmony()) {
- e.classList.add("av--touch");
- }
+ for (let i = 0; i < avElements.length; i++) {
+ const e = avElements[i] as HTMLElement;
+ e.removeAttribute("data-rendering");
+ if (e.getAttribute("data-render") === "true" || hasClosestByClassName(e, "av__gallery-content")) {
+ return;
+ }
+ if (isMobile() || isInIOS() || isInAndroid() || isInHarmony()) {
+ e.classList.add("av--touch");
+ }
- if (e.getAttribute("data-av-type") === "gallery") {
- renderGallery({blockElement: e, protyle, cb, renderAll});
- return;
- }
- if (e.getAttribute("data-av-type") === "kanban") {
- renderKanban({blockElement: e, protyle, cb, renderAll});
- return;
- }
+ if (e.getAttribute("data-av-type") === "gallery") {
+ renderGallery({blockElement: e, protyle, cb, renderAll});
+ return;
+ }
+ if (e.getAttribute("data-av-type") === "kanban") {
+ renderKanban({blockElement: e, protyle, cb, renderAll});
+ return;
+ }
- let selectCellId;
- const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
- if (selectCellElement) {
- selectCellId = {
- groupId: (hasClosestByClassName(selectCellElement, "av__body") as HTMLElement).dataset.groupId || "",
- rowId: (hasClosestByClassName(selectCellElement, "av__row") as HTMLElement).dataset.id,
- colId: selectCellElement.getAttribute("data-col-id"),
- };
- }
- const selectRowIds: IIds[] = [];
- e.querySelectorAll(".av__row--select").forEach(rowItem => {
- const rowId = rowItem.getAttribute("data-id");
- if (rowId) {
- selectRowIds.push({
- groupId: (hasClosestByClassName(rowItem, "av__body") as HTMLElement).dataset.groupId || "",
- rowId
- });
- }
- });
- let dragFillId;
- const dragFillElement = e.querySelector(".av__drag-fill") as HTMLElement;
- if (dragFillElement) {
- dragFillId = {
- groupId: (hasClosestByClassName(dragFillElement, "av__body") as HTMLElement).dataset.groupId || "",
- rowId: (hasClosestByClassName(dragFillElement, "av__row") as HTMLElement).dataset.id,
- colId: dragFillElement.parentElement.getAttribute("data-col-id"),
- };
- }
- const activeIds: IIds[] = [];
- e.querySelectorAll(".av__cell--active").forEach((item: HTMLElement) => {
- activeIds.push({
- groupId: (hasClosestByClassName(item, "av__body") as HTMLElement).dataset.groupId || "",
- rowId: (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id,
- colId: item.getAttribute("data-col-id"),
- });
- });
- const searchInputElement = e.querySelector('[data-type="av-search"]') as HTMLInputElement;
- const pageSizes: { [key: string]: string } = {};
- e.querySelectorAll(".av__body").forEach((item: HTMLElement) => {
- pageSizes[item.dataset.groupId || "unGroup"] = item.dataset.pageSize;
- });
- const resetData = {
- selectCellId,
- alignSelf: e.style.alignSelf,
- left: e.querySelector(".av__scroll")?.scrollLeft || 0,
- headerTransform: (e.querySelector('.av__row--header[style^="transform"]') as HTMLElement)?.style.transform,
- footerTransform: (e.querySelector(".av__row--footer") as HTMLElement)?.style.transform,
- isSearching: searchInputElement && document.activeElement === searchInputElement,
- selectRowIds,
- dragFillId,
- activeIds,
- query: searchInputElement?.value || "",
- pageSizes
+ let selectCellId;
+ const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
+ if (selectCellElement) {
+ selectCellId = {
+ groupId: (hasClosestByClassName(selectCellElement, "av__body") as HTMLElement).dataset.groupId || "",
+ rowId: (hasClosestByClassName(selectCellElement, "av__row") as HTMLElement).dataset.id,
+ colId: selectCellElement.getAttribute("data-col-id"),
};
- if (e.firstElementChild.innerHTML === "") {
- e.style.alignSelf = "";
- let html = "";
- [1, 2, 3].forEach(() => {
- html += `
+ }
+ const selectRowIds: IIds[] = [];
+ e.querySelectorAll(".av__row--select").forEach(rowItem => {
+ const rowId = rowItem.getAttribute("data-id");
+ if (rowId) {
+ selectRowIds.push({
+ groupId: (hasClosestByClassName(rowItem, "av__body") as HTMLElement).dataset.groupId || "",
+ rowId
+ });
+ }
+ });
+ let dragFillId;
+ const dragFillElement = e.querySelector(".av__drag-fill") as HTMLElement;
+ if (dragFillElement) {
+ dragFillId = {
+ groupId: (hasClosestByClassName(dragFillElement, "av__body") as HTMLElement).dataset.groupId || "",
+ rowId: (hasClosestByClassName(dragFillElement, "av__row") as HTMLElement).dataset.id,
+ colId: dragFillElement.parentElement.getAttribute("data-col-id"),
+ };
+ }
+ const activeIds: IIds[] = [];
+ e.querySelectorAll(".av__cell--active").forEach((item: HTMLElement) => {
+ activeIds.push({
+ groupId: (hasClosestByClassName(item, "av__body") as HTMLElement).dataset.groupId || "",
+ rowId: (hasClosestByClassName(item, "av__row") as HTMLElement).dataset.id,
+ colId: item.getAttribute("data-col-id"),
+ });
+ });
+ const searchInputElement = e.querySelector('[data-type="av-search"]') as HTMLInputElement;
+ const pageSizes: { [key: string]: string } = {};
+ e.querySelectorAll(".av__body").forEach((item: HTMLElement) => {
+ pageSizes[item.dataset.groupId || "unGroup"] = item.dataset.pageSize;
+ });
+ const resetData = {
+ selectCellId,
+ alignSelf: e.style.alignSelf,
+ left: e.querySelector(".av__scroll")?.scrollLeft || 0,
+ headerTransform: (e.querySelector('.av__row--header[style^="transform"]') as HTMLElement)?.style.transform,
+ footerTransform: (e.querySelector(".av__row--footer") as HTMLElement)?.style.transform,
+ isSearching: searchInputElement && document.activeElement === searchInputElement,
+ selectRowIds,
+ dragFillId,
+ activeIds,
+ query: searchInputElement?.value || "",
+ pageSizes
+ };
+ if (e.firstElementChild.innerHTML === "") {
+ e.style.alignSelf = "";
+ let html = "";
+ [1, 2, 3].forEach(() => {
+ html += `
`;
- });
- e.firstElementChild.innerHTML = html;
- }
- const created = protyle.options.history?.created;
- const snapshot = protyle.options.history?.snapshot;
- const avPageSize = getPageSize(e);
- fetchPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), {
+ });
+ e.firstElementChild.innerHTML = html;
+ }
+ const created = protyle.options.history?.created;
+ const snapshot = protyle.options.history?.snapshot;
+ const avPageSize = getPageSize(e);
+ if (!data) {
+ const response = await fetchSyncPost(created ? "/api/av/renderHistoryAttributeView" : (snapshot ? "/api/av/renderSnapshotAttributeView" : "/api/av/renderAttributeView"), {
id: e.getAttribute("data-av-id"),
created,
snapshot,
@@ -552,43 +554,48 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: (data: IAV) =
viewID: e.getAttribute(Constants.CUSTOM_SY_AV_VIEW) || "",
query: resetData.query.trim(),
blockID: e.getAttribute("data-node-id"),
- }, (response) => {
- const data = response.data.view as IAVTable;
- if (response.data.viewType === "gallery") {
- e.setAttribute("data-av-type", "table");
- renderGallery({blockElement: e, protyle, cb, renderAll, data: response.data});
- return;
- }
- if (data.groups?.length > 0) {
- renderGroupTable({blockElement: e, protyle, cb, renderAll, data: response.data, resetData});
- return;
- }
- const avBodyHTML = `
- ${getTableHTMLs(data, e)}
+ });
+ data = response.data;
+ }
+ if (data.viewType === "gallery") {
+ e.setAttribute("data-av-type", data.viewType);
+ renderGallery({blockElement: e, protyle, cb, renderAll, data});
+ return;
+ }
+ if (data.viewType === "kanban") {
+ e.setAttribute("data-av-type", data.viewType);
+ renderKanban({blockElement: e, protyle, cb, renderAll, data});
+ return;
+ }
+ const view = data.view as IAVTable;
+ if (view.groups?.length > 0) {
+ renderGroupTable({blockElement: e, protyle, cb, renderAll, data, resetData});
+ return;
+ }
+ const avBodyHTML = `
+ ${getTableHTMLs(view, e)}
`;
- if (renderAll) {
- e.firstElementChild.outerHTML = `
- ${genTabHeaderHTML(response.data, resetData.isSearching || !!resetData.query, !protyle.disabled && !hasClosestByAttribute(e, "data-type", "NodeBlockQueryEmbed"))}
+ if (renderAll) {
+ e.firstElementChild.outerHTML = `
+ ${genTabHeaderHTML(data, resetData.isSearching || !!resetData.query, !protyle.disabled && !hasClosestByAttribute(e, "data-type", "NodeBlockQueryEmbed"))}
${avBodyHTML}
${Constants.ZWSP}
`;
- } else {
- e.firstElementChild.querySelector(".av__scroll").innerHTML = avBodyHTML;
- }
- afterRenderTable({
- renderAll,
- data: response.data,
- cb,
- protyle,
- blockElement: e,
- resetData
- });
- // 历史兼容
- e.style.margin = "";
- });
+ } else {
+ e.firstElementChild.querySelector(".av__scroll").innerHTML = avBodyHTML;
+ }
+ afterRenderTable({
+ renderAll,
+ data,
+ cb,
+ protyle,
+ blockElement: e,
+ resetData
});
+ // 历史兼容
+ e.style.margin = "";
}
};
diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts
index f3fcf2426..b00eb28bf 100644
--- a/app/src/types/index.d.ts
+++ b/app/src/types/index.d.ts
@@ -909,6 +909,20 @@ interface IAVGallery extends IAVView {
cardCount: number,
}
+interface IAVKanban extends IAVView {
+ coverFrom: number; // 0:无,1:内容图,2:资源字段,3:内容块
+ coverFromAssetKeyID?: string;
+ cardSize: number; // 0:小卡片,1:中卡片,2:大卡片
+ cardAspectRatio: number;
+ displayFieldName: boolean;
+ fitImage: boolean;
+ cards: IAVGalleryItem[],
+ desc: string
+ fields: IAVColumn[]
+ cardCount: number,
+ fillColBackgroundColor: boolean
+}
+
interface IAVFilter {
column: string,
operator: TAVFilterOperator,
diff --git a/app/src/util/assets.ts b/app/src/util/assets.ts
index f2bbc699a..a737012f9 100644
--- a/app/src/util/assets.ts
+++ b/app/src/util/assets.ts
@@ -58,9 +58,14 @@ export const loadAssets = (data: Config.IAppearance) => {
/// #if !MOBILE
setTimeout(() => {
document.querySelectorAll(".av__kanban-group").forEach(item => {
- const nameElement = item.querySelector(".av__group-title .b3-chip") as HTMLElement;
- if (nameElement) {
- const selectBg = getComputedStyle(document.documentElement).getPropertyValue(`--b3-font-background${nameElement.style.backgroundColor.slice(-2, -1)}`);
+ if (item.getAttribute("style")) {
+ let selectBg;
+ const nameElement = item.querySelector(".av__group-title .b3-chip") as HTMLElement;
+ if (nameElement) {
+ selectBg = getComputedStyle(document.documentElement).getPropertyValue(`--b3-font-background${nameElement.style.backgroundColor.slice(-2, -1)}`);
+ } else {
+ selectBg = getComputedStyle(document.documentElement).getPropertyValue("--b3-border-color");
+ }
item.setAttribute("style", `--b3-av-kanban-border:${selectBg};--b3-av-kanban-bg:${selectBg}29;--b3-av-kanban-content-bg:${selectBg}47;--b3-av-kanban-content-hover-bg:${selectBg}5c;`);
}
});