2023-12-23 20:25:58 +08:00
|
|
|
import {Menu} from "../../../plugin/Menu";
|
2023-12-23 23:50:04 +08:00
|
|
|
import {hasClosestByClassName} from "../../util/hasClosest";
|
2023-12-23 20:25:58 +08:00
|
|
|
import {upDownHint} from "../../../util/upDownHint";
|
|
|
|
|
import {fetchPost} from "../../../util/fetch";
|
2023-12-23 23:50:04 +08:00
|
|
|
import {escapeHtml} from "../../../util/escape";
|
|
|
|
|
import {transaction} from "../../wysiwyg/transaction";
|
2023-12-23 20:25:58 +08:00
|
|
|
|
2023-12-23 23:50:04 +08:00
|
|
|
const genSearchList = (element: Element, keyword: string, avId: string, cb?: () => void) => {
|
2023-12-23 20:25:58 +08:00
|
|
|
fetchPost("/api/av/searchAttributeView", {keyword}, (response) => {
|
2023-12-23 23:50:04 +08:00
|
|
|
let html = "";
|
|
|
|
|
response.data.results.forEach((item: {
|
|
|
|
|
avID: string
|
|
|
|
|
avName: string
|
|
|
|
|
blockID: string
|
|
|
|
|
hPath: string
|
|
|
|
|
}, index: number) => {
|
|
|
|
|
html += `<div class="b3-list-item b3-list-item--narrow${index === 0 ? " b3-list-item--focus" : ""}" data-av-id="${item.avID}" data-block-id="${item.blockID}">
|
|
|
|
|
<div class="b3-list-item--two fn__flex-1">
|
|
|
|
|
<div class="b3-list-item__first">
|
|
|
|
|
<span class="b3-list-item__text">${escapeHtml(item.avName || window.siyuan.languages.title)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="b3-list-item__meta b3-list-item__showall">${escapeHtml(item.hPath)}</div>
|
|
|
|
|
</div>
|
|
|
|
|
<svg aria-label="${window.siyuan.languages.thisDatabase}" style="margin: 0 0 0 4px" class="b3-list-item__hinticon ariaLabel${item.avID === avId ? "" : " fn__none"}"><use xlink:href="#iconInfo"></use></svg>
|
|
|
|
|
</div>`
|
2023-12-23 20:25:58 +08:00
|
|
|
});
|
2023-12-23 23:50:04 +08:00
|
|
|
element.innerHTML = html;
|
|
|
|
|
if (cb) {
|
|
|
|
|
cb()
|
|
|
|
|
}
|
2023-12-23 20:25:58 +08:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-24 12:17:05 +08:00
|
|
|
const setDatabase = (avId: string, element: HTMLElement, item: HTMLElement) => {
|
2023-12-23 23:50:04 +08:00
|
|
|
element.dataset.avId = item.dataset.avId;
|
|
|
|
|
element.dataset.blockId = item.dataset.blockId;
|
|
|
|
|
element.querySelector(".b3-menu__accelerator").textContent = item.querySelector(".b3-list-item__hinticon").classList.contains("fn__none") ? item.querySelector(".b3-list-item__text").textContent : window.siyuan.languages.thisDatabase
|
2023-12-24 12:17:05 +08:00
|
|
|
const menuElement = hasClosestByClassName(element, "b3-menu__items")
|
|
|
|
|
if (menuElement) {
|
|
|
|
|
toggleUpdateRelationBtn(menuElement, avId);
|
|
|
|
|
}
|
2023-12-23 23:50:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const openSearchAV = (avId: string, target: HTMLElement) => {
|
2023-12-23 20:25:58 +08:00
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
const menu = new Menu();
|
|
|
|
|
menu.addItem({
|
|
|
|
|
iconHTML: "",
|
2023-12-23 23:50:04 +08:00
|
|
|
type: "empty",
|
2023-12-23 20:25:58 +08:00
|
|
|
label: `<div class="fn__flex-column" style = "min-width: 260px;max-width:420px;max-height: 50vh">
|
2023-12-23 23:50:04 +08:00
|
|
|
<input class="b3-text-field fn__flex-shrink"/>
|
|
|
|
|
<div class="fn__hr"></div>
|
|
|
|
|
<div class="b3-list fn__flex-1 b3-list--background">
|
2023-12-23 20:25:58 +08:00
|
|
|
<img style="margin: 0 auto;display: block;width: 64px;height: 64px" src="/stage/loading-pure.svg">
|
|
|
|
|
</div>
|
|
|
|
|
</div>`,
|
|
|
|
|
bind(element) {
|
|
|
|
|
const listElement = element.querySelector(".b3-list");
|
|
|
|
|
const inputElement = element.querySelector("input");
|
|
|
|
|
inputElement.addEventListener("keydown", (event: KeyboardEvent) => {
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-12-23 23:50:04 +08:00
|
|
|
const currentElement = upDownHint(listElement, event);
|
|
|
|
|
if (currentElement) {
|
|
|
|
|
event.stopPropagation();
|
2023-12-23 20:25:58 +08:00
|
|
|
}
|
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
event.stopPropagation();
|
2023-12-24 12:17:05 +08:00
|
|
|
setDatabase(avId, target, listElement.querySelector(".b3-list-item--focus"));
|
2023-12-23 23:50:04 +08:00
|
|
|
window.siyuan.menus.menu.remove();
|
2023-12-23 20:25:58 +08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
inputElement.addEventListener("input", (event) => {
|
|
|
|
|
event.stopPropagation();
|
2023-12-23 23:50:04 +08:00
|
|
|
genSearchList(listElement, inputElement.value, avId);
|
2023-12-23 20:25:58 +08:00
|
|
|
});
|
|
|
|
|
element.lastElementChild.addEventListener("click", (event) => {
|
2023-12-23 23:50:04 +08:00
|
|
|
const listItemElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item");
|
2023-12-23 20:25:58 +08:00
|
|
|
if (listItemElement) {
|
|
|
|
|
event.stopPropagation();
|
2023-12-24 12:17:05 +08:00
|
|
|
setDatabase(avId, target, listItemElement)
|
2023-12-23 20:25:58 +08:00
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-12-23 23:50:04 +08:00
|
|
|
genSearchList(listElement, "", avId, () => {
|
|
|
|
|
const rect = target.getBoundingClientRect();
|
|
|
|
|
menu.open({
|
|
|
|
|
x: rect.left,
|
|
|
|
|
y: rect.bottom,
|
|
|
|
|
h: rect.height,
|
|
|
|
|
})
|
|
|
|
|
element.querySelector("input").focus();
|
|
|
|
|
});
|
2023-12-23 20:25:58 +08:00
|
|
|
}
|
|
|
|
|
});
|
2023-12-23 23:50:04 +08:00
|
|
|
menu.element.querySelector(".b3-menu__items").setAttribute("style", "overflow: initial");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const updateRelation = (options: {
|
|
|
|
|
protyle: IProtyle,
|
|
|
|
|
avID: string,
|
|
|
|
|
avElement: Element
|
|
|
|
|
}) => {
|
|
|
|
|
transaction(options.protyle, [{
|
|
|
|
|
action: "updateAttrViewColRelation",
|
|
|
|
|
avID: options.avID,
|
|
|
|
|
id: options.avElement.querySelector('.b3-menu__item[data-type="goSearchAV"]').getAttribute("data-av-id"),
|
|
|
|
|
keyID: options.avElement.querySelector(".b3-menu__item").getAttribute("data-col-id"), // 源 av 关联列 ID
|
|
|
|
|
backRelationKeyID: Lute.NewNodeID(), // 双向关联的目标关联列 ID
|
|
|
|
|
isTwoWay: (options.avElement.querySelector(".b3-switch") as HTMLInputElement).checked,
|
|
|
|
|
name: (options.avElement.querySelector('input[data-type="colName"]') as HTMLInputElement).value,
|
|
|
|
|
}], []);
|
|
|
|
|
options.avElement.remove();
|
2023-12-23 20:25:58 +08:00
|
|
|
}
|
2023-12-24 11:11:07 +08:00
|
|
|
|
2023-12-24 12:17:05 +08:00
|
|
|
export const toggleUpdateRelationBtn = (menuItemsElement: HTMLElement, avId: string) => {
|
|
|
|
|
const searchElement = menuItemsElement.querySelector('.b3-menu__item[data-type="goSearchAV"]') as HTMLElement
|
|
|
|
|
const switchItemElement = searchElement.nextElementSibling;
|
|
|
|
|
const switchElement = switchItemElement.querySelector(".b3-switch") as HTMLInputElement;
|
2023-12-24 13:21:07 +08:00
|
|
|
const inputItemElement = switchItemElement.nextElementSibling;
|
|
|
|
|
const btnElement = inputItemElement.nextElementSibling;
|
2023-12-24 12:17:05 +08:00
|
|
|
const oldValue = JSON.parse(searchElement.dataset.oldValue);
|
|
|
|
|
if (oldValue.avID) {
|
|
|
|
|
if (searchElement.dataset.avId !== avId) {
|
|
|
|
|
switchItemElement.classList.remove("fn__none");
|
|
|
|
|
if (switchElement.checked) {
|
2023-12-24 13:21:07 +08:00
|
|
|
inputItemElement.classList.remove("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
} else {
|
2023-12-24 13:21:07 +08:00
|
|
|
inputItemElement.classList.add("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switchItemElement.classList.add("fn__none");
|
2023-12-24 13:21:07 +08:00
|
|
|
inputItemElement.classList.add("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
}
|
2023-12-24 13:21:07 +08:00
|
|
|
const inputElement = inputItemElement.querySelector("input") as HTMLInputElement;
|
|
|
|
|
if ((searchElement.dataset.avId && oldValue.avID !== searchElement.dataset.avId)|| oldValue.isTwoWay !== switchElement.checked || inputElement.dataset.oldValue !== inputElement.value) {
|
2023-12-24 12:17:05 +08:00
|
|
|
btnElement.classList.remove("fn__none");
|
2023-12-24 13:21:07 +08:00
|
|
|
} else {
|
|
|
|
|
btnElement.classList.add("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
}
|
|
|
|
|
} else if (searchElement.dataset.avId) {
|
|
|
|
|
switchItemElement.classList.remove("fn__none");
|
|
|
|
|
if (switchElement.checked) {
|
2023-12-24 13:21:07 +08:00
|
|
|
inputItemElement.classList.remove("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
} else {
|
2023-12-24 13:21:07 +08:00
|
|
|
inputItemElement.classList.add("fn__none");
|
2023-12-24 12:17:05 +08:00
|
|
|
}
|
|
|
|
|
btnElement.classList.remove("fn__none");
|
|
|
|
|
}
|
2023-12-24 11:11:07 +08:00
|
|
|
}
|