Vanessa 2023-07-17 19:55:46 +08:00
parent 22c4a1554b
commit 5c29e2c8b2
4 changed files with 188 additions and 148 deletions

View file

@ -110,6 +110,10 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
const cellElement = hasClosestByClassName(event.target, "av__cell"); const cellElement = hasClosestByClassName(event.target, "av__cell");
if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) { if (cellElement && !cellElement.parentElement.classList.contains("av__row--header")) {
cellElement.parentElement.parentElement.querySelectorAll(".av__row--select").forEach(item => {
item.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck");
item.classList.remove("av__row--select");
});
popTextCell(protyle, [cellElement]); popTextCell(protyle, [cellElement]);
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();

View file

@ -292,8 +292,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[]) => {
} else if (type === "number") { } else if (type === "number") {
html = `<input type="number" value="${cellElements[0].textContent}" ${style} class="b3-text-field">`; html = `<input type="number" value="${cellElements[0].textContent}" ${style} class="b3-text-field">`;
} else if (["select", "mSelect"].includes(type) && blockElement) { } else if (["select", "mSelect"].includes(type) && blockElement) {
// TODO openMenuPanel(protyle, blockElement, "select", {cellElements});
openMenuPanel(protyle, blockElement, "select", {cellElement: cellElements[0]});
return; return;
} }
window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.remove();

View file

@ -44,7 +44,7 @@ export const openMenuPanel = (protyle: IProtyle,
const menuElement = avPanelElement.lastElementChild as HTMLElement; const menuElement = avPanelElement.lastElementChild as HTMLElement;
const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect(); const tabRect = blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
if (type === "select") { if (type === "select") {
const cellRect = options.cellElement.getBoundingClientRect(); const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height); setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
bindSelectEvent(protyle, data, menuElement, options); bindSelectEvent(protyle, data, menuElement, options);
menuElement.querySelector("input").select(); menuElement.querySelector("input").select();
@ -82,7 +82,8 @@ export const openMenuPanel = (protyle: IProtyle,
} else if (targetElement.querySelector('[data-type="removeFilter"]')) { } else if (targetElement.querySelector('[data-type="removeFilter"]')) {
type = "filters"; type = "filters";
} else if (targetElement.querySelector('[data-type="setSelectCol"]')) { } else if (targetElement.querySelector('[data-type="setSelectCol"]')) {
const changeData = data.view.columns.find((column) => column.id === options.cellElement.dataset.colId).options; const colId = options.cellElements[0].dataset.colId;
const changeData = data.view.columns.find((column) => column.id === colId).options;
const oldData = Object.assign([], changeData); const oldData = Object.assign([], changeData);
let targetOption: { name: string, color: string }; let targetOption: { name: string, color: string };
changeData.find((option, index: number) => { changeData.find((option, index: number) => {
@ -103,12 +104,12 @@ export const openMenuPanel = (protyle: IProtyle,
}); });
transaction(protyle, [{ transaction(protyle, [{
action: "updateAttrViewColOptions", action: "updateAttrViewColOptions",
id: options.cellElement.dataset.colId, id: colId,
avID: data.id, avID: data.id,
data: changeData, data: changeData,
}], [{ }], [{
action: "updateAttrViewColOptions", action: "updateAttrViewColOptions",
id: options.cellElement.dataset.colId, id: colId,
avID: data.id, avID: data.id,
data: oldData, data: oldData,
}]); }]);

View file

@ -43,66 +43,62 @@ const filterSelectHTML = (key: string, options: { name: string, color: string }[
}; };
export const removeSelectCell = (protyle: IProtyle, data: IAV, options: { export const removeSelectCell = (protyle: IProtyle, data: IAV, options: {
cellElement: HTMLElement cellElements: HTMLElement[]
}, target: HTMLElement) => { }, target: HTMLElement) => {
if (!target) { if (!target) {
return; return;
} }
const rowID = options.cellElement.parentElement.dataset.id; const colId = options.cellElements[0].dataset.colId;
const colId = options.cellElement.dataset.colId; const doOperations: IOperation[] = []
const cellId = options.cellElement.dataset.id; const undoOperations: IOperation[] = []
let colData: IAVColumn; options.cellElements.forEach(item => {
data.view.columns.find((item: IAVColumn) => { const rowID = item.parentElement.dataset.id;
if (item.id === colId) { const cellId = item.dataset.id;
colData = item; let cellData: IAVCell;
return; data.view.rows.find(row => {
} if (row.id === rowID) {
}); row.cells.find(cell => {
if (!colData.options) { if (cell.id === cellId) {
colData.options = []; cellData = cell;
} return true;
let cellData: IAVCell; }
data.view.rows.find(row => { });
if (row.id === rowID) { return true;
row.cells.find(cell => { }
if (cell.id === cellId) { });
cellData = cell; const oldValue = Object.assign([], cellData.value.mSelect);
return true; cellData.value.mSelect?.find((item: { content: string }, index: number) => {
} if (item.content === target.dataset.content) {
}); cellData.value.mSelect.splice(index, 1);
return true; return true;
} }
}); });
const oldValue = Object.assign([], cellData.value.mSelect);
cellData.value.mSelect?.find((item: { content: string }, index: number) => {
if (item.content === target.dataset.content) {
cellData.value.mSelect.splice(index, 1);
return true;
}
});
target.remove();
transaction(protyle, [{ doOperations.push({
action: "updateAttrViewCell", action: "updateAttrViewCell",
id: cellId, id: cellId,
keyID: colId, keyID: colId,
rowID, rowID,
avID: data.id, avID: data.id,
data: cellData.value data: cellData.value
}], [{ })
action: "updateAttrViewCell", undoOperations.push({
id: cellId, action: "updateAttrViewCell",
keyID: colId, id: cellId,
rowID, keyID: colId,
avID: data.id, rowID,
data: { avID: data.id,
[colData.type]: oldValue data: {
} mSelect: oldValue
}]); }
})
})
transaction(protyle, doOperations, undoOperations);
target.remove();
}; };
export const setSelectCol = (protyle: IProtyle, data: IAV, options: { export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
cellElement: HTMLElement; cellElements: HTMLElement[];
}, target: HTMLElement,) => { }, target: HTMLElement,) => {
const menuElement = hasClosestByClassName(target, "b3-menu"); const menuElement = hasClosestByClassName(target, "b3-menu");
if (!menuElement) { if (!menuElement) {
@ -145,9 +141,9 @@ export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
} }
}); });
data.view.rows.find(row => { data.view.rows.find(row => {
if (row.id === options.cellElement.parentElement.dataset.id) { if (row.id === options.cellElements[0].parentElement.dataset.id) {
row.cells.find(cell => { row.cells.find(cell => {
if (cell.id === options.cellElement.dataset.id) { if (cell.id === options.cellElements[0].dataset.id) {
cell.value.mSelect.find((item) => { cell.value.mSelect.find((item) => {
if (item.content === name) { if (item.content === name) {
item.content = inputElement.value; item.content = inputElement.value;
@ -166,7 +162,7 @@ export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
if (menu.isOpen) { if (menu.isOpen) {
return; return;
} }
const colId = options.cellElement.dataset.colId; const colId = options.cellElements[0].dataset.colId;
menu.addItem({ menu.addItem({
iconHTML: "", iconHTML: "",
label: `<input class="b3-text-field" style="margin: 4px 0" value="${name}">` label: `<input class="b3-text-field" style="margin: 4px 0" value="${name}">`
@ -202,9 +198,9 @@ export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
} }
}); });
data.view.rows.find(row => { data.view.rows.find(row => {
if (row.id === options.cellElement.parentElement.dataset.id) { if (row.id === options.cellElements[0].parentElement.dataset.id) {
row.cells.find(cell => { row.cells.find(cell => {
if (cell.id === options.cellElement.dataset.id) { if (cell.id === options.cellElements[0].dataset.id) {
cell.value.mSelect.find((item, index) => { cell.value.mSelect.find((item, index) => {
if (item.content === newName) { if (item.content === newName) {
cell.value.mSelect.splice(index, 1); cell.value.mSelect.splice(index, 1);
@ -269,9 +265,9 @@ export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
} }
}); });
data.view.rows.find(row => { data.view.rows.find(row => {
if (row.id === options.cellElement.parentElement.dataset.id) { if (row.id === options.cellElements[0].parentElement.dataset.id) {
row.cells.find(cell => { row.cells.find(cell => {
if (cell.id === options.cellElement.dataset.id) { if (cell.id === options.cellElements[0].dataset.id) {
cell.value.mSelect.find((item) => { cell.value.mSelect.find((item) => {
if (item.content === name) { if (item.content === name) {
item.content = inputElement.value; item.content = inputElement.value;
@ -305,10 +301,10 @@ export const setSelectCol = (protyle: IProtyle, data: IAV, options: {
}; };
export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLElement, options: { export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLElement, options: {
cellElement: HTMLElement cellElements: HTMLElement[]
}) => { }) => {
const inputElement = menuElement.querySelector("input"); const inputElement = menuElement.querySelector("input");
const colId = options.cellElement.dataset.colId; const colId = options.cellElements[0].dataset.colId;
let colData: IAVColumn; let colData: IAVColumn;
data.view.columns.find((item: IAVColumn) => { data.view.columns.find((item: IAVColumn) => {
if (item.id === colId) { if (item.id === colId) {
@ -350,13 +346,24 @@ export const bindSelectEvent = (protyle: IProtyle, data: IAV, menuElement: HTMLE
}; };
export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: { export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: {
cellElement: HTMLElement cellElements: HTMLElement[]
}, currentElement: HTMLElement, menuElement: HTMLElement) => { }, currentElement: HTMLElement, menuElement: HTMLElement) => {
const rowID = options.cellElement.parentElement.dataset.id; let hasSelected = false;
const colId = options.cellElement.dataset.colId; Array.from(menuElement.querySelectorAll(".b3-chips .b3-chip")).find((item: HTMLElement) => {
if (item.dataset.content === currentElement.dataset.name) {
hasSelected = true;
return true;
}
})
if (hasSelected) {
menuElement.querySelector("input").focus();
return;
}
const colId = options.cellElements[0].dataset.colId;
let cellIndex = 0; let cellIndex = 0;
Array.from(options.cellElement.parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => { Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
if (item.dataset.id === options.cellElement.dataset.id) { if (item.dataset.id === options.cellElements[0].dataset.id) {
cellIndex = index; cellIndex = index;
return true; return true;
} }
@ -365,82 +372,60 @@ export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: {
data.view.columns.find((item: IAVColumn) => { data.view.columns.find((item: IAVColumn) => {
if (item.id === colId) { if (item.id === colId) {
colData = item; colData = item;
if (!colData.options) {
colData.options = [];
}
return; return;
} }
}); });
if (!colData.options) {
colData.options = []; const cellDoOperations: IOperation[] = []
} const cellUndoOperations: IOperation[] = []
let cellData: IAVCell; options.cellElements.forEach(item => {
data.view.rows.find(row => { let cellData: IAVCell;
if (row.id === rowID) { const rowID = item.parentElement.dataset.id;
cellData = row.cells[cellIndex]; data.view.rows.find(row => {
// 为空时 cellId 每次请求都不一致 if (row.id === rowID) {
cellData.id = options.cellElement.dataset.id; cellData = row.cells[cellIndex];
if (!cellData.value || !cellData.value.mSelect) { // 为空时 cellId 每次请求都不一致
cellData.value = {mSelect: []} as IAVCellValue; cellData.id = item.dataset.id;
if (!cellData.value || !cellData.value.mSelect) {
cellData.value = {mSelect: []} as IAVCellValue;
}
return true;
} }
return true;
}
});
let hasSelected = false;
cellData.value.mSelect.find((item) => {
if (item.content === currentElement.dataset.name) {
hasSelected = true;
return true;
}
});
if (hasSelected) {
menuElement.querySelector("input").focus();
return;
}
const oldValue = Object.assign([], cellData.value.mSelect);
if (colData.type === "mSelect") {
cellData.value.mSelect.push({
color: currentElement.dataset.color,
content: currentElement.dataset.name
}); });
} else {
cellData.value.mSelect = [{
color: currentElement.dataset.color,
content: currentElement.dataset.name
}];
}
if (currentElement.querySelector(".b3-menu__accelerator")) { const oldValue = Object.assign([], cellData.value.mSelect);
colData.options.push({ if (colData.type === "mSelect") {
color: currentElement.dataset.color, let hasOption = false;
name: currentElement.dataset.name cellData.value.mSelect.find((item) => {
}); if (item.content === currentElement.dataset.name) {
transaction(protyle, [{ hasOption = true
action: "updateAttrViewColOptions", return true
id: colId, }
avID: data.id, });
data: colData.options if (!hasOption) {
}, { cellData.value.mSelect.push({
color: currentElement.dataset.color,
content: currentElement.dataset.name
});
}
} else {
cellData.value.mSelect = [{
color: currentElement.dataset.color,
content: currentElement.dataset.name
}];
}
cellDoOperations.push({
action: "updateAttrViewCell", action: "updateAttrViewCell",
id: cellData.id, id: cellData.id,
keyID: colId, keyID: colId,
rowID, rowID,
avID: data.id, avID: data.id,
data: cellData.value data: cellData.value
}], [{ })
action: "removeAttrViewColOption", cellUndoOperations.push({
id: colId,
avID: data.id,
data: currentElement.dataset.name,
}]);
} else {
transaction(protyle, [{
action: "updateAttrViewCell",
id: cellData.id,
keyID: colId,
rowID,
avID: data.id,
data: cellData.value
}], [{
action: "updateAttrViewCell", action: "updateAttrViewCell",
id: cellData.id, id: cellData.id,
keyID: colId, keyID: colId,
@ -449,7 +434,28 @@ export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: {
data: { data: {
[colData.type]: oldValue [colData.type]: oldValue
} }
})
})
if (currentElement.querySelector(".b3-menu__accelerator")) {
colData.options.push({
color: currentElement.dataset.color,
name: currentElement.dataset.name
});
cellDoOperations.splice(0, 0, {
action: "updateAttrViewColOptions",
id: colId,
avID: data.id,
data: colData.options
})
transaction(protyle, cellDoOperations, [{
action: "removeAttrViewColOption",
id: colId,
avID: data.id,
data: currentElement.dataset.name,
}]); }]);
} else {
transaction(protyle, cellDoOperations, cellUndoOperations);
} }
if (colData.type === "select") { if (colData.type === "select") {
menuElement.parentElement.remove(); menuElement.parentElement.remove();
@ -460,28 +466,58 @@ export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: {
} }
}; };
export const getSelectHTML = (data: IAVTable, options: { cellElement: HTMLElement }) => { export const getSelectHTML = (data: IAVTable, options: { cellElements: HTMLElement[] }) => {
const cellId = options.cellElement.dataset.id; const colId = options.cellElements[0].dataset["colId"];
const colId = options.cellElement.dataset["colId"];
const colData = data.columns.find(item => { const colData = data.columns.find(item => {
if (item.id === colId) { if (item.id === colId) {
return item; return item;
} }
}); });
const commonOptions: { content: string, color: string }[][] = []
const allUniqueOptions: { content: string, color: string }[] = []
options.cellElements.forEach((cellElement) => {
data.rows.find(row => {
if (cellElement.parentElement.dataset.id === row.id) {
const commonOption: { content: string, color: string }[] = []
row.cells.find(cell => {
if (cell.id === cellElement.dataset.id) {
if (cell.value && cell.value.mSelect) {
cell.value.mSelect.forEach((item: { content: string, color: string }) => {
commonOption.push(item)
allUniqueOptions.push(item)
});
}
return true;
}
});
commonOptions.push(commonOption)
return true;
}
});
});
let selectedHTML = ""; let selectedHTML = "";
data.rows.find(row => { allUniqueOptions.forEach((unique) => {
if (options.cellElement.parentElement.dataset.id === row.id) { let everyRowHas = true
row.cells.find(cell => { commonOptions.find(item => {
if (cell.id === cellId && cell.value) { let hasContent = false
cell.value.mSelect?.forEach((item: { content: string, color: string }) => { item.find((option) => {
selectedHTML += `<div class="b3-chip b3-chip--middle" data-content="${item.content}" style="background-color:var(--b3-font-background${item.color});color:var(--b3-font-color${item.color})">${item.content}<svg class="b3-chip__close" data-type="removeSelectCell"><use xlink:href="#iconCloseRound"></use></svg></div>`; if (option.content === unique.content) {
}); hasContent = true
return true; return true;
} }
}); })
return true; if (!hasContent) {
everyRowHas = false
return true
}
})
if (everyRowHas && selectedHTML.indexOf(`data-content="${unique.content}"`) === -1) {
selectedHTML += `<div class="b3-chip b3-chip--middle" data-content="${unique.content}" style="background-color:var(--b3-font-background${unique.color});color:var(--b3-font-color${unique.color})">${unique.content}<svg class="b3-chip__close" data-type="removeSelectCell"><use xlink:href="#iconCloseRound"></use></svg></div>`;
} }
}); });
return `<div class="b3-chips"> return `<div class="b3-chips">
${selectedHTML} ${selectedHTML}
<input> <input>