Vanessa 2023-06-08 22:55:31 +08:00
parent 142eecf17e
commit f131872820
21 changed files with 161 additions and 23 deletions

View file

@ -1,4 +1,7 @@
{
"hide": "Hide",
"wrap": "Wrap column",
"edit": "Edit",
"incompatiblePluginTip": "This plugin is not supported on the current terminal",
"incompatible": "Incompatible",
"trust": "Trust",

View file

@ -1,4 +1,7 @@
{
"hide": "Ocultar",
"wrap": "Columna de ajuste",
"edit": "Editar",
"incompatiblePluginTip": "Este complemento no es compatible con el terminal actual",
"incompatible": "Incompatible",
"trust": "Confiar",

View file

@ -1,4 +1,7 @@
{
"hide": "Masquer",
"wrap": "Reboucler la colonne",
"edit": "Modifier",
"incompatiblePluginTip": "Ce plugin n'est pas supporté sur le terminal actuel",
"incompatible": "Incompatible",
"trust": "Confiance",

View file

@ -1,4 +1,7 @@
{
"hide": "隱藏",
"wrap": "換行",
"edit": "編輯",
"incompatiblePluginTip": "該插件不支持在當前終端上使用",
"incompatible": "不兼容",
"trust": "信任",

View file

@ -1,4 +1,7 @@
{
"hide": "隐藏",
"wrap": "换行",
"edit": "编辑",
"incompatiblePluginTip": "该插件不支持在当前终端上使用",
"incompatible": "不兼容",
"trust": "信任",

View file

@ -42,6 +42,23 @@
&__row {
display: flex;
border-bottom: 1px solid var(--b3-theme-surface-lighter);
&--header .av__cell {
display: flex;
align-items: center;
svg {
height: 14px;
width: 14px;
color: var(--b3-theme-on-surface);
margin-right: 5px;
}
}
&--header,
&--footer {
background-color: var(--b3-theme-background);
}
}
&__cell {

View file

@ -11,7 +11,7 @@ import {setStorageVal} from "../../protyle/util/compatibility";
import {closePanel} from "./closePanel";
import {showMessage} from "../../dialog/message";
import {getCurrentEditor} from "../editor";
import {avRender} from "../../protyle/render/av";
import {avRender} from "../../protyle/render/av/render";
const forwardStack: IBackStack[] = [];

View file

@ -40,7 +40,7 @@ import {activeBlur} from "../../mobile/util/keyboardToolbar";
import {hideTooltip} from "../../dialog/tooltip";
import {appearanceMenu} from "../toolbar/Font";
import {setPosition} from "../../util/setPosition";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export class Gutter {
public element: HTMLElement;

View file

@ -19,7 +19,7 @@ import {zoomOut} from "../../menus/protyle";
import {hideElements} from "../ui/hideElements";
import {genAssetHTML} from "../../asset/renderAssets";
import {unicode2Emoji} from "../../emoji";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export const hintSlash = (key: string, protyle: IProtyle) => {
const allList: IHintData[] = [{

View file

@ -32,7 +32,7 @@ import {processRender} from "../util/processCode";
import {AIChat} from "../../ai/chat";
import {isMobile} from "../../util/functions";
import {isCtrl} from "../util/compatibility";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export class Hint {
public timeId: number;

View file

@ -7,7 +7,7 @@ import { chartRender } from "./render/chartRender";
import { abcRender } from "./render/abcRender";
import { mindmapRender } from "./render/mindmapRender";
import { plantumlRender } from "./render/plantumlRender";
import { avRender } from "./render/av";
import { avRender } from "./render/av/render";
import "../assets/scss/export.scss";
class Protyle {

View file

@ -17,7 +17,7 @@ import {fetchPost} from "../../util/fetch";
import {processRender} from "../util/processCode";
import {highlightRender} from "../render/highlightRender";
import {speechRender} from "../render/speechRender";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export class Preview {
public element: HTMLElement;

View file

@ -1,6 +1,7 @@
import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../../util/hasClosest";
import {transaction} from "../../wysiwyg/transaction";
import {Menu} from "../../../plugin/API";
import {getIconByType} from "./render";
export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => {
const blockElement = hasClosestBlock(event.target)
@ -23,13 +24,13 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
id,
parentID: blockElement.getAttribute("data-av-type"),
}]);
}
})
const addRect = addElement.getBoundingClientRect()
menu.open({
x: addRect.left,
y: addRect.bottom
y: addRect.bottom,
h: addRect.height
})
event.preventDefault();
event.stopPropagation();
@ -37,6 +38,84 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
}
const cellElement = hasClosestByClassName(event.target, "av__cell")
if (cellElement && blockElement) {
const type = cellElement.getAttribute("data-dtype")
const menu = new Menu("av-header-cell")
menu.addItem({
icon: getIconByType(type),
label: `<input style="margin: 4px 0" class="b3-text-field" type="text" value="${cellElement.innerText.trim()}">`,
bind() {
}
})
if (type !== "block") {
menu.addItem({
icon: "iconEdit",
label: window.siyuan.languages.edit,
click() {
}
})
}
menu.addSeparator()
menu.addItem({
icon: "iconUp",
label: window.siyuan.languages.fileNameNatASC,
click() {
}
})
menu.addItem({
icon: "iconDown",
label: window.siyuan.languages.fileNameNatDESC,
click() {
}
})
menu.addItem({
icon: "iconFilter",
label: window.siyuan.languages.filter,
click() {
}
})
menu.addSeparator()
if (type !== "block") {
menu.addItem({
icon: "iconEyeoff",
label: window.siyuan.languages.hide,
click() {
}
})
menu.addItem({
icon: "iconCopy",
label: window.siyuan.languages.duplicate,
click() {
}
})
menu.addItem({
icon: "iconTrashcan",
label: window.siyuan.languages.delete,
click() {
}
})
menu.addSeparator()
}
menu.addItem({
label: `<div class="fn__flex" style="margin-bottom: 4px"><span>${window.siyuan.languages.wrap}</span><span class="fn__space fn__flex-1"></span>
<input type="checkbox" class="b3-switch fn__flex-center"${cellElement.getAttribute("data-wrap") === "true" ? " checked" : ""}></div>`,
click() {
}
})
const cellRect = cellElement.getBoundingClientRect()
menu.open({
x: cellRect.left,
y: cellRect.bottom,
h: cellRect.height
})
event.preventDefault();
event.stopPropagation();
return true

View file

@ -1,5 +1,14 @@
import {fetchPost} from "../../../util/fetch";
export const getIconByType = (type: string) => {
switch (type) {
case "text":
return "iconAlignLeft";
case "block":
return "iconParagraph";
}
}
export const avRender = (element: Element) => {
let avElements: Element[] = [];
if (element.getAttribute("data-type") === "NodeAttributeView") {
@ -12,18 +21,23 @@ export const avRender = (element: Element) => {
return;
}
if (avElements.length > 0) {
avElements.forEach((e: HTMLDivElement) => {
avElements.forEach((e: HTMLElement) => {
if (e.getAttribute("data-render") === "true") {
return;
}
fetchPost("/api/av/renderAttributeView", {id: e.getAttribute("data-av-id")}, (response) => {
const data = response.data.av;
this.data = data;
// header
let tableHTML = '<div class="av__row av__row--header" style="background-color: var(--b3-theme-background)"><div class="av__firstcol"><input style="margin-top: 14px" type="checkbox"></div>';
let tableHTML = '<div class="av__row av__row--header"><div class="av__firstcol"><input style="margin-top: 14px" type="checkbox"></div>';
data.columns.forEach((column: IAVColumn) => {
tableHTML += `
<div class="av__cell" style="width: ${column.width || 200}px;">${column.name}</div>`
if (column.hidden) {
return;
}
tableHTML += `<div class="av__cell" data-id="${column.id}" data-dtype="${column.type}" data-wrap="${column.wrap}" style="width: ${column.width || 200}px;">
<svg><use xlink:href="#${column.icon || getIconByType(column.type)}"></use></svg>
<span>${column.name}</span>
</div>`
});
tableHTML += `<div class="block__icons">
<div class="block__icon block__icon--show" data-type="av-header-add"><svg><use xlink:href="#iconAdd"></use></svg></div>
@ -55,18 +69,19 @@ export const avRender = (element: Element) => {
</div>
</div>
<div class="av__scroll">
<div style="padding-left: ${paddingLeft};padding-right: ${paddingRight};min-width: 100%;float: left;">
<div style="padding-left: ${paddingLeft};padding-right: ${paddingRight};float: left;">
${tableHTML}
<div class="block__icon block__icon--show">
<div class="fn__space"></div>
<svg><use xlink:href="#iconAdd"></use></svg><span class="fn__space"></span>
${window.siyuan.languages.addAttr}
</div>
<div class="av__row--footer">Calculate</div>
</div>
</div>
</div>`;
e.setAttribute("data-render", "true");
})
});
});
}
};

View file

@ -4,7 +4,7 @@ import {processRender} from "../util/processCode";
import {highlightRender} from "./highlightRender";
import {Constants} from "../../constants";
import {genBreadcrumb} from "../wysiwyg/renderBacklink";
import {avRender} from "./av";
import {avRender} from "./av/render";
export const blockRender = (protyle: IProtyle, element: Element, top?: number) => {
let blockElements: Element[] = [];

View file

@ -26,7 +26,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
protyle.wysiwyg.element.querySelectorAll(".av").forEach((item: HTMLElement) => {
if (item.parentElement.classList.contains("protyle-wysiwyg")) {
const headerTop = item.offsetTop - 30 + 56
const headerTop = item.offsetTop - 30 + 56; // 30 - 面包屑, 56 - tab+title
const headerElement = item.querySelector(".av__row--header") as HTMLElement
if (headerElement) {
if (headerTop < element.scrollTop && headerTop + headerElement.parentElement.clientHeight > element.scrollTop) {
@ -35,6 +35,16 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
headerElement.style.transform = "";
}
}
const footerElement = item.querySelector(".av__row--footer") as HTMLElement
if (footerElement) {
const footerBottom = headerTop + footerElement.parentElement.clientHeight
const scrollBottom = element.scrollTop + element.clientHeight;
if (headerTop + 42 + 36 * 2 < scrollBottom && footerBottom > scrollBottom) {
footerElement.style.transform = `translateY(${scrollBottom - footerBottom}px)`;
} else {
footerElement.style.transform = "";
}
}
}
});

View file

@ -16,7 +16,7 @@ import {removeLoading} from "../ui/initUI";
import {isMobile} from "../../util/functions";
import {foldPassiveType} from "../wysiwyg/renderBacklink";
import {showMessage} from "../../dialog/message";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export const onGet = (options: {
data: IWebSocketData,

View file

@ -14,7 +14,7 @@ import {isDynamicRef, isFileAnnotation} from "../../util/functions";
import {insertHTML} from "./insertHTML";
import {scrollCenter} from "../../util/highlightById";
import {hideElements} from "../ui/hideElements";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
const filterClipboardHint = (protyle: IProtyle, textPlain: string) => {
let needRender = true;

View file

@ -6,7 +6,7 @@ import {processRender} from "../util/processCode";
import {highlightRender} from "../render/highlightRender";
import {blockRender} from "../render/blockRender";
import {disabledForeverProtyle, disabledProtyle} from "../util/onGet";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
export const renderBacklink = (protyle: IProtyle, backlinkData: {
blockPaths: IBreadcrumb[],

View file

@ -17,7 +17,7 @@ import {hideElements} from "../ui/hideElements";
import {reloadProtyle} from "../util/reload";
import {countBlockWord} from "../../layout/status";
import {needSubscribe} from "../../util/needSubscribe";
import {avRender} from "../render/av";
import {avRender} from "../render/av/render";
const removeTopElement = (updateElement: Element, protyle: IProtyle) => {
// 移动到其他文档中,该块需移除

View file

@ -26,6 +26,7 @@ type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins"
type TCardType = "doc" | "notebook" | "all"
type TEventBus = "ws-main" | "click-blockicon" | "click-editorcontent" | "click-pdf" |
"click-editortitleicon" | "open-noneditableblock" | "loaded-protyle"
type TAVCol = "text" | "date" | "number" | "relation" | "rollup" | "select" | "block"
declare module "blueimp-md5"
@ -282,7 +283,7 @@ interface IOperation {
nextID?: string // insert 专享
srcIDs?: string[] // insertAttrViewBlock 专享
name?: string // addAttrViewCol 专享
type?: "text" | "date" | "number" | "relation" | "rollup" | "select" // addAttrViewCol 专享
type?: TAVCol // addAttrViewCol 专享
deckID?: string // add/removeFlashcards 专享
blockIDs?: string[] // add/removeFlashcards 专享
}
@ -810,7 +811,8 @@ interface IAVColumn {
id: string,
name: string,
wrap: boolean,
type: string,
hidden: boolean,
type: TAVCol,
}
interface IAVRow {