mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 17:40:13 +01:00
This commit is contained in:
parent
142eecf17e
commit
f131872820
21 changed files with 161 additions and 23 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"hide": "隱藏",
|
||||
"wrap": "換行",
|
||||
"edit": "編輯",
|
||||
"incompatiblePluginTip": "該插件不支持在當前終端上使用",
|
||||
"incompatible": "不兼容",
|
||||
"trust": "信任",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"hide": "隐藏",
|
||||
"wrap": "换行",
|
||||
"edit": "编辑",
|
||||
"incompatiblePluginTip": "该插件不支持在当前终端上使用",
|
||||
"incompatible": "不兼容",
|
||||
"trust": "信任",
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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[] = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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[] = [{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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[] = [];
|
||||
|
|
|
|||
|
|
@ -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 = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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[],
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
// 移动到其他文档中,该块需移除
|
||||
|
|
|
|||
6
app/src/types/index.d.ts
vendored
6
app/src/types/index.d.ts
vendored
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue