Vanessa 2023-07-11 22:48:48 +08:00
parent caf074185d
commit 0ec924e239
8 changed files with 244 additions and 228 deletions

View file

@ -246,17 +246,13 @@ export const updateAVName = (protyle: IProtyle, blockElement: Element) => {
return;
}
transaction(protyle, [{
action: "setAttrView",
action: "setAttrViewName",
id: avId,
data: {
name: nameElement.textContent.trim(),
}
data: nameElement.textContent.trim(),
}], [{
action: "setAttrView",
action: "setAttrViewName",
id: avId,
data: {
name: nameElement.dataset.title,
}
}]);
nameElement.dataset.title = nameElement.textContent.trim();
};

View file

@ -105,20 +105,18 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
click() {
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
sorts: [{
action: "setAttrViewSorts",
avID: response.data.id,
viewID: response.data.viewID,
data: [{
column: colId,
order: "ASC"
}]
}
}], [{
action: "setAttrView",
id: avId,
data: {
sorts: response.data.view.sorts
}
action: "setAttrViewSorts",
avID: response.data.id,
viewID: response.data.viewID,
data: response.data.view.sorts
}]);
});
}
@ -129,20 +127,18 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
click() {
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
sorts: [{
action: "setAttrViewSorts",
avID: response.data.id,
viewID: response.data.viewID,
data: [{
column: colId,
order: "DESC"
}]
}
}], [{
action: "setAttrView",
id: avId,
data: {
sorts: response.data.view.sorts
}
action: "setAttrViewSorts",
avID: response.data.id,
viewID: response.data.viewID,
data: response.data.view.sorts
}]);
});
}
@ -152,9 +148,9 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
label: window.siyuan.languages.filter,
click() {
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
const avData = response.data.view as IAVTable;
const avData = response.data as IAV;
let filter: IAVFilter;
avData.filters.find((item) => {
avData.view.filters.find((item) => {
if (item.column === colId) {
filter = item;
return true;
@ -166,19 +162,17 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl
operator: "Contains",
value: getCellValue(type, "")
};
avData.filters.push(filter);
avData.view.filters.push(filter);
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
filters: [filter]
}
action: "setAttrViewFilters",
avID: avId,
viewID: avData.viewID,
data: [filter]
}], [{
action: "setAttrView",
id: avId,
data: {
filters: []
}
action: "setAttrViewFilters",
avID: avId,
viewID: avData.viewID,
data: []
}]);
}
setFilter({

View file

@ -42,13 +42,13 @@ export const getCellValue = (colType: TAVCol, value: string) => {
export const setFilter = (options: {
filter: IAVFilter,
protyle: IProtyle,
data: IAVTable,
data: IAV,
target: HTMLElement,
}) => {
const colType = Object.keys(options.filter.value)[0] as TAVCol;
const rectTarget = options.target.getBoundingClientRect();
const menu = new Menu("set-filter-" + options.filter.column, () => {
const oldFilters = JSON.parse(JSON.stringify(options.data.filters));
const oldFilters = JSON.parse(JSON.stringify(options.data.view.filters));
let hasMatch = false;
const cellValue = getCellValue(colType, textElement?.value || "");
const newFilter: IAVFilter = {
@ -58,13 +58,13 @@ export const setFilter = (options: {
}
let isSame = false;
options.data.filters.find((filter, index) => {
options.data.view.filters.find((filter, index) => {
if (filter.column === options.filter.column) {
if (objEquals(filter, newFilter)) {
isSame = true;
return true;
}
options.data.filters[index] = newFilter;
options.data.view.filters[index] = newFilter;
hasMatch = true;
return true;
}
@ -73,21 +73,19 @@ export const setFilter = (options: {
return;
}
transaction(options.protyle, [{
action: "setAttrView",
id: options.data.id,
data: {
filters: options.data.filters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: options.data.view.filters
}], [{
action: "setAttrView",
id: options.data.id,
data: {
filters: oldFilters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: oldFilters
}]);
const menuElement = hasClosestByClassName(options.target, "b3-menu");
if (menuElement) {
menuElement.innerHTML = getFiltersHTML(options.data);
menuElement.innerHTML = getFiltersHTML(options.data.view);
}
});
if (menu.isOpen) {
@ -119,7 +117,7 @@ export const setFilter = (options: {
`;
break;
case "mSelect":
options.data.columns.find((column) => {
options.data.view.columns.find((column) => {
if (column.id === options.filter.column) {
colData = column;
if (column.type === "select") {
@ -169,29 +167,27 @@ export const setFilter = (options: {
icon: "iconTrashcan",
label: window.siyuan.languages.delete,
click() {
const oldFilters = Object.assign([], options.data.filters);
options.data.filters.find((item: IAVFilter, index: number) => {
const oldFilters = Object.assign([], options.data.view.filters);
options.data.view.filters.find((item: IAVFilter, index: number) => {
if (item.column === options.filter.column) {
options.data.filters.splice(index, 1);
options.data.view.filters.splice(index, 1);
return true;
}
});
transaction(options.protyle, [{
action: "setAttrView",
id: options.data.id,
data: {
filters: options.data.filters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: options.data.view.filters
}], [{
action: "setAttrView",
id: options.data.id,
data: {
filters: oldFilters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: oldFilters
}]);
const menuElement = hasClosestByClassName(options.target, "b3-menu");
if (menuElement) {
menuElement.innerHTML = getFiltersHTML(options.data);
menuElement.innerHTML = getFiltersHTML(options.data.view);
}
}
});
@ -228,7 +224,7 @@ export const setFilter = (options: {
};
export const addFilter = (options: {
data: IAVTable,
data: IAV,
rect: DOMRect,
menuElement: HTMLElement,
tabRect: DOMRect,
@ -236,9 +232,9 @@ export const addFilter = (options: {
protyle: IProtyle
}) => {
const menu = new Menu("av-add-filter");
options.data.columns.forEach((column) => {
options.data.view.columns.forEach((column) => {
let hasFilter = false;
options.data.filters.find((filter) => {
options.data.view.filters.find((filter) => {
if (filter.column === column.id) {
hasFilter = true;
return true;
@ -249,27 +245,25 @@ export const addFilter = (options: {
label: column.name,
icon: getColIconByType(column.type),
click: () => {
const oldFilters = Object.assign([], options.data.filters);
const oldFilters = Object.assign([], options.data.view.filters);
const cellValue = getCellValue(column.type, "");
options.data.filters.push({
options.data.view.filters.push({
column: column.id,
operator: "Contains",
value: cellValue,
});
transaction(options.protyle, [{
action: "setAttrView",
id: options.avId,
data: {
filters: options.data.filters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: options.data.view.filters
}], [{
action: "setAttrView",
id: options.avId,
data: {
filters: oldFilters
}
action: "setAttrViewFilters",
avID: options.data.id,
viewID: options.data.viewID,
data: oldFilters
}]);
options.menuElement.innerHTML = getFiltersHTML(options.data);
options.menuElement.innerHTML = getFiltersHTML(options.data.view);
setPosition(options.menuElement, options.tabRect.right - options.menuElement.clientWidth, options.tabRect.bottom, options.tabRect.height);
const filterElement = options.menuElement.querySelector(`[data-id="${column.id}"] .b3-chip`) as HTMLElement;
setFilter({

View file

@ -20,18 +20,18 @@ export const openMenuPanel = (protyle: IProtyle,
window.siyuan.menus.menu.remove();
const avId = blockElement.getAttribute("data-av-id");
fetchPost("/api/av/renderAttributeView", {id: avId}, (response) => {
const data = response.data.view as IAVTable;
const data = response.data as IAV;
let html;
if (type === "config") {
html = getConfigHTML(data);
html = getConfigHTML(data.view);
} else if (type === "properties") {
html = getPropertiesHTML(data);
html = getPropertiesHTML(data.view);
} else if (type === "sorts") {
html = getSortsHTML(data);
html = getSortsHTML(data.view.columns, data.view.sorts);
} else if (type === "filters") {
html = getFiltersHTML(data);
html = getFiltersHTML(data.view);
} else if (type === "select") {
html = getSelectHTML(data, options);
html = getSelectHTML(data.view, options);
}
document.body.insertAdjacentHTML("beforeend", `<div class="av__panel">
@ -44,7 +44,7 @@ export const openMenuPanel = (protyle: IProtyle,
if (options && options.cellElement) {
const cellRect = options.cellElement.getBoundingClientRect();
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
bindSelectEvent(protyle, data, menuElement, options);
bindSelectEvent(protyle, data.view, menuElement, options);
menuElement.querySelector("input").select();
menuElement.querySelector("input").focus();
} else {
@ -79,7 +79,7 @@ export const openMenuPanel = (protyle: IProtyle,
} else if (targetElement.querySelector('[data-type="removeFilter"]')) {
type = "filters";
} else if (targetElement.querySelector('[data-type="setSelectCol"]')) {
const changeData = data.columns.find((column) => column.id === options.cellElement.dataset.colId).options;
const changeData = data.view.columns.find((column) => column.id === options.cellElement.dataset.colId).options;
const oldData = Object.assign([], changeData);
let targetOption: { name: string, color: string };
changeData.find((option, index: number) => {
@ -109,14 +109,50 @@ export const openMenuPanel = (protyle: IProtyle,
parentID: data.id,
data: oldData,
}]);
menuElement.innerHTML = getSelectHTML(data, options);
bindSelectEvent(protyle, data, menuElement, options);
menuElement.innerHTML = getSelectHTML(data.view, options);
bindSelectEvent(protyle, data.view, menuElement, options);
return;
}
const sourceId = sourceElement.dataset.id;
const targetId = targetElement.dataset.id;
if (type !== "columns") {
const changeData = (type === "sorts" ? data.sorts : data.filters) as IAVFilter[];
if (type === "sorts") {
const changeData = data.view.sorts;
const oldData = Object.assign([], changeData);
let sortFilter: IAVSort;
changeData.find((sort, index: number) => {
if (sort.column === sourceId) {
sortFilter = changeData.splice(index, 1)[0];
return true;
}
});
changeData.find((sort, index: number) => {
if (sort.column === targetId) {
if (isTop) {
changeData.splice(index, 0, sortFilter);
} else {
changeData.splice(index + 1, 0, sortFilter);
}
return true;
}
});
transaction(protyle, [{
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: changeData
}], [{
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: oldData
}]);
menuElement.innerHTML = getSortsHTML(data.view.columns, data.view.sorts);
bindSortsEvent(protyle, menuElement, data);
return;
}
if (type === "filters") {
const changeData = data.view.filters;
const oldData = Object.assign([], changeData);
let targetFilter: IAVFilter;
changeData.find((filter, index: number) => {
@ -137,22 +173,17 @@ export const openMenuPanel = (protyle: IProtyle,
});
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
[type]: changeData
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: changeData
}], [{
action: "setAttrView",
id: avId,
data: {
[type]: oldData
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: oldData
}]);
menuElement.innerHTML = (type === "sorts" ? getSortsHTML(data) : getFiltersHTML(data));
if (type === "sorts") {
bindSortsEvent(protyle, menuElement, data);
}
menuElement.innerHTML = getFiltersHTML(data.view);
return;
}
transaction(protyle, [{
@ -167,23 +198,23 @@ export const openMenuPanel = (protyle: IProtyle,
id: sourceId,
}]);
let column: IAVColumn;
data.columns.find((item, index: number) => {
data.view.columns.find((item, index: number) => {
if (item.id === sourceId) {
column = data.columns.splice(index, 1)[0];
column = data.view.columns.splice(index, 1)[0];
return true;
}
});
data.columns.find((item, index: number) => {
data.view.columns.find((item, index: number) => {
if (item.id === targetId) {
if (isTop) {
data.columns.splice(index, 0, column);
data.view.columns.splice(index, 0, column);
} else {
data.columns.splice(index + 1, 0, column);
data.view.columns.splice(index + 1, 0, column);
}
return true;
}
});
menuElement.innerHTML = getPropertiesHTML(data);
menuElement.innerHTML = getPropertiesHTML(data.view);
});
let dragoverElement: HTMLElement;
avPanelElement.addEventListener("dragover", (event: DragEvent) => {
@ -229,37 +260,35 @@ export const openMenuPanel = (protyle: IProtyle,
event.stopPropagation();
break;
} else if (type === "goConfig") {
menuElement.innerHTML = getConfigHTML(data);
menuElement.innerHTML = getConfigHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "goProperties") {
menuElement.innerHTML = getPropertiesHTML(data);
menuElement.innerHTML = getPropertiesHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "goSorts") {
menuElement.innerHTML = getSortsHTML(data);
menuElement.innerHTML = getSortsHTML(data.view.columns, data.view.sorts);
bindSortsEvent(protyle, menuElement, data);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "removeSorts") {
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
sorts: []
}
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: []
}], [{
action: "setAttrView",
id: avId,
data: {
sorts: data.sorts
}
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: data.view.sorts
}]);
data.sorts = [];
menuElement.innerHTML = getSortsHTML(data);
data.view.sorts = [];
menuElement.innerHTML = getSortsHTML(data.view.columns, data.view.sorts);
bindSortsEvent(protyle, menuElement, data);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
@ -269,52 +298,48 @@ export const openMenuPanel = (protyle: IProtyle,
event.stopPropagation();
break;
} else if (type === "removeSort") {
const oldSorts = Object.assign([], data.sorts);
data.sorts.find((item: IAVSort, index: number) => {
const oldSorts = Object.assign([], data.view.sorts);
data.view.sorts.find((item: IAVSort, index: number) => {
if (item.column === target.parentElement.dataset.id) {
data.sorts.splice(index, 1);
data.view.sorts.splice(index, 1);
return true;
}
});
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
sorts: data.sorts
}
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: data.view.sorts
}], [{
action: "setAttrView",
id: avId,
data: {
sorts: oldSorts
}
action: "setAttrViewSorts",
avID: avId,
viewID: data.viewID,
data: oldSorts
}]);
menuElement.innerHTML = getSortsHTML(data);
menuElement.innerHTML = getSortsHTML(data.view.columns, data.view.sorts);
bindSortsEvent(protyle, menuElement, data);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "goFilters") {
menuElement.innerHTML = getFiltersHTML(data);
menuElement.innerHTML = getFiltersHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "removeFilters") {
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
filters: []
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: []
}], [{
action: "setAttrView",
id: avId,
data: {
filters: data.filters
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: data.view.filters
}]);
data.filters = [];
menuElement.innerHTML = getFiltersHTML(data);
data.view.filters = [];
menuElement.innerHTML = getFiltersHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
@ -324,32 +349,30 @@ export const openMenuPanel = (protyle: IProtyle,
break;
} else if (type === "removeFilter") {
window.siyuan.menus.menu.remove();
const oldFilters = Object.assign([], data.filters);
data.filters.find((item: IAVFilter, index: number) => {
const oldFilters = Object.assign([], data.view.filters);
data.view.filters.find((item: IAVFilter, index: number) => {
if (item.column === target.parentElement.dataset.id) {
data.filters.splice(index, 1);
data.view.filters.splice(index, 1);
return true;
}
});
transaction(protyle, [{
action: "setAttrView",
id: avId,
data: {
filters: data.filters
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: data.view.filters
}], [{
action: "setAttrView",
id: avId,
data: {
filters: oldFilters
}
action: "setAttrViewFilters",
avID: avId,
viewID: data.viewID,
data: oldFilters
}]);
menuElement.innerHTML = getFiltersHTML(data);
menuElement.innerHTML = getFiltersHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "setFilter") {
data.filters.find((item: IAVFilter) => {
data.view.filters.find((item: IAVFilter) => {
if (item.column === target.parentElement.parentElement.dataset.id) {
setFilter({
filter: item,
@ -376,7 +399,7 @@ export const openMenuPanel = (protyle: IProtyle,
} else if (type === "showAllCol") {
const doOperations: IOperation[] = [];
const undoOperations: IOperation[] = [];
data.columns.forEach((item: IAVColumn) => {
data.view.columns.forEach((item: IAVColumn) => {
if (item.hidden) {
doOperations.push({
action: "setAttrViewColHidden",
@ -395,7 +418,7 @@ export const openMenuPanel = (protyle: IProtyle,
});
if (doOperations.length > 0) {
transaction(protyle, doOperations, undoOperations);
menuElement.innerHTML = getPropertiesHTML(data);
menuElement.innerHTML = getPropertiesHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
}
event.stopPropagation();
@ -403,7 +426,7 @@ export const openMenuPanel = (protyle: IProtyle,
} else if (type === "hideAllCol") {
const doOperations: IOperation[] = [];
const undoOperations: IOperation[] = [];
data.columns.forEach((item: IAVColumn) => {
data.view.columns.forEach((item: IAVColumn) => {
if (!item.hidden && item.type !== "block") {
doOperations.push({
action: "setAttrViewColHidden",
@ -422,7 +445,7 @@ export const openMenuPanel = (protyle: IProtyle,
});
if (doOperations.length > 0) {
transaction(protyle, doOperations, undoOperations);
menuElement.innerHTML = getPropertiesHTML(data);
menuElement.innerHTML = getPropertiesHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
}
event.stopPropagation();
@ -440,8 +463,8 @@ export const openMenuPanel = (protyle: IProtyle,
parentID: avId,
data: false
}]);
data.columns.find((item: IAVColumn) => item.id === colId).hidden = true;
menuElement.innerHTML = getPropertiesHTML(data);
data.view.columns.find((item: IAVColumn) => item.id === colId).hidden = true;
menuElement.innerHTML = getPropertiesHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
@ -458,22 +481,22 @@ export const openMenuPanel = (protyle: IProtyle,
parentID: avId,
data: true
}]);
data.columns.find((item: IAVColumn) => item.id === colId).hidden = false;
menuElement.innerHTML = getPropertiesHTML(data);
data.view.columns.find((item: IAVColumn) => item.id === colId).hidden = false;
menuElement.innerHTML = getPropertiesHTML(data.view);
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
event.stopPropagation();
break;
} else if (type === "setSelectCol") {
setSelectCol(protyle, data, options, target);
setSelectCol(protyle, data.view, options, target);
event.stopPropagation();
break;
} else if (type === "addSelectColAndCell") {
addSelectColAndCell(protyle, data, options, target, menuElement);
addSelectColAndCell(protyle, data.view, options, target, menuElement);
window.siyuan.menus.menu.remove();
event.stopPropagation();
break;
} else if (type === "removeSelectCell") {
removeSelectCell(protyle, data, options, target.parentElement);
removeSelectCell(protyle, data.view, options, target.parentElement);
event.stopPropagation();
break;
}

View file

@ -141,7 +141,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
}
lastElement = protyle.contentElement;
lastParentID = operation.parentID;
const avId = operation.action === "setAttrView" ? operation.id : operation.parentID;
const avId = operation.avID;
if (operation.action === "addAttrViewCol") {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
item.removeAttribute("data-render");
@ -159,14 +159,14 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
(rowItem.querySelector(`[data-col-id="${operation.id}"]`) as HTMLElement).style.width = operation.data;
});
});
} else if (operation.action === "setAttrView" && typeof operation.data.name === "string") {
} else if (operation.action === "setAttrViewName") {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
const titleElement = item.querySelector(".av__title") as HTMLElement;
if (!titleElement || titleElement.textContent.trim() === operation.data.name) {
if (!titleElement || titleElement.textContent.trim() === operation.data) {
return;
}
titleElement.textContent = operation.data.name;
titleElement.dataset.title = operation.data.name;
titleElement.textContent = operation.data;
titleElement.dataset.title = operation.data;
});
} else {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {

View file

@ -4,7 +4,7 @@ import {transaction} from "../../wysiwyg/transaction";
import {setPosition} from "../../../util/setPosition";
export const addSort = (options: {
data: IAVTable,
data: IAV,
rect: DOMRect,
menuElement: HTMLElement,
tabRect: DOMRect,
@ -12,9 +12,9 @@ export const addSort = (options: {
protyle: IProtyle
}) => {
const menu = new Menu("av-add-sort");
options.data.columns.forEach((column) => {
options.data.view.columns.forEach((column) => {
let hasSort = false;
options.data.sorts.find((sort) => {
options.data.view.sorts.find((sort) => {
if (sort.column === column.id) {
hasSort = true;
return true;
@ -25,25 +25,23 @@ export const addSort = (options: {
label: column.name,
icon: getColIconByType(column.type),
click: () => {
const oldSorts = Object.assign([], options.data.sorts);
options.data.sorts.push({
const oldSorts = Object.assign([], options.data.view.sorts);
options.data.view.sorts.push({
column: column.id,
order: "ASC",
});
transaction(options.protyle, [{
action: "setAttrView",
id: options.avId,
data: {
sorts: options.data.sorts
}
action: "setAttrViewSorts",
avID: options.data.id,
viewID: options.data.viewID,
data: options.data.view.sorts
}], [{
action: "setAttrView",
id: options.avId,
data: {
sorts: oldSorts
}
action: "setAttrViewSorts",
avID: options.data.id,
viewID: options.data.viewID,
data: oldSorts
}]);
options.menuElement.innerHTML = getSortsHTML(options.data);
options.menuElement.innerHTML = getSortsHTML(options.data.view.columns, options.data.view.sorts);
bindSortsEvent(options.protyle, options.menuElement, options.data);
setPosition(options.menuElement, options.tabRect.right - options.menuElement.clientWidth, options.tabRect.bottom, options.tabRect.height);
}
@ -57,13 +55,13 @@ export const addSort = (options: {
});
};
export const bindSortsEvent = (protyle: IProtyle, menuElement: HTMLElement, data: IAVTable) => {
export const bindSortsEvent = (protyle: IProtyle, menuElement: HTMLElement, data: IAV) => {
menuElement.querySelectorAll("select").forEach((item: HTMLSelectElement) => {
item.addEventListener("change", () => {
const colId = item.parentElement.getAttribute("data-id");
const oldSort = JSON.parse(JSON.stringify(data.sorts));
const oldSort = JSON.parse(JSON.stringify(data.view.sorts));
if (item.previousElementSibling.classList.contains("b3-menu__icon")) {
data.sorts.find((sort: IAVSort) => {
data.view.sorts.find((sort: IAVSort) => {
if (sort.column === colId) {
sort.column = item.value;
item.parentElement.setAttribute("data-id", item.value);
@ -71,35 +69,33 @@ export const bindSortsEvent = (protyle: IProtyle, menuElement: HTMLElement, data
}
});
} else {
data.sorts.find((sort: IAVSort) => sort.column === colId).order = item.value as "ASC" | "DESC";
data.view.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: "setAttrViewSorts",
avID: data.id,
viewID: data.viewID,
data: data.view.sorts
}], [{
action: "setAttrView",
id: data.id,
data: {
sorts: oldSort
}
action: "setAttrViewSorts",
avID: data.id,
viewID: data.viewID,
data: oldSort
}]);
});
});
};
export const getSortsHTML = (data: IAVTable) => {
export const getSortsHTML = (columns: IAVColumn[], sorts: IAVSort[]) => {
let html = "";
const genSortItem = (id: string) => {
let sortHTML = "";
data.columns.forEach((item) => {
columns.forEach((item) => {
sortHTML += `<option value="${item.id}" ${item.id === id ? "selected" : ""}>${item.name}</option>`;
});
return sortHTML;
};
data.sorts.forEach((item: IAVSort) => {
sorts.forEach((item: IAVSort) => {
html += `<button draggable="true" class="b3-menu__item" data-id="${item.column}">
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
<select class="b3-select" style="margin: 4px 0">
@ -122,7 +118,7 @@ export const getSortsHTML = (data: IAVTable) => {
</button>
<button class="b3-menu__separator"></button>
${html}
<button class="b3-menu__item${data.sorts.length === data.columns.length ? " fn__none" : ""}" data-type="addSort">
<button class="b3-menu__item${sorts.length === columns.length ? " fn__none" : ""}" data-type="addSort">
<svg class="b3-menu__icon"><use xlink:href="#iconAdd"></use></svg>
<span class="b3-menu__label">${window.siyuan.languages.new}</span>
</button>

View file

@ -653,7 +653,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b
reloadProtyle(protyle, false);
} else if (["addAttrViewCol", "insertAttrViewBlock", "updateAttrViewCol", "updateAttrViewColOptions",
"updateAttrViewColOption", "updateAttrViewCell", "sortAttrViewRow", "sortAttrViewCol", "setAttrViewColHidden",
"setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrView"].includes(operation.action)) {
"setAttrViewColWrap", "setAttrViewColWidth", "removeAttrViewColOption", "setAttrViewName"].includes(operation.action)) {
refreshAV(protyle, operation);
}
};

View file

@ -32,7 +32,9 @@ type TOperation =
| "updateAttrViewColOptions"
| "removeAttrViewColOption"
| "updateAttrViewColOption"
| "setAttrView"
| "setAttrViewName"
| "setAttrViewFilters"
| "setAttrViewSorts"
type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins"
type TCardType = "doc" | "notebook" | "all"
type TEventBus = "ws-main" |
@ -304,6 +306,8 @@ interface IScrollAttr {
interface IOperation {
action: TOperation, // move delete 不需要传 data
id?: string,
avID?: string, // av
viewID?: string, // av
data?: any, // updateAttr 时为 { old: IObject, new: IObject }, updateAttrViewCell 时为 {TAVCol: {content: string}}
parentID?: string // 为 insertAttrViewBlock 传 avid
previousID?: string
@ -842,6 +846,15 @@ interface IBazaarItem {
preferredFunding: string
}
interface IAV {
id: string
name: string
view: IAVTable
viewID: string
viewType: string
views: IAVView[],
}
interface IAVView {
name: string
id: string