import {hasClosestBlock} from "../../util/hasClosest"; import {Menu} from "../../../plugin/Menu"; import {transaction} from "../../wysiwyg/transaction"; import {fetchPost} from "../../../util/fetch"; import {getDefaultOperatorByType, setFilter} from "./filter"; import {genCellValue} from "./cell"; import {openMenuPanel} from "./openMenuPanel"; import {getLabelByNumberFormat} from "./number"; import {removeAttrViewColAnimation, updateAttrViewCellAnimation} from "./action"; import {openEmojiPanel, unicode2Emoji} from "../../../emoji"; export const duplicateCol = (options: { protyle: IProtyle, type: TAVCol, avID: string, colId: string, newValue: string, icon: string }) => { const id = Lute.NewNodeID(); const nameMatch = options.newValue.match(/^(.*) \((\d+)\)$/); if (nameMatch) { options.newValue = `${nameMatch[1]} (${parseInt(nameMatch[2]) + 1})`; } else { options.newValue = `${options.newValue} (1)`; } if (["select", "mSelect"].includes(options.type)) { fetchPost("/api/av/renderAttributeView", {id: options.avID}, (response) => { const data = response.data as IAV; let colOptions; data.view.columns.find((item) => { if (item.id === options.colId) { colOptions = item.options; return true; } }); transaction(options.protyle, [{ action: "addAttrViewCol", name: options.newValue, avID: options.avID, type: options.type, data: options.icon, id }, { action: "sortAttrViewCol", avID: options.avID, previousID: options.colId, id }, { action: "updateAttrViewColOptions", id, avID: options.avID, data: colOptions }], [{ action: "removeAttrViewCol", id, avID: options.avID, }]); }); } else { transaction(options.protyle, [{ action: "addAttrViewCol", name: options.newValue, avID: options.avID, type: options.type, data: options.icon, id }, { action: "sortAttrViewCol", avID: options.avID, previousID: options.colId, id }], [{ action: "removeAttrViewCol", id, avID: options.avID, }]); } addAttrViewColAnimation({ blockElement: options.protyle.wysiwyg.element.querySelector(`[data-av-id="${options.avID}"]`), protyle: options.protyle, type: options.type, name: options.newValue, icon: options.icon, previousId: options.colId, id }); }; export const getEditHTML = (options: { protyle: IProtyle, colId: string, data: IAV }) => { let colData: IAVColumn; options.data.view.columns.find((item) => { if (item.id === options.colId) { colData = item; return true; } }); let html = ` `; if (colData.options && colData.options.length > 0) { html += ` `; colData.options.forEach(item => { html += ``; }); } if (colData.type === "number") { html += ` `; } else if (colData.type === "template") { html += ` `; } return `
`; }; export const bindEditEvent = (options: { protyle: IProtyle, data: IAV, menuElement: HTMLElement }) => { const avID = options.data.id; const colId = options.menuElement.querySelector(".b3-menu__item").getAttribute("data-col-id"); const colData = options.data.view.columns.find((item: IAVColumn) => item.id === colId); const nameElement = options.menuElement.querySelector('[data-type="name"]') as HTMLInputElement; nameElement.addEventListener("blur", () => { const newValue = nameElement.value; if (newValue === colData.name) { return; } transaction(options.protyle, [{ action: "updateAttrViewCol", id: colId, avID, name: newValue, type: colData.type, }], [{ action: "updateAttrViewCol", id: colId, avID, name: colData.name, type: colData.type, }]); colData.name = newValue; updateAttrViewCellAnimation(options.protyle.wysiwyg.element.querySelector(`.av__row--header .av__cell[data-col-id="${colId}"]`)); }); nameElement.addEventListener("keydown", (event: KeyboardEvent) => { if (event.isComposing) { return; } if (event.key === "Escape") { options.menuElement.parentElement.remove(); } else if (event.key === "Enter") { nameElement.dispatchEvent(new CustomEvent("blur")); options.menuElement.parentElement.remove(); } }); const tplElement = options.menuElement.querySelector('[data-type="updateTemplate"]') as HTMLTextAreaElement; if (tplElement) { tplElement.addEventListener("blur", () => { const newValue = tplElement.value; if (newValue === colData.template) { return; } transaction(options.protyle, [{ action: "updateAttrViewColTemplate", id: colId, avID, data: newValue, type: colData.type, }], [{ action: "updateAttrViewColTemplate", id: colId, avID, data: colData.template, type: colData.type, }]); colData.template = newValue; }); tplElement.addEventListener("keydown", (event: KeyboardEvent) => { if (event.isComposing) { return; } if (event.key === "Escape") { options.menuElement.parentElement.remove(); } else if (event.key === "Enter" && !event.shiftKey) { tplElement.dispatchEvent(new CustomEvent("blur")); options.menuElement.parentElement.remove(); } }); } const addOptionElement = options.menuElement.querySelector('[data-type="addOption"]') as HTMLInputElement; if (!addOptionElement) { return; } addOptionElement.addEventListener("keydown", (event: KeyboardEvent) => { if (event.isComposing) { return; } if (event.key === "Escape") { options.menuElement.parentElement.remove(); } if (event.key === "Enter") { let hasSelected = false; colData.options.find((item) => { if (addOptionElement.value === item.name) { hasSelected = true; return true; } }); if (hasSelected) { return; } colData.options.push({ color: (colData.options.length + 1).toString(), name: addOptionElement.value }); transaction(options.protyle, [{ action: "updateAttrViewColOptions", id: colId, avID, data: colData.options }], [{ action: "removeAttrViewColOption", id: colId, avID, data: addOptionElement.value }]); options.menuElement.innerHTML = getEditHTML({protyle: options.protyle, colId, data: options.data}); bindEditEvent({protyle: options.protyle, menuElement: options.menuElement, data: options.data}); (options.menuElement.querySelector('[data-type="addOption"]') as HTMLInputElement).focus(); } }); }; export const getColIconByType = (type: TAVCol) => { switch (type) { case "text": return "iconAlignLeft"; case "block": return "iconParagraph"; case "number": return "iconNumber"; case "select": return "iconListItem"; case "mSelect": return "iconList"; case "date": return "iconCalendar"; case "updated": case "created": return "iconClock"; case "url": return "iconLink"; case "mAsset": return "iconImage"; case "email": return "iconEmail"; case "phone": return "iconPhone"; case "template": return "iconMath"; } }; export const updateHeader = (rowElement: HTMLElement) => { const blockElement = hasClosestBlock(rowElement); if (!blockElement) { return; } const selectCount = rowElement.parentElement.querySelectorAll(".av__row--select:not(.av__row--header)").length; const diffCount = rowElement.parentElement.childElementCount - 3 - selectCount; const headElement = rowElement.parentElement.firstElementChild; const headUseElement = headElement.querySelector("use"); const counterElement = blockElement.querySelector(".av__counter"); const avHeadElement = blockElement.querySelector(".av__header") as HTMLElement; if (diffCount === 0 && rowElement.parentElement.childElementCount - 3 !== 0) { headElement.classList.add("av__row--select"); headUseElement.setAttribute("xlink:href", "#iconCheck"); } else if (diffCount === rowElement.parentElement.childElementCount - 3) { headElement.classList.remove("av__row--select"); headUseElement.setAttribute("xlink:href", "#iconUncheck"); counterElement.classList.add("fn__none"); avHeadElement.style.position = ""; return; } else if (diffCount > 0) { headElement.classList.add("av__row--select"); headUseElement.setAttribute("xlink:href", "#iconIndeterminateCheck"); } counterElement.classList.remove("fn__none"); counterElement.innerHTML = `${selectCount} selected`; avHeadElement.style.position = "sticky"; }; export const addAttrViewColAnimation = (options: { blockElement: Element, protyle: IProtyle, type: TAVCol, name: string, previousId?: string, id: string, icon?: string }) => { if (!options.blockElement) { return; } options.blockElement.querySelectorAll(".av__row").forEach((item, index) => { let previousElement; if (options.previousId) { previousElement = item.querySelector(`[data-col-id="${options.previousId}"]`); } else { previousElement = item.lastElementChild.previousElementSibling; } let html = ""; if (index === 0) { html = `