mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-03-07 13:20:16 +01:00
176 lines
8.5 KiB
TypeScript
176 lines
8.5 KiB
TypeScript
import {fetchPost} from "../../../util/fetch";
|
|
import {getColIconByType} from "./col";
|
|
import {escapeAttr} from "../../../util/escape";
|
|
import {hasClosestByAttribute} from "../../util/hasClosest";
|
|
import * as dayjs from "dayjs";
|
|
import {popTextCell} from "./cell";
|
|
|
|
export const genAVValueHTML = (value: IAVCellValue) => {
|
|
let html = "";
|
|
switch (value.type) {
|
|
case "block":
|
|
html = `<div class="fn__flex-1">${value.block.content}</div>`;
|
|
break;
|
|
case "text":
|
|
html = `<textarea rows="${value.text.content.split("\n").length}" class="b3-text-field b3-text-field--text fn__flex-1">${value.text.content}</textarea>`;
|
|
break;
|
|
case "number":
|
|
html = `<input value="${value.number.content}" type="number" class="b3-text-field b3-text-field--text fn__flex-1">`;
|
|
break;
|
|
case "mSelect":
|
|
case "select":
|
|
value.mSelect?.forEach(item => {
|
|
html += `<span class="b3-chip b3-chip--middle" style="background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">${item.content}</span>`;
|
|
});
|
|
break;
|
|
case "mAsset":
|
|
value.mAsset?.forEach(item => {
|
|
if (item.type === "image") {
|
|
html += `<img class="av__cellassetimg" src="${item.content}">`;
|
|
} else {
|
|
html += `<span class="b3-chip b3-chip--middle av__celltext--url" data-url="${item.content}">${item.name}</span>`;
|
|
}
|
|
});
|
|
break;
|
|
case "date":
|
|
if (value[value.type].isNotEmpty) {
|
|
html = `<span data-content="${value[value.type].content}">${dayjs(value[value.type].content).format(value[value.type].isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}</span>`;
|
|
}
|
|
if (value[value.type].hasEndDate && value[value.type].isNotEmpty2 && value[value.type].isNotEmpty) {
|
|
html += `<svg class="custom-attr__avarrow"><use xlink:href="#iconForward"></use></svg><span data-content="${value[value.type].content2}">${dayjs(value[value.type].content2).format(value[value.type].isNotTime ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm")}</span>`;
|
|
}
|
|
break;
|
|
case "created":
|
|
case "updated":
|
|
if (value[value.type].isNotEmpty) {
|
|
html = `<span data-content="${value[value.type].content}">${dayjs(value[value.type].content).format("YYYY-MM-DD HH:mm")}</span>`;
|
|
}
|
|
break;
|
|
case "url":
|
|
html = `<input value="${value.url.content}" class="b3-text-field b3-text-field--text fn__flex-1">
|
|
<span class="fn__space"></span>
|
|
<a href="${value.url.content}" target="_blank" aria-label="${window.siyuan.languages.openBy}" class="block__icon block__icon--show fn__flex-center b3-tooltips__w b3-tooltips"><svg><use xlink:href="#iconLink"></use></svg></a>`;
|
|
break;
|
|
case "phone":
|
|
html = `<input value="${value.phone.content}" class="b3-text-field b3-text-field--text fn__flex-1">
|
|
<span class="fn__space"></span>
|
|
<a href="tel:${value.phone.content}" target="_blank" aria-label="${window.siyuan.languages.openBy}" class="block__icon block__icon--show fn__flex-center b3-tooltips__w b3-tooltips"><svg><use xlink:href="#iconPhone"></use></svg></a>`;
|
|
break;
|
|
case "checkbox":
|
|
html = `<svg class="av__checkbox" style="height: 17px;"><use xlink:href="#icon${value.checkbox.checked?"Check":"Uncheck"}"></use></svg>`;
|
|
break;
|
|
case "template":
|
|
html = `<div class="fn__flex-1">${value.template.content}</div>`;
|
|
break;
|
|
case "email":
|
|
html = `<input value="${value.email.content}" class="b3-text-field b3-text-field--text fn__flex-1">
|
|
<span class="fn__space"></span>
|
|
<a href="mailto:${value.email.content}" target="_blank" aria-label="${window.siyuan.languages.openBy}" class="block__icon block__icon--show fn__flex-center b3-tooltips__w b3-tooltips"><svg><use xlink:href="#iconEmail"></use></svg></a>`;
|
|
break;
|
|
}
|
|
return html;
|
|
};
|
|
|
|
export const renderAVAttribute = (element: HTMLElement, id: string, protyle?: IProtyle) => {
|
|
fetchPost("/api/av/getAttributeViewKeys", {id}, (response) => {
|
|
let html = "";
|
|
response.data.forEach((table: {
|
|
keyValues: {
|
|
key: {
|
|
type: TAVCol,
|
|
name: string,
|
|
options?: {
|
|
name: string,
|
|
color: string
|
|
}[]
|
|
},
|
|
values: {
|
|
keyID: string,
|
|
id: string,
|
|
blockID: string,
|
|
type: TAVCol & IAVCellValue
|
|
} []
|
|
}[],
|
|
blockIDs: string[],
|
|
avID: string
|
|
avName: string
|
|
}) => {
|
|
html += `<div data-av-id="${table.avID}" data-node-id="${id}" data-type="NodeAttributeView">
|
|
<div class="block__logo custom-attr__avheader popover__block" data-id='${JSON.stringify(table.blockIDs)}'>
|
|
<svg><use xlink:href="#iconDatabase"></use></svg>
|
|
<span>${table.avName || window.siyuan.languages.database}</span>
|
|
</div>`;
|
|
table.keyValues?.forEach(item => {
|
|
html += `<div class="block__icons av__row" data-id="${id}">
|
|
<div class="block__logo">
|
|
<svg><use xlink:href="#${getColIconByType(item.key.type)}"></use></svg>
|
|
<span>${item.key.name}</span>
|
|
</div>
|
|
<div data-av-id="${table.avID}" data-col-id="${item.values[0].keyID}" data-block-id="${item.values[0].blockID}" data-id="${item.values[0].id}" data-type="${item.values[0].type}"
|
|
data-options="${item.key?.options ? escapeAttr(JSON.stringify(item.key.options)) : "[]"}"
|
|
class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes(item.values[0].type) ? "" : " custom-attr__avvalue"}">
|
|
${genAVValueHTML(item.values[0])}
|
|
</div>
|
|
</div>`;
|
|
});
|
|
html += "</div>";
|
|
});
|
|
element.innerHTML = html;
|
|
element.addEventListener("click", (event) => {
|
|
const target = event.target as HTMLElement;
|
|
const dateElement = hasClosestByAttribute(target, "data-type", "date");
|
|
if (dateElement) {
|
|
popTextCell(protyle, [dateElement], "date");
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
const mSelectElement = hasClosestByAttribute(target, "data-type", "select") || hasClosestByAttribute(target, "data-type", "mSelect");
|
|
if (mSelectElement) {
|
|
popTextCell(protyle, [mSelectElement], mSelectElement.getAttribute("data-type") as TAVCol);
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
const mAssetElement = hasClosestByAttribute(target, "data-type", "mAsset");
|
|
if (mAssetElement) {
|
|
popTextCell(protyle, [mAssetElement], "mAsset");
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
const checkboxElement = hasClosestByAttribute(target, "data-type", "checkbox");
|
|
if (checkboxElement) {
|
|
popTextCell(protyle, [checkboxElement], "checkbox");
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
});
|
|
element.querySelectorAll(".b3-text-field--text").forEach((item: HTMLInputElement) => {
|
|
item.addEventListener("change", () => {
|
|
let value;
|
|
if (["url", "text", "email", "phone"].includes(item.parentElement.dataset.type)) {
|
|
value = {
|
|
[item.parentElement.dataset.type]: {
|
|
content: item.value
|
|
}
|
|
};
|
|
} else if (item.parentElement.dataset.type === "number") {
|
|
value = {
|
|
number: {
|
|
content: parseFloat(item.value)
|
|
}
|
|
};
|
|
}
|
|
fetchPost("/api/av/setAttributeViewBlockAttr", {
|
|
avID: item.parentElement.dataset.avId,
|
|
keyID: item.parentElement.dataset.colId,
|
|
rowID: item.parentElement.dataset.blockId,
|
|
cellID: item.parentElement.dataset.id,
|
|
value
|
|
});
|
|
});
|
|
});
|
|
});
|
|
};
|