mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-21 17:10:12 +01:00
This commit is contained in:
parent
c83d138c60
commit
d076941a87
5 changed files with 111 additions and 15 deletions
|
|
@ -2,6 +2,7 @@ import {transaction} from "../../wysiwyg/transaction";
|
||||||
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
|
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
|
||||||
import {Menu} from "../../../plugin/Menu";
|
import {Menu} from "../../../plugin/Menu";
|
||||||
import {getColIconByType} from "./col";
|
import {getColIconByType} from "./col";
|
||||||
|
import {fetchPost} from "../../../util/fetch";
|
||||||
|
|
||||||
export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
||||||
const type = cellElement.parentElement.parentElement.firstElementChild.children[parseInt(cellElement.getAttribute("data-index")) + 1].getAttribute("data-dtype") as TAVCol;
|
const type = cellElement.parentElement.parentElement.firstElementChild.children[parseInt(cellElement.getAttribute("data-index")) + 1].getAttribute("data-dtype") as TAVCol;
|
||||||
|
|
@ -39,7 +40,6 @@ export const popTextCell = (protyle: IProtyle, cellElement: HTMLElement) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVCol) => {
|
const updateCellValue = (protyle: IProtyle, cellElement: HTMLElement, type: TAVCol) => {
|
||||||
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
const rowElement = hasClosestByClassName(cellElement, "av__row");
|
||||||
if (!rowElement) {
|
if (!rowElement) {
|
||||||
|
|
@ -128,14 +128,48 @@ export const showHeaderCellMenu = (protyle: IProtyle, blockElement: HTMLElement,
|
||||||
icon: "iconUp",
|
icon: "iconUp",
|
||||||
label: window.siyuan.languages.fileNameNatASC,
|
label: window.siyuan.languages.fileNameNatASC,
|
||||||
click() {
|
click() {
|
||||||
|
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
|
||||||
|
transaction(protyle, [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: [{
|
||||||
|
column: colId,
|
||||||
|
order: "ASC"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: response.data.av.sorts
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
menu.addItem({
|
menu.addItem({
|
||||||
icon: "iconDown",
|
icon: "iconDown",
|
||||||
label: window.siyuan.languages.fileNameNatDESC,
|
label: window.siyuan.languages.fileNameNatDESC,
|
||||||
click() {
|
click() {
|
||||||
|
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
|
||||||
|
transaction(protyle, [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: [{
|
||||||
|
column: colId,
|
||||||
|
order: "DESC"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: response.data.av.sorts
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
menu.addItem({
|
menu.addItem({
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type
|
||||||
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
||||||
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
|
|
||||||
|
bindSortsEvent(protyle, menuElement, data);
|
||||||
avPanelElement.addEventListener("click", (event) => {
|
avPanelElement.addEventListener("click", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let target = event.target as HTMLElement;
|
let target = event.target as HTMLElement;
|
||||||
|
|
@ -40,6 +41,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type
|
||||||
const type = target.dataset.type;
|
const type = target.dataset.type;
|
||||||
if (type === "close") {
|
if (type === "close") {
|
||||||
avPanelElement.remove();
|
avPanelElement.remove();
|
||||||
|
window.siyuan.menus.menu.remove();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
} else if (type === "goConfig") {
|
} else if (type === "goConfig") {
|
||||||
|
|
@ -54,6 +56,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type
|
||||||
break;
|
break;
|
||||||
} else if (type === "goSorts") {
|
} else if (type === "goSorts") {
|
||||||
menuElement.innerHTML = getSortsHTML(data);
|
menuElement.innerHTML = getSortsHTML(data);
|
||||||
|
bindSortsEvent(protyle, menuElement, data);
|
||||||
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
|
|
@ -73,6 +76,7 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type
|
||||||
}]);
|
}]);
|
||||||
data.sorts = [];
|
data.sorts = [];
|
||||||
menuElement.innerHTML = getSortsHTML(data);
|
menuElement.innerHTML = getSortsHTML(data);
|
||||||
|
bindSortsEvent(protyle, menuElement, data);
|
||||||
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
|
|
@ -81,7 +85,29 @@ export const openMenuPanel = (protyle: IProtyle, blockElement: HTMLElement, type
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
} else if (type === "removeSort") {
|
} else if (type === "removeSort") {
|
||||||
// TODO
|
const oldSorts = Object.assign([], data.sorts);
|
||||||
|
data.sorts.find((item: IAVSort, index: number) => {
|
||||||
|
if (item.column === target.parentElement.dataset.id) {
|
||||||
|
data.sorts.splice(index, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
transaction(protyle, [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: data.sorts
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: avId,
|
||||||
|
data: {
|
||||||
|
sorts: oldSorts
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
menuElement.innerHTML = getSortsHTML(data);
|
||||||
|
bindSortsEvent(protyle, menuElement, data);
|
||||||
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
} else if (type === "newCol") {
|
} else if (type === "newCol") {
|
||||||
|
|
@ -224,25 +250,58 @@ const getConfigHTML = (data: IAV) => {
|
||||||
</button>`;
|
</button>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bindSortsEvent = (protyle: IProtyle, menuElement: HTMLElement, data: IAV) => {
|
||||||
|
menuElement.querySelectorAll("select").forEach((item: HTMLSelectElement) => {
|
||||||
|
item.addEventListener("change", (event) => {
|
||||||
|
const colId = item.parentElement.getAttribute("data-id");
|
||||||
|
const oldSort = JSON.parse(JSON.stringify(data.sorts));
|
||||||
|
if (item.previousElementSibling.classList.contains("b3-menu__icon")) {
|
||||||
|
data.sorts.find((sort: IAVSort) => {
|
||||||
|
if (sort.column === colId) {
|
||||||
|
sort.column = item.value
|
||||||
|
item.parentElement.setAttribute("data-id", item.value);
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
data.sorts.find((sort: IAVSort) => sort.column === colId).order = item.value as "ASC" | "DESC";
|
||||||
|
}
|
||||||
|
transaction(protyle, [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: data.id,
|
||||||
|
data: {
|
||||||
|
sorts: data.sorts
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
action: "setAttrView",
|
||||||
|
id: data.id,
|
||||||
|
data: {
|
||||||
|
sorts: oldSort
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const getSortsHTML = (data: IAV) => {
|
const getSortsHTML = (data: IAV) => {
|
||||||
let html = "";
|
let html = "";
|
||||||
const genSortItem = (id: string) => {
|
const genSortItem = (id: string) => {
|
||||||
let sortHTML = ''
|
let sortHTML = ''
|
||||||
data.columns.forEach((item) => {
|
data.columns.forEach((item) => {
|
||||||
sortHTML += `<option value="${item.id}" ${item.id === id ? "checked" : ""}>${item.name}</option>`
|
sortHTML += `<option value="${item.id}" ${item.id === id ? "selected" : ""}>${item.name}</option>`
|
||||||
})
|
})
|
||||||
return sortHTML;
|
return sortHTML;
|
||||||
}
|
}
|
||||||
data.sorts.forEach((item: IAVSort) => {
|
data.sorts.forEach((item: IAVSort) => {
|
||||||
html += `<button class="b3-menu__item">
|
html += `<button class="b3-menu__item" data-id="${item.column}">
|
||||||
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
|
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
|
||||||
<select class="b3-select" style="width: 106px;margin: 4px 0">
|
<select class="b3-select" style="width: 106px;margin: 4px 0">
|
||||||
${genSortItem(item.column)}
|
${genSortItem(item.column)}
|
||||||
</select>
|
</select>
|
||||||
<span class="fn__space"></span>
|
<span class="fn__space"></span>
|
||||||
<select class="b3-select" style="width: 106px;margin: 4px 0">
|
<select class="b3-select" style="width: 106px;margin: 4px 0">
|
||||||
<option value="ASC" ${item.order === "ASC" ? "checked" : ""}>${window.siyuan.languages.fileNameNatASC}</option>
|
<option value="ASC" ${item.order === "ASC" ? "selected" : ""}>${window.siyuan.languages.fileNameNatASC}</option>
|
||||||
<option value="DESC" ${item.order === "DESC" ? "checked" : ""}>${window.siyuan.languages.fileNameNatDESC}</option>
|
<option value="DESC" ${item.order === "DESC" ? "selected" : ""}>${window.siyuan.languages.fileNameNatDESC}</option>
|
||||||
</select>
|
</select>
|
||||||
<svg class="b3-menu__action" data-type="removeSort"><use xlink:href="#iconTrashcan"></use></svg>
|
<svg class="b3-menu__action" data-type="removeSort"><use xlink:href="#iconTrashcan"></use></svg>
|
||||||
</button>`;
|
</button>`;
|
||||||
|
|
@ -256,7 +315,7 @@ const getSortsHTML = (data: IAV) => {
|
||||||
</button>
|
</button>
|
||||||
<button class="b3-menu__separator"></button>
|
<button class="b3-menu__separator"></button>
|
||||||
${html}
|
${html}
|
||||||
<button class="b3-menu__item" data-type="addSort">
|
<button class="b3-menu__item${data.sorts.length === data.columns.length ? " fn__none" : ""}" data-type="addSort">
|
||||||
<svg class="b3-menu__icon"><use xlink:href="#iconAdd"></use></svg>
|
<svg class="b3-menu__icon"><use xlink:href="#iconAdd"></use></svg>
|
||||||
<span class="b3-menu__label">${window.siyuan.languages.new}</span>
|
<span class="b3-menu__label">${window.siyuan.languages.new}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -366,6 +425,7 @@ const addSort = (options: {
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
options.menuElement.innerHTML = getSortsHTML(options.data);
|
options.menuElement.innerHTML = getSortsHTML(options.data);
|
||||||
|
bindSortsEvent(options.protyle, options.menuElement, options.data);
|
||||||
setPosition(options.menuElement, options.tabRect.right - options.menuElement.clientWidth, options.tabRect.bottom, options.tabRect.height);
|
setPosition(options.menuElement, options.tabRect.right - options.menuElement.clientWidth, options.tabRect.bottom, options.tabRect.height);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,11 @@ ${cell.color ? `color:${cell.color};` : ""}"><span class="av__celltext">${text}<
|
||||||
<span class="item__text">${data.type}</span>
|
<span class="item__text">${data.type}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="fn__flex-1"></div>
|
<div class="fn__flex-1"></div>
|
||||||
<span data-type="av-filter" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.filter}">
|
<span data-type="av-filter" class="block__icon block__icon--show b3-tooltips b3-tooltips__w${data.filters.length > 0 ? " block__icon--active" : ""}" aria-label="${window.siyuan.languages.filter}">
|
||||||
<svg><use xlink:href="#iconFilter"></use></svg>
|
<svg><use xlink:href="#iconFilter"></use></svg>
|
||||||
</span>
|
</span>
|
||||||
<div class="fn__space"></div>
|
<div class="fn__space"></div>
|
||||||
<span data-type="av-sort" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.sort}">
|
<span data-type="av-sort" class="block__icon block__icon--show b3-tooltips b3-tooltips__w${data.sorts.length > 0 ? " block__icon--active" : ""}" aria-label="${window.siyuan.languages.sort}">
|
||||||
<svg><use xlink:href="#iconSort"></use></svg>
|
<svg><use xlink:href="#iconSort"></use></svg>
|
||||||
</span>
|
</span>
|
||||||
<div class="fn__space"></div>
|
<div class="fn__space"></div>
|
||||||
|
|
@ -137,15 +137,16 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
|
||||||
}
|
}
|
||||||
lastElement = protyle.contentElement;
|
lastElement = protyle.contentElement;
|
||||||
lastParentID = operation.parentID;
|
lastParentID = operation.parentID;
|
||||||
|
const avId = operation.action === "setAttrView"?operation.id: operation.parentID
|
||||||
if (operation.action === "addAttrViewCol") {
|
if (operation.action === "addAttrViewCol") {
|
||||||
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => {
|
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
|
||||||
item.removeAttribute("data-render");
|
item.removeAttribute("data-render");
|
||||||
avRender(item, () => {
|
avRender(item, () => {
|
||||||
showHeaderCellMenu(protyle, item, item.querySelector(".av__row--header").lastElementChild.previousElementSibling as HTMLElement);
|
showHeaderCellMenu(protyle, item, item.querySelector(".av__row--header").lastElementChild.previousElementSibling as HTMLElement);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (operation.action === "setAttrViewColWidth") {
|
} else if (operation.action === "setAttrViewColWidth") {
|
||||||
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => {
|
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
|
||||||
const cellElement = item.querySelector(`.av__cell[data-id="${operation.id}"]`) as HTMLElement;
|
const cellElement = item.querySelector(`.av__cell[data-id="${operation.id}"]`) as HTMLElement;
|
||||||
if (!cellElement || cellElement.style.width === operation.data) {
|
if (!cellElement || cellElement.style.width === operation.data) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -156,7 +157,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${operation.parentID}"]`)).forEach((item: HTMLElement) => {
|
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
|
||||||
item.removeAttribute("data-render");
|
item.removeAttribute("data-render");
|
||||||
avRender(item);
|
avRender(item);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -652,7 +652,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b
|
||||||
} else if (operation.action === "append") {
|
} else if (operation.action === "append") {
|
||||||
reloadProtyle(protyle, false);
|
reloadProtyle(protyle, false);
|
||||||
} else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewCell", "sortAttrViewRow",
|
} else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewCell", "sortAttrViewRow",
|
||||||
"sortAttrViewCol", "setAttrViewColHidden", "setAttrViewColWrap", "setAttrViewColWidth"].includes(operation.action)) {
|
"sortAttrViewCol", "setAttrViewColHidden", "setAttrViewColWrap", "setAttrViewColWidth", "setAttrView"].includes(operation.action)) {
|
||||||
refreshAV(protyle, operation);
|
refreshAV(protyle, operation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
1
app/src/types/index.d.ts
vendored
1
app/src/types/index.d.ts
vendored
|
|
@ -831,6 +831,7 @@ interface IAV {
|
||||||
name: string,
|
name: string,
|
||||||
type: "table"
|
type: "table"
|
||||||
rows: IAVRow[],
|
rows: IAVRow[],
|
||||||
|
id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IAVSort {
|
interface IAVSort {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue