import {unicode2Emoji} from "../../../emoji"; import {getColIconByType} from "./col"; import {escapeHtml} from "../../../util/escape"; import {setPosition} from "../../../util/setPosition"; import {getFieldsByData} from "./view"; import {fetchSyncPost} from "../../../util/fetch"; import {Menu} from "../../../plugin/Menu"; import {objEquals} from "../../../util/functions"; export const getPageSize = (blockElement: Element) => { const groupPageSize: { [key: string]: { pageSize: number } } = {}; let unGroupPageSize: number; blockElement.querySelectorAll(".av__body").forEach((item: HTMLElement) => { const id = item.dataset.groupId; const pageSize = parseInt(item.dataset.pageSize); if (id) { groupPageSize[id] = {pageSize}; } else if (!unGroupPageSize) { unGroupPageSize = pageSize; } }); return {groupPageSize, unGroupPageSize}; }; export const setGroupMethod = async (options: { protyle: IProtyle; fieldId: string; data: IAV; menuElement: HTMLElement, blockElement: Element, }) => { const blockID = options.blockElement.getAttribute("data-node-id"); const column: IAVColumn = getFieldsByData(options.data).find(item => item.id === options.fieldId); const data = column ? { field: options.fieldId, method: column.type === "number" ? 1 : (["date", "updated", "created"].includes(column.type) ? 2 : 0), order: 0, range: column.type === "number" ? { numStart: 0, numEnd: 1000, numStep: 100, } : null, hideEmpty: true, } : {field: null, method: null, order: null, range: null, hideEmpty: null}; const response = await fetchSyncPost("/api/av/setAttrViewGroup", { blockID, avID: options.blockElement.getAttribute("data-av-id"), group: data }); options.data.view = response.data.view; options.menuElement.innerHTML = getGroupsHTML(getFieldsByData(options.data), options.data.view); bindGroupsEvent({ protyle: options.protyle, menuElement: options.menuElement, blockElement: options.blockElement, data: options.data }); 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[], group: IAVGroup) => { const selectHTML = ''; let html = ``; columns.forEach(item => { if (["rollup", "mAsset", "lineNumber"].includes(item.type)) { return; } html += ``; }); return `
${html}
`; }; export const getLanguageByIndex = (index: number, type: "sort" | "date") => { if (type === "sort") { switch (index) { case 0: return window.siyuan.languages.asc; case 1: return window.siyuan.languages.desc; case 2: return window.siyuan.languages.customSort; case 3: return window.siyuan.languages.sortBySelectOption; default: return ""; } } else if (type === "date") { switch (index) { case 2: return window.siyuan.languages.groupMethodDateRelative; case 3: return window.siyuan.languages.groupMethodDateDay; case 4: return window.siyuan.languages.groupMethodDateWeek; case 5: return window.siyuan.languages.groupMethodDateMonth; case 6: return window.siyuan.languages.groupMethodDateYear; default: return ""; } } }; export const getGroupsNumberHTML = (group: IAVGroup) => { return `
${window.siyuan.languages.groupRange}
-
${window.siyuan.languages.groupStep}
`; }; export const bindGroupsNumber = (options: { protyle: IProtyle; menuElement: HTMLElement; blockElement: Element; data: IAV; }) => { return async () => { if (!options.menuElement.querySelector('[data-type="avGroupRange"]')) { return; } const blockID = options.blockElement.getAttribute("data-node-id"); const inputElements = options.menuElement.querySelectorAll("input"); const range = { numStart: inputElements[0].value ? parseFloat(inputElements[0].value) : options.data.view.group.range.numStart, numEnd: inputElements[1].value ? parseFloat(inputElements[1].value) : options.data.view.group.range.numEnd, numStep: inputElements[2].value ? parseFloat(inputElements[2].value) : options.data.view.group.range.numStep }; if (objEquals(options.data.view.group.range, range)) { return; } Object.assign(options.data.view.group.range, range); const response = await fetchSyncPost("/api/av/setAttrViewGroup", { blockID, avID: options.blockElement.getAttribute("data-av-id"), group: options.data.view.group }); options.data.view = response.data.view; }; }; export const getGroupsHTML = (columns: IAVColumn[], view: IAVView) => { let html = ""; let column: IAVColumn; if (view.group && view.group.field) { let groupHTML = ""; column = columns.find(item => item.id === view.group.field); if (view.groups?.length > 0) { const disabledDrag = ["created", "date", "created", "updated"].includes(column.type); let showCount = 0; view.groups.forEach(item => { if (item.groupHidden === 0) { showCount++; } groupHTML += ``; }); groupHTML = ` ` + groupHTML; } html = ` ${groupHTML} `; } return `
${html}
`; }; export const bindGroupsEvent = (options: { protyle: IProtyle; menuElement: HTMLElement; blockElement: Element; data: IAV; }) => { const checkElement = options.menuElement.querySelector("input"); if (!checkElement) { return; } const blockID = options.blockElement.getAttribute("data-node-id"); checkElement.addEventListener("change", async () => { options.data.view.group.hideEmpty = checkElement.checked; const response = await fetchSyncPost("/api/av/setAttrViewGroup", { blockID, avID: options.blockElement.getAttribute("data-av-id"), group: options.data.view.group }); options.data.view = response.data.view; options.menuElement.innerHTML = getGroupsHTML(getFieldsByData(options.data), options.data.view); bindGroupsEvent({ protyle: options.protyle, menuElement: options.menuElement, blockElement: options.blockElement, data: options.data }); const tabRect = options.blockElement.querySelector(".av__views").getBoundingClientRect(); setPosition(options.menuElement, tabRect.right - options.menuElement.clientWidth, tabRect.bottom, tabRect.height); }); }; export const goGroupsDate = (options: { protyle: IProtyle; target: Element; menuElement: HTMLElement; data: IAV; blockElement: Element; }) => { const menu = new Menu("avGroupDate"); if (menu.isOpen) { return; } const blockID = options.blockElement.getAttribute("data-node-id"); [2, 3, 4, 5, 6].forEach((item) => { const label = getLanguageByIndex(item, "date"); menu.addItem({ iconHTML: "", checked: options.data.view.group.method === item, label, async click() { options.data.view.group.method = item; options.target.querySelector(".b3-menu__accelerator").textContent = label; const response = await fetchSyncPost("/api/av/setAttrViewGroup", { blockID, avID: options.blockElement.getAttribute("data-av-id"), group: options.data.view.group }); options.data.view = response.data.view; options.menuElement.innerHTML = getGroupsHTML(getFieldsByData(options.data), options.data.view); bindGroupsEvent({ protyle: options.protyle, menuElement: options.menuElement, blockElement: options.blockElement, data: options.data }); const tabRect = options.blockElement.querySelector(".av__views").getBoundingClientRect(); setPosition(options.menuElement, tabRect.right - options.menuElement.clientWidth, tabRect.bottom, tabRect.height); } }); }); const rect = options.target.getBoundingClientRect(); menu.open({ isLeft: true, x: rect.right, y: rect.bottom }); }; export const goGroupsSort = (options: { protyle: IProtyle; target: Element; data: IAV; menuElement: HTMLElement; blockElement: Element; }) => { const menu = new Menu("avGroupSort"); if (menu.isOpen) { return; } const blockID = options.blockElement.getAttribute("data-node-id"); const column = getFieldsByData(options.data).find(item => item.id === options.data.view.group.field); (["created", "date", "created", "updated"].includes(column.type) ? [0, 1] : ( ["mSelect", "select"].includes(column.type) ? [2, 0, 1, 3] : [2, 0, 1] )).forEach((item) => { const label = getLanguageByIndex(item, "sort"); menu.addItem({ iconHTML: "", checked: options.data.view.group.order === item, label, async click() { options.target.querySelector(".b3-menu__accelerator").textContent = label; options.data.view.group.order = item; const response = await fetchSyncPost("/api/av/setAttrViewGroup", { blockID, avID: options.blockElement.getAttribute("data-av-id"), group: options.data.view.group }); options.data.view = response.data.view; options.menuElement.innerHTML = getGroupsHTML(getFieldsByData(options.data), options.data.view); bindGroupsEvent({ protyle: options.protyle, menuElement: options.menuElement, blockElement: options.blockElement, data: options.data }); const tabRect = options.blockElement.querySelector(".av__views").getBoundingClientRect(); setPosition(options.menuElement, tabRect.right - options.menuElement.clientWidth, tabRect.bottom, tabRect.height); } }); }); const rect = options.target.getBoundingClientRect(); menu.open({ isLeft: true, x: rect.right, y: rect.bottom }); };