diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index 43e1037a2..ebba58a41 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -155,9 +155,9 @@ &__item .b3-chip { max-width: 196px; - margin: 1px 0; - padding-top: 6px; - padding-bottom: 6px; + margin: 3px 0; + padding-top: 4px; + padding-bottom: 4px; float: left; svg { diff --git a/app/src/protyle/render/av/col.ts b/app/src/protyle/render/av/col.ts index dce97edfe..e14b1a058 100644 --- a/app/src/protyle/render/av/col.ts +++ b/app/src/protyle/render/av/col.ts @@ -2,7 +2,7 @@ import {hasClosestBlock} from "../../util/hasClosest"; import {Menu} from "../../../plugin/Menu"; import {transaction} from "../../wysiwyg/transaction"; import {fetchPost} from "../../../util/fetch"; -import {getCellValue, setFilter} from "./filter"; +import {genCellValue, setFilter} from "./filter"; export const getColIconByType = (type: TAVCol) => { switch (type) { @@ -156,7 +156,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: HTMLElement, cellEl filter = { column: colId, operator: "Contains", - value: getCellValue(type, "") + value: genCellValue(type, "") }; avData.view.filters.push(filter); transaction(protyle, [{ diff --git a/app/src/protyle/render/av/filter.ts b/app/src/protyle/render/av/filter.ts index 26fb38b09..091c4ec0b 100644 --- a/app/src/protyle/render/av/filter.ts +++ b/app/src/protyle/render/av/filter.ts @@ -5,44 +5,71 @@ import {getColIconByType} from "./col"; import {setPosition} from "../../../util/setPosition"; import {objEquals} from "../../../util/functions"; -export const getCellValue = (colType: TAVCol, value: string) => { +export const genCellValue = (colType: TAVCol, value: string | { + content: string, + color: string +}[]) => { let cellValue: IAVCellValue; - if (colType === "number") { - if (value) { + if (typeof value === "string") { + if (colType === "number") { + if (value) { + cellValue = { + type: colType, + number: { + content: parseFloat(value), + isNotEmpty: true + } + }; + } else { + cellValue = { + type: colType, + number: { + isNotEmpty: false + } + }; + } + } else if (colType === "text") { cellValue = { type: colType, - number: { - content: parseFloat(value), - isNotEmpty: true + text: { + content: value } }; - } else { - cellValue = { + } else if (colType === "mSelect" || colType === "select") { + return cellValue = { type: colType, - number: { - isNotEmpty: false - } + mSelect: [{ + content: value, + color: "" + }] }; } - } else if (colType === "text") { - cellValue = { + return cellValue; + } + if (colType === "mSelect" || colType === "select") { + return cellValue = { type: colType, - text: { - content: value - } - }; - } else if (colType === "mSelect" || colType === "select") { - cellValue = { - type: colType, - mSelect: [{ - content: value, - color: "" - }] + mSelect: value }; } - return cellValue; }; +const toggleEmpty = (element: HTMLElement, show: boolean) => { + const menuElement = hasClosestByClassName(element, "b3-menu") + if (menuElement) { + menuElement.querySelectorAll("input, .b3-chip").forEach(inputElement => { + const menuItemElement = hasClosestByClassName(inputElement, "b3-menu__item") + if (menuItemElement) { + if (show) { + menuItemElement.classList.remove("fn__none") + } else { + menuItemElement.classList.add("fn__none") + } + } + }) + } +} + export const setFilter = (options: { filter: IAVFilter, protyle: IProtyle, @@ -53,7 +80,22 @@ export const setFilter = (options: { const menu = new Menu("set-filter-" + options.filter.column, () => { const oldFilters = JSON.parse(JSON.stringify(options.data.view.filters)); let hasMatch = false; - const cellValue = getCellValue(options.filter.value.type, textElement?.value || ""); + let cellValue: IAVCellValue; + if (textElement) { + cellValue = genCellValue(options.filter.value.type, textElement.value); + } else { + const mSelect: { color: string, content: string }[] = [] + window.siyuan.menus.menu.element.querySelectorAll('svg').forEach(item => { + if (item.firstElementChild.getAttribute("xlink:href") === "#iconCheck") { + const chipElement = item.nextElementSibling.firstElementChild as HTMLElement + mSelect.push({ + color: chipElement.dataset.color, + content: chipElement.dataset.name + }) + } + }) + cellValue = genCellValue(options.filter.value.type, mSelect); + } const newFilter: IAVFilter = { column: options.filter.column, value: cellValue, @@ -118,6 +160,7 @@ export const setFilter = (options: { `; break; case "mSelect": + case "select": options.data.view.columns.find((column) => { if (column.id === options.filter.column) { colData = column; @@ -143,15 +186,30 @@ export const setFilter = (options: { iconHTML: "", label: `` }); - if (options.filter.value.type === "mSelect") { - // TODO + if (options.filter.value.type === "select" || options.filter.value.type === "mSelect") { colData.options.forEach((option) => { - menu.addItem({ - label: ``, - click() { - + let icon = "iconUncheck" + options.filter.value.mSelect.find((optionItem) => { + if (optionItem.content === option.name) { + icon = "iconCheck" } - }); + }) + menu.addItem({ + icon, + label: ` + ${option.name} +`, + bind(element) { + element.addEventListener("click", () => { + const useElement = element.querySelector("use") + if (useElement.getAttribute("xlink:href") === "#iconUncheck") { + useElement.setAttribute("xlink:href", "#iconCheck"); + } else { + useElement.setAttribute("xlink:href", "#iconUncheck"); + } + }) + } + }) }); } else if (options.filter.value.type === "text") { menu.addItem({ @@ -192,11 +250,7 @@ export const setFilter = (options: { }); 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") { - selectElement.parentElement.parentElement.nextElementSibling.classList.add("fn__none"); - } else { - selectElement.parentElement.parentElement.nextElementSibling.classList.remove("fn__none"); - } + toggleEmpty(selectElement, selectElement.value !== "Is empty" && selectElement.value !== "Is not empty") }); const textElement = window.siyuan.menus.menu.element.querySelector(".b3-text-field") as HTMLInputElement; if (textElement) { @@ -211,11 +265,7 @@ export const setFilter = (options: { } }); } - if (selectElement.value === "Is empty" || selectElement.value === "Is not empty") { - selectElement.parentElement.parentElement.nextElementSibling.classList.add("fn__none"); - } else { - selectElement.parentElement.parentElement.nextElementSibling.classList.remove("fn__none"); - } + toggleEmpty(selectElement, selectElement.value !== "Is empty" && selectElement.value !== "Is not empty") menu.open({x: rectTarget.left, y: rectTarget.bottom}); if (textElement) { textElement.select(); @@ -245,7 +295,7 @@ export const addFilter = (options: { icon: getColIconByType(column.type), click: () => { const oldFilters = Object.assign([], options.data.view.filters); - const cellValue = getCellValue(column.type, ""); + const cellValue = genCellValue(column.type, ""); options.data.view.filters.push({ column: column.id, operator: "Contains", diff --git a/app/src/protyle/render/av/select.ts b/app/src/protyle/render/av/select.ts index cb5e9f7cc..8e2ebab63 100644 --- a/app/src/protyle/render/av/select.ts +++ b/app/src/protyle/render/av/select.ts @@ -3,6 +3,7 @@ import {transaction} from "../../wysiwyg/transaction"; import {hasClosestByClassName} from "../../util/hasClosest"; import {confirmDialog} from "../../../dialog/confirmDialog"; import {upDownHint} from "../../../util/upDownHint"; +import {genCellValue} from "./filter"; const filterSelectHTML = (key: string, options: { name: string, color: string }[]) => { let html = ""; @@ -385,10 +386,7 @@ export const addSelectColAndCell = (protyle: IProtyle, data: IAV, options: { color: "", bgColor: "", id: Lute.NewNodeID(), - value: { - type: colData.type, - mSelect: [] - }, + value: genCellValue(colData.type, ""), valueType: colData.type } }