Vanessa 2025-07-04 18:27:11 +08:00
parent 476e7b6c66
commit 0446aeb1c6
5 changed files with 131 additions and 4 deletions

View file

@ -1,4 +1,8 @@
{
"groupMethod": "分组方式",
"hideEmptyGroup": "隐藏空白分组",
"groups": "组群",
"removeGroup": "移除分组",
"contentBlock": "内容块",
"insertItemBefore": "在前方插入${x}条",
"insertItemAfter": "在后方插入${x}条",

View file

@ -0,0 +1,94 @@
import {unicode2Emoji} from "../../../emoji";
import {getColIconByType} from "./col";
import {escapeHtml} from "../../../util/escape";
import {transaction} from "../../wysiwyg/transaction";
import {setPosition} from "../../../util/setPosition";
import {getFieldsByData} from "./view";
export const setGroupMethod = (options: {
protyle: IProtyle;
fieldId: string;
data: IAV;
menuElement: HTMLElement,
blockElement: HTMLElement,
}) => {
transaction(options.protyle, [{
action: "setAttrViewGroup",
data: {
field: options.fieldId,
method: null,
order: null,
range: null
}
}], [{
action: "setAttrViewGroup",
data: {
field: options.data.view.groups?.field || "",
method: null,
order: null,
range: null
}
}]);
options.data.view.groups.field = options.fieldId;
options.menuElement.innerHTML = getGroupsHTML(getFieldsByData(options.data), options.data.view.groups);
// bindGroupsEvent(options.protyle, options.menuElement, options.data, blockID);
const tabRect = options.blockElement.querySelector(".av__views").getBoundingClientRect();
setPosition(options.menuElement, tabRect.right - options.menuElement.clientWidth, tabRect.bottom, tabRect.height);
}
export const getGroupsMethodHTML = (columns: IAVColumn[], groups: IAVGroups) => {
const selectHTML = '<svg class="b3-menu__checked"><use xlink:href="#iconSelect"></use></svg>';
let html = `<button class="b3-menu__item" data-type="setGroupMethod">
<div class="b3-menu__label">${window.siyuan.languages.calcOperatorNone}</div>
${groups ? "" : selectHTML}
</button>`;
columns.forEach(item => {
html += `<button class="b3-menu__item" data-id="${item.id}" data-type="setGroupMethod">
<div class="b3-menu__label fn__flex">
${item.icon ? unicode2Emoji(item.icon, "b3-menu__icon", true) : `<svg class="b3-menu__icon"><use xlink:href="#${getColIconByType(item.type)}"></use></svg>`}
${escapeHtml(item.name) || "&nbsp;"}
</div>
${groups?.field === item.id ? selectHTML : ""}
</button>`;
});
return `<div class="b3-menu__items">
<button class="b3-menu__item" data-type="nobg">
<span class="block__icon" style="padding: 8px;margin-left: -4px;" data-type="goGroups">
<svg><use xlink:href="#iconLeft"></use></svg>
</span>
<span class="b3-menu__label ft__center">${window.siyuan.languages.groupMethod}</span>
</button>
<button class="b3-menu__separator"></button>
${html}
</div>`;
};
export const getGroupsHTML = (columns: IAVColumn[], groups: IAVGroups) => {
let html = "";
if (groups) {
html = `<button class="b3-menu__separator"></button>
<button class="b3-menu__item" data-type="removeGroups">
<svg class="b3-menu__icon"><use xlink:href="#iconTrashcan"></use></svg>
<span class="b3-menu__label">${window.siyuan.languages.delete}</span>
</button>`;
}
return `<div class="b3-menu__items">
<button class="b3-menu__item" data-type="nobg">
<span class="block__icon" style="padding: 8px;margin-left: -4px;" data-type="go-config">
<svg><use xlink:href="#iconLeft"></use></svg>
</span>
<span class="b3-menu__label ft__center">${window.siyuan.languages.group}</span>
</button>
<button class="b3-menu__separator"></button>
<button class="b3-menu__item" data-type="goGroupsMethod">
<span class="b3-menu__label">${window.siyuan.languages.groupMethod}</span>
<span class="b3-menu__accelerator">${groups ? columns.filter(item => item.id === groups.field)[0].name : ""}</span>
<svg class="b3-menu__icon b3-menu__icon--small"><use xlink:href="#iconRight"></use></svg>
</button>
${html}
</div>`;
};
export const bindGroupsEvent = (protyle: IProtyle, menuElement: HTMLElement, data: IAV, blockID: string) => {
};

View file

@ -47,6 +47,7 @@ import {escapeAttr, escapeHtml} from "../../../util/escape";
import {Dialog} from "../../../dialog";
import {bindLayoutEvent, getLayoutHTML, updateLayout} from "./layout";
import {setGalleryCover, setGalleryRatio, setGallerySize} from "./gallery/util";
import {bindGroupsEvent, getGroupsHTML, getGroupsMethodHTML, setGroupMethod} from "./groups";
export const openMenuPanel = (options: {
protyle: IProtyle,
@ -575,6 +576,31 @@ export const openMenuPanel = (options: {
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "goGroups") {
menuElement.innerHTML = getGroupsHTML(fields, data.view.groups);
bindGroupsEvent(options.protyle, menuElement, data, blockID);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
window.siyuan.menus.menu.remove();
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "goGroupsMethod") {
menuElement.innerHTML = getGroupsMethodHTML(fields, data.view.groups);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "setGroupMethod") {
setGroupMethod({
protyle: options.protyle,
fieldId: target.getAttribute("data-id"),
data,
menuElement,
blockElement: options.blockElement,
});
event.preventDefault();
event.stopPropagation();
break;
} else if (type === "removeSorts") {
transaction(options.protyle, [{
action: "setAttrViewSorts",

View file

@ -855,7 +855,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo:
"updateAttrViewColRelation", "setAttrViewPageSize", "updateAttrViewColRollup", "sortAttrViewKey", "setAttrViewColDesc",
"duplicateAttrViewKey", "setAttrViewViewDesc", "setAttrViewCoverFrom", "setAttrViewCoverFromAssetKeyID",
"setAttrViewBlockView", "setAttrViewCardSize", "setAttrViewCardAspectRatio", "hideAttrViewName", "setAttrViewShowIcon",
"setAttrViewWrapField"].includes(operation.action)) {
"setAttrViewWrapField", "setAttrViewGroup"].includes(operation.action)) {
if (!isUndo) {
// 撤销 transaction 会进行推送,需使用推送来进行刷新最新数据 https://github.com/siyuan-note/siyuan/issues/13607
refreshAV(protyle, operation);

View file

@ -63,6 +63,7 @@ type TOperation =
| "setAttrViewViewDesc"
| "setAttrViewColDesc"
| "setAttrViewBlockView"
| "setAttrViewGroup"
type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins"
type TCardType = "doc" | "notebook" | "all"
type TEventBus = "ws-main" | "sync-start" | "sync-end" | "sync-fail" |
@ -841,9 +842,7 @@ interface IAVView {
wrapField: boolean;
filters: IAVFilter[],
sorts: IAVSort[],
groups: {
field: string,
}
groups: IAVGroups
}
interface IAVTable extends IAVView {
@ -878,6 +877,10 @@ interface relativeDate {
direction: number; // 方向:-1: 前、0: 现在、1: 后
}
interface IAVGroups {
field: string,
}
interface IAVSort {
column: string,
order: "ASC" | "DESC"