mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 09:30:14 +01:00
This commit is contained in:
parent
8cf28fcd24
commit
e1d7ab0bc1
5 changed files with 128 additions and 40 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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="<=">≤</option>
|
<option ${"<=" === options.filter.operator ? "selected" : ""} value="<=">≤</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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
app/src/types/index.d.ts
vendored
2
app/src/types/index.d.ts
vendored
|
|
@ -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 }[]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue