Vanessa 2023-07-10 22:15:14 +08:00
parent 8cf28fcd24
commit e1d7ab0bc1
5 changed files with 128 additions and 40 deletions

View file

@ -175,7 +175,8 @@
border: 0; border: 0;
background-color: var(--b3-menu-background); background-color: var(--b3-menu-background);
flex: 1; flex: 1;
height: 38px; height: 30px;
color: var(--b3-theme-on-background);
} }
} }

View file

@ -3,6 +3,7 @@ import {transaction} from "../../wysiwyg/transaction";
import {hasClosestByClassName} from "../../util/hasClosest"; import {hasClosestByClassName} from "../../util/hasClosest";
import {getColIconByType} from "./col"; import {getColIconByType} from "./col";
import {setPosition} from "../../../util/setPosition"; import {setPosition} from "../../../util/setPosition";
import {objEquals} from "../../../util/functions";
export const setFilter = (options: { export const setFilter = (options: {
filter: IAVFilter, filter: IAVFilter,
@ -14,28 +15,62 @@ export const setFilter = (options: {
const rectTarget = options.target.getBoundingClientRect(); const rectTarget = options.target.getBoundingClientRect();
const menu = new Menu("set-filter-" + options.filter.column, () => { 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.filters));
options.data.filters.find((filter) => { let hasMatch = false;
if (filter.column === options.filter.column) {
let cellValue: IAVCellValue; let cellValue;
if (colType === "number") { if (colType === "number") {
if (textElement.value) { if (textElement.value) {
cellValue = { cellValue = {
content: parseFloat(textElement.value), number: {
isNotEmpty: true content: parseFloat(textElement.value),
}; isNotEmpty: true
} else {
cellValue = {};
} }
} else { };
cellValue = { } else {
content: textElement.value cellValue = {
}; number: {
isNotEmpty: false
}
};
}
} else if (colType === "text") {
cellValue = {
text: {
content: textElement.value
} }
filter.value[colType] = cellValue; };
filter.operator = (window.siyuan.menus.menu.element.querySelector(".b3-select") as HTMLSelectElement).value as TAVFilterOperator; } else if (colType === "select") {
cellValue = {
text: {
content: textElement.value
}
};
}
const newFilter = {
column: options.filter.column,
value: cellValue,
operator: (window.siyuan.menus.menu.element.querySelector(".b3-select") as HTMLSelectElement).value as TAVFilterOperator
}
let isSame = false;
options.data.filters.find((filter, index) => {
if (filter.column === options.filter.column) {
if (objEquals(filter, newFilter)) {
isSame = true;
return true;
}
options.data.filters[index] = newFilter;
hasMatch = true;
return true; return true;
} }
}); });
if (isSame) {
return;
}
if (!hasMatch) {
options.data.filters.push(newFilter)
}
transaction(options.protyle, [{ transaction(options.protyle, [{
action: "setAttrView", action: "setAttrView",
id: options.data.id, id: options.data.id,
@ -79,6 +114,20 @@ export const setFilter = (options: {
<option ${"<=" === options.filter.operator ? "selected" : ""} value="<=">&le;</option> <option ${"<=" === options.filter.operator ? "selected" : ""} value="<=">&le;</option>
<option ${"Is empty" === options.filter.operator ? "selected" : ""} value="Is empty">${window.siyuan.languages.filterOperatorIsEmpty}</option> <option ${"Is empty" === options.filter.operator ? "selected" : ""} value="Is empty">${window.siyuan.languages.filterOperatorIsEmpty}</option>
<option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option> <option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option>
`;
break;
case "select":
selectHTML = `<option ${"=" === options.filter.operator ? "selected" : ""} value="=">${window.siyuan.languages.filterOperatorIs}</option>
<option ${"!=" === options.filter.operator ? "selected" : ""} value="!=">${window.siyuan.languages.filterOperatorIsNot}</option>
<option ${"Is empty" === options.filter.operator ? "selected" : ""} value="Is empty">${window.siyuan.languages.filterOperatorIsEmpty}</option>
<option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option>
`;
break;
case "mSelect":
selectHTML = `<option ${"Contains" === options.filter.operator ? "selected" : ""} value="Contains">${window.siyuan.languages.filterOperatorContains}</option>
<option ${"Does not contains" === options.filter.operator ? "selected" : ""} value="Does not contains">${window.siyuan.languages.filterOperatorDoesNotContain}</option>
<option ${"Is empty" === options.filter.operator ? "selected" : ""} value="Is empty">${window.siyuan.languages.filterOperatorIsEmpty}</option>
<option ${"Is not empty" === options.filter.operator ? "selected" : ""} value="Is not empty">${window.siyuan.languages.filterOperatorIsNotEmpty}</option>
`; `;
break; break;
} }
@ -86,9 +135,26 @@ export const setFilter = (options: {
iconHTML: "", iconHTML: "",
label: `<select style="margin: 4px 0" class="b3-select fn__size200">${selectHTML}</select>` label: `<select style="margin: 4px 0" class="b3-select fn__size200">${selectHTML}</select>`
}); });
menu.addItem({ if (colType === "select" || colType === "mSelect") {
iconHTML: "",
label: `<input style="margin: 4px 0" value="${options.filter.value[colType].content}" class="b3-text-field fn__size200">` } else if (colType === "text") {
menu.addItem({
iconHTML: "",
label: `<input style="margin: 4px 0" value="${options.filter.value[colType].content}" class="b3-text-field fn__size200">`
});
} else if (colType === "number") {
menu.addItem({
iconHTML: "",
label: `<input style="margin: 4px 0" value="${options.filter.value[colType].isNotEmpty ? options.filter.value[colType].content : ""}" class="b3-text-field fn__size200">`
});
}
const selectElement = (window.siyuan.menus.menu.element.querySelector(".b3-select") as HTMLSelectElement);
selectElement.addEventListener("change", () => {
if (selectElement.value === "Is empty" || selectElement.value === "Is not empty") {
textElement.parentElement.parentElement.classList.add("fn__none");
} else {
textElement.parentElement.parentElement.classList.remove("fn__none");
}
}); });
const textElement = (window.siyuan.menus.menu.element.querySelector(".b3-text-field") as HTMLInputElement); const textElement = (window.siyuan.menus.menu.element.querySelector(".b3-text-field") as HTMLInputElement);
textElement.addEventListener("keydown", (event) => { textElement.addEventListener("keydown", (event) => {
@ -101,6 +167,11 @@ export const setFilter = (options: {
event.preventDefault(); event.preventDefault();
} }
}); });
if (selectElement.value === "Is empty" || selectElement.value === "Is not empty") {
textElement.parentElement.parentElement.classList.add("fn__none");
} else {
textElement.parentElement.parentElement.classList.remove("fn__none");
}
menu.open({x: rectTarget.left, y: rectTarget.bottom}); menu.open({x: rectTarget.left, y: rectTarget.bottom});
textElement.select(); textElement.select();
}; };
@ -185,16 +256,32 @@ export const getFiltersHTML = (data: IAV) => {
let filterHTML = ""; let filterHTML = "";
data.columns.find((item) => { data.columns.find((item) => {
if (item.id === filter.column) { if (item.id === filter.column) {
const filterValue = (filter.value && filter.value[item.type] && filter.value[item.type].content) ? filter.value[item.type].content : ""; let filterValue = ""
filterHTML += `<span data-type="setFilter" data-coltype="${item.type}" data-op="${filter.operator}" data-value="${filterValue}" class="b3-chip${filterValue ? " b3-chip--primary" : ""}"> if (filter.operator === "Is empty") {
filterValue = ": " + window.siyuan.languages.filterOperatorIsEmpty
} else if (filter.operator === "Is not empty") {
filterValue = ": " + window.siyuan.languages.filterOperatorIsNotEmpty
} else if (filter.value?.number?.content && ["=", "!=", ">", "<", ">=", "<="].includes(filter.operator)) {
filterValue = ` ${filter.operator} ${filter.value.number.content}`
} else if (filter.value?.text?.content && ["=", "Contains"].includes(filter.operator)) {
filterValue = `: ${filter.value.text.content}`
} else if (filter.value?.text?.content && ["!=", "Does not contains"].includes(filter.operator)) {
filterValue = `Not ${filter.value.text.content}`
} else if (filter.value?.text?.content && "Starts with" === filter.operator) {
filterValue = `: ${window.siyuan.languages.filterOperatorStartsWith} ${filter.value.text.content}`
} else if (filter.value?.text?.content && "Ends with" === filter.operator) {
filterValue = `: ${window.siyuan.languages.filterOperatorEndsWith} ${filter.value.text.content}`
}
filterHTML += `<span data-type="setFilter" class="b3-chip${filterValue ? " b3-chip--primary" : ""}">
<svg><use xlink:href="#${getColIconByType(item.type)}"></use></svg> <svg><use xlink:href="#${getColIconByType(item.type)}"></use></svg>
<span class="fn__ellipsis">${item.name}${filterValue ? ": " + filterValue : ""}</span> <span class="fn__ellipsis">${item.name}${filterValue}</span>
</span>`; </span>`;
return true; return true;
} }
}); });
return filterHTML; return filterHTML;
}; };
data.filters.forEach((item: IAVFilter) => { data.filters.forEach((item: IAVFilter) => {
html += `<button class="b3-menu__item" draggable="true" data-id="${item.column}"> html += `<button class="b3-menu__item" draggable="true" 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>

View file

@ -349,19 +349,17 @@ export const openMenuPanel = (protyle: IProtyle,
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (type === "setFilter") { } else if (type === "setFilter") {
const colType = target.getAttribute("data-coltype") as TAVCol; data.filters.find((item: IAVFilter) => {
setFilter({ if (item.column === target.parentElement.parentElement.dataset.id) {
filter: { setFilter({
operator: target.dataset.op as TAVFilterOperator, filter: item,
column: target.parentElement.parentElement.dataset.id, protyle,
value: { data,
[colType]: {content: target.dataset.value} target
} });
}, return true;
protyle, }
data, })
target
});
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (type === "newCol") { } else if (type === "newCol") {
@ -475,7 +473,7 @@ export const openMenuPanel = (protyle: IProtyle,
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (type === "removeSelectCell") { } else if (type === "removeSelectCell") {
removeSelectCell(protyle, data, options, target); removeSelectCell(protyle, data, options, target.parentElement);
event.stopPropagation(); event.stopPropagation();
break; break;
} }

View file

@ -478,10 +478,10 @@ export const getSelectHTML = (data: IAV, options: { cellElement: HTMLElement })
if (cell.id === cellId && cell.value) { if (cell.id === cellId && cell.value) {
if (colData.type === "mSelect") { if (colData.type === "mSelect") {
cell.value.mSelect?.forEach((item: { content: string, color: string }) => { cell.value.mSelect?.forEach((item: { content: string, color: string }) => {
selectedHTML += `<div class="b3-chip" data-type="removeSelectCell" 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="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>`; 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>`;
}); });
} else if (cell.value.select.content) { } else if (cell.value.select.content) {
selectedHTML += `<div class="b3-chip" data-type="removeSelectCell" data-content="${cell.value.select.content}" style="background-color:var(--b3-font-background${cell.value.select.color});color:var(--b3-font-color${cell.value.select.color})">${cell.value.select.content}<svg class="b3-chip__close" data-type="remove-option"><use xlink:href="#iconCloseRound"></use></svg></div>`; selectedHTML += `<div class="b3-chip b3-chip--middle" data-content="${cell.value.select.content}" style="background-color:var(--b3-font-background${cell.value.select.color});color:var(--b3-font-color${cell.value.select.color})">${cell.value.select.content}<svg class="b3-chip__close" data-type="removeSelectCell"><use xlink:href="#iconCloseRound"></use></svg></div>`;
} }
return true; return true;
} }

View file

@ -857,6 +857,8 @@ interface IAVFilter {
operator: TAVFilterOperator, operator: TAVFilterOperator,
value: { value: {
[key in TAVCol]?: IAVCellValue [key in TAVCol]?: IAVCellValue
} & {
mSelect?: { content: string, color: string }[]
}, },
} }