diff --git a/app/src/protyle/render/av/filter.ts b/app/src/protyle/render/av/filter.ts index fc5b79e1e..c4036996f 100644 --- a/app/src/protyle/render/av/filter.ts +++ b/app/src/protyle/render/av/filter.ts @@ -8,7 +8,7 @@ import {genCellValue} from "./cell"; import * as dayjs from "dayjs"; import {unicode2Emoji} from "../../../emoji"; import {openMenuPanel} from "./openMenuPanel"; -import {fetchSyncPost} from "../../../util/fetch"; +import {fetchPost, fetchSyncPost} from "../../../util/fetch"; import {showMessage} from "../../../dialog/message"; import {upDownHint} from "../../../util/upDownHint"; import {getFieldsByData} from "./view"; @@ -427,12 +427,10 @@ export const setFilter = async (options: { } }); }); - } else if (["text", "url", "block", "mAsset", "email", "phone", "template", "relation"].includes(filterValue.type)) { + } else if (["text", "url", "block", "mAsset", "email", "phone", "template"].includes(filterValue.type)) { let value = ""; if (filterValue) { - if (filterValue.type === "relation") { - value = filterValue.relation.blockIDs[0] || ""; - } else if (filterValue.type === "mAsset") { + if (filterValue.type === "mAsset") { value = filterValue.mAsset[0]?.content || ""; } else { value = filterValue[filterValue.type as "text"].content || ""; @@ -443,6 +441,65 @@ export const setFilter = async (options: { type: "readonly", label: `` }); + } else if (filterValue.type === "relation") { + let value = ""; + if (filterValue) { + value = filterValue.relation.blockIDs[0] || ""; + } + menu.addItem({ + iconHTML: "", + type: "readonly", + label: `
`, + bind(element) { + const inputElement = element.querySelector("input"); + const listElement = inputElement.nextElementSibling; + const renderList = () => { + fetchPost("/api/av/getAttributeViewPrimaryKeyValues", { + id: options.data.id, + keyword: inputElement.value, + }, response => { + let html = ""; + (response.data.rows.values as IAVCellValue[] || []).forEach((item, index) => { + html += `
${item.block.content}
`; + }); + listElement.innerHTML = html; + if (html === "") { + listElement.classList.add("fn__none"); + } else { + listElement.classList.remove("fn__none"); + } + }); + }; + inputElement.addEventListener("input", (event: KeyboardEvent) => { + if (event.isComposing) { + return; + } + renderList(); + }); + inputElement.addEventListener("compositionend", () => { + renderList(); + }); + inputElement.addEventListener("keydown", (event) => { + if (event.isComposing) { + return; + } + if (event.key !== "Enter" && listElement.innerHTML !== "") { + listElement.classList.remove("fn__none"); + } + upDownHint(listElement, event); + if (event.key === "Enter") { + if (listElement.classList.contains("fn__none")) { + menu.close(); + } else { + inputElement.value = listElement.querySelector(".b3-list-item--focus").textContent.replace(/\n/g, " "); + listElement.classList.add("fn__none"); + } + event.preventDefault(); + event.stopPropagation(); + } + }); + } + }); } else if (filterValue.type === "number") { menu.addItem({ iconHTML: "", @@ -575,7 +632,7 @@ export const setFilter = async (options: { }); const textElements: NodeListOf = menu.element.querySelectorAll(".b3-text-field"); - if (filterValue.type !== "select" && filterValue.type !== "mSelect") { + if (!["relation", "select", "mSelect"].includes(filterValue.type)) { textElements.forEach(item => { item.addEventListener("keydown", (event: KeyboardEvent) => { if (event.isComposing) { @@ -591,6 +648,10 @@ export const setFilter = async (options: { } toggleEmpty(operationElement, operationElement.value, filterValue.type); menu.open({x: rectTarget.left, y: rectTarget.bottom}); + if (filterValue.type === "relation") { + const inputRect = textElements[0].getBoundingClientRect(); + textElements[0].nextElementSibling.setAttribute("style", `position:fixed;top:${inputRect.bottom}px;left:${inputRect.left}px`); + } if (textElements.length > 0) { textElements[0].select(); }