From 56b19bac1d680efdc362adbfe64dbdea81276f8f Mon Sep 17 00:00:00 2001 From: Timothy Mugo Date: Tue, 12 May 2026 13:32:47 +0300 Subject: [PATCH 1/6] fix (TCDIZM-364): fix configuration fields not showing in daata filter --- .../blocks/filter/BlockEdit.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js b/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js index b0f8c26b6..d2a771ed1 100644 --- a/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js +++ b/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js @@ -254,7 +254,7 @@ class BlockEdit extends BlockEditWithAPIMetadata { } - {app != 'csv' && this.state.filters && + {app && app !== 'csv' && } - {app == 'csv' && this.state.filters && + {app && app === 'csv' && setAttributes({ param })} @@ -321,7 +321,7 @@ class BlockEdit extends BlockEditWithAPIMetadata { help={__('How to determine the default value.')} /> - {defaultValueCriteria == DEFAULT_VALUE_INPUT && + {defaultValueCriteria === DEFAULT_VALUE_INPUT && setAttributes({ defaultValues })} help={__("Manually specified default values.")} @@ -338,7 +338,7 @@ class BlockEdit extends BlockEditWithAPIMetadata { onChange={(filterType) => { setAttributes({ filterType: filterType, isRange: filterType == "range" }) }} - options={app == 'csv' ? [{ + options={app === 'csv' ? [{ label: "Multi select", value: "multi-select" }, { label: "Single select", value: "single-select" }, { @@ -369,7 +369,7 @@ class BlockEdit extends BlockEditWithAPIMetadata { /> } - {app != 'csv' && + {app !== 'csv' && - {filterType == "multi-select" && <> + {filterType === "multi-select" && <> Date: Tue, 12 May 2026 13:39:48 +0300 Subject: [PATCH 2/6] fix (TCDIZM-364): show filter configuration section while metadata loads - Display "Select Filter" section immediately when app is selected instead of waiting for filters to load - Add loading state ("Loading filter options...") while API metadata is being fetched - Add null/undefined checks for this.state.filters to prevent errors during loading - Apply fixes to both non-API and CSV filter sections - Guard DataFilters component rendering with filters existence check This fixes the issue where Zambia blocks had no filter configuration options visible on initial load, making the filter appear useless until the user changed the app. Ethiopia worked because it had a default app pre-configured. --- .../blocks/filter/BlockEdit.js | 1299 ++++++++++------- 1 file changed, 761 insertions(+), 538 deletions(-) diff --git a/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js b/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js index d2a771ed1..62e0aad51 100644 --- a/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js +++ b/plugins/wp-react-blocks-plugin/blocks/filter/BlockEdit.js @@ -1,576 +1,799 @@ -import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; -import { Panel, PanelBody, PanelRow, SelectControl, TextControl, ToggleControl, Button } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { BlockEditWithAPIMetadata } from '@devgateway/dvz-wp-commons' -import { isSupersetAPI } from '@devgateway/dvz-wp-commons'; +import { InspectorControls, useBlockProps } from "@wordpress/block-editor"; +import { + Panel, + PanelBody, + PanelRow, + SelectControl, + TextControl, + ToggleControl, + Button, +} from "@wordpress/components"; +import { __ } from "@wordpress/i18n"; +import { BlockEditWithAPIMetadata } from "@devgateway/dvz-wp-commons"; +import { isSupersetAPI } from "@devgateway/dvz-wp-commons"; import { useEffect } from "react"; -import { DataFilters } from '@devgateway/dvz-wp-commons'; -const DEFAULT_VALUE_INPUT = 'DEFAULT_VALUE_INPUT' -const LOWEST_VALUE = 'LOWEST_VALUE' -const HIGHEST_VALUE = 'HIGHEST_VALUE' +import { DataFilters } from "@devgateway/dvz-wp-commons"; +const DEFAULT_VALUE_INPUT = "DEFAULT_VALUE_INPUT"; +const LOWEST_VALUE = "LOWEST_VALUE"; +const HIGHEST_VALUE = "HIGHEST_VALUE"; const CategoricalFilter = ({ value, index, items, onUpdateFilterValue }) => { - if (items) { - const sortedItems = items.sort(function (a, b) { - if (a.position !== undefined && b.position !== undefined) { - return a.position - b.position - } - - let aValue = a.value ? a.value.toLowerCase() : ""; - let bValue = b.value ? b.value.toLowerCase() : ""; - return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; - - }); - - return sortedItems.map(v => -1} - onChange={e => { - onUpdateFilterValue(v.id, index) - }} />) - } else { - return null; - } -} - -const DefaultSelection = ({ defaultValues, items, filterType, onToggle, onSelect }) => { - if (!items) { - return null; - } - + if (items) { const sortedItems = items.sort(function (a, b) { - if (a.position !== undefined && b.position !== undefined && a.position !== b.position) { - return a.position - b.position - } + if (a.position !== undefined && b.position !== undefined) { + return a.position - b.position; + } - let aValue = a.value ? a.value.toLowerCase() : ""; - let bValue = b.value ? b.value.toLowerCase() : ""; - return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; + let aValue = a.value ? a.value.toLowerCase() : ""; + let bValue = b.value ? b.value.toLowerCase() : ""; + return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; }); - const defaultsArr = (defaultValues || '').toString().split(',').map(v => v.trim()).filter(v => v.length > 0); + return sortedItems.map((v) => ( + + {" "} + -1} + onChange={(e) => { + onUpdateFilterValue(v.id, index); + }} + /> + + )); + } else { + return null; + } +}; + +const DefaultSelection = ({ + defaultValues, + items, + filterType, + onToggle, + onSelect, +}) => { + if (!items) { + return null; + } + + const sortedItems = items.sort(function (a, b) { + if ( + a.position !== undefined && + b.position !== undefined && + a.position !== b.position + ) { + return a.position - b.position; + } - if (filterType === 'multi-select') { - return ( - <> - {sortedItems.map(v => { - const idStr = typeof v.id === 'boolean' ? (v.id ? 'true' : 'false') : String(v.id); - const checked = defaultsArr.indexOf(idStr) > -1; - return ( - - onToggle(v.id)} - /> - - ) - })} - - ) - } else if (filterType === 'single-select') { - const options = [{ label: __('None'), value: '' }, ...sortedItems.map(v => ({ label: v.value, value: (typeof v.id === 'boolean' ? (v.id ? 'true' : 'false') : String(v.id)) }))]; - const current = defaultsArr.length > 0 ? defaultsArr[0] : ''; - return ( + let aValue = a.value ? a.value.toLowerCase() : ""; + let bValue = b.value ? b.value.toLowerCase() : ""; + return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; + }); + + const defaultsArr = (defaultValues || "") + .toString() + .split(",") + .map((v) => v.trim()) + .filter((v) => v.length > 0); + + if (filterType === "multi-select") { + return ( + <> + {sortedItems.map((v) => { + const idStr = + typeof v.id === "boolean" + ? v.id + ? "true" + : "false" + : String(v.id); + const checked = defaultsArr.indexOf(idStr) > -1; + return ( - + onToggle(v.id)} + /> - ) - } else { - return null; - } -} + ); + })} + + ); + } else if (filterType === "single-select") { + const options = [ + { label: __("None"), value: "" }, + ...sortedItems.map((v) => ({ + label: v.value, + value: + typeof v.id === "boolean" ? (v.id ? "true" : "false") : String(v.id), + })), + ]; + const current = defaultsArr.length > 0 ? defaultsArr[0] : ""; + return ( + + + + ); + } else { + return null; + } +}; class BlockEdit extends BlockEditWithAPIMetadata { - constructor(props) { - super(props); - this.iframe = React.createRef(); - this.updateHiddenFilters = this.updateHiddenFilters.bind(this) - //this.onFilterChange = this.onFilterChange.bind(this) - this.items = this.items.bind(this) - this.updateDefaultValues = this.updateDefaultValues.bind(this) - this.selectDefaultValue = this.selectDefaultValue.bind(this) - - // Add a key to force iframe reload on attribute changes - this.state = { ...(this.state || {}), iframeReloadKey: 0 } + constructor(props) { + super(props); + this.iframe = React.createRef(); + this.updateHiddenFilters = this.updateHiddenFilters.bind(this); + //this.onFilterChange = this.onFilterChange.bind(this) + this.items = this.items.bind(this); + this.updateDefaultValues = this.updateDefaultValues.bind(this); + this.selectDefaultValue = this.selectDefaultValue.bind(this); + + // Add a key to force iframe reload on attribute changes + this.state = { ...(this.state || {}), iframeReloadKey: 0 }; + } + + updateHiddenFilters(value, idx) { + const { + attributes: { hiddenFilters }, + setAttributes, + } = this.props; + if (hiddenFilters.indexOf(value) > -1) { + setAttributes({ + hiddenFilters: hiddenFilters.filter((item) => item !== value), + }); + } else { + setAttributes({ hiddenFilters: [...hiddenFilters, value] }); } - - updateHiddenFilters(value, idx) { - const { attributes: { hiddenFilters }, setAttributes } = this.props - if (hiddenFilters.indexOf(value) > -1) { - setAttributes({ hiddenFilters: hiddenFilters.filter(item => item !== value) }) - } else { - setAttributes({ hiddenFilters: [...hiddenFilters, value] }) - } + } + + items(type) { + const allCategories = this.state.categories; + const values = allCategories + ? allCategories.filter((c) => c.type === type) + : []; + const cat = values.length > 0 ? values[0] : null; + let items = []; + if (type === "Boolean") { + items = [ + { value: "Yes", id: true }, + { value: "No", id: false }, + ]; + } else if (cat) { + items = cat.items; } - - items(type) { - const allCategories = this.state.categories - const values = allCategories ? allCategories.filter(c => c.type === type) : [] - const cat = values.length > 0 ? values[0] : null - let items = [] - if (type === 'Boolean') { - items = [{ "value": "Yes", id: true }, { "value": "No", id: false }] - } else if (cat) { - items = cat.items - } - - return items - + return items; + } + + componentDidUpdate(prevProps, prevState, snapshot) { + super.componentDidUpdate(prevProps, prevState, snapshot); + const { attributes, setAttributes } = this.props; + const prevAttributes = prevProps.attributes || {}; + if ( + prevAttributes.defaultValues !== attributes.defaultValues || + prevAttributes.filterType !== attributes.filterType || + prevAttributes.param !== attributes.param || + prevAttributes.app !== attributes.app || + prevAttributes.defaultValueCriteria !== attributes.defaultValueCriteria || + prevAttributes.defaultTopNEnabled !== attributes.defaultTopNEnabled || + prevAttributes.defaultTopNCount !== attributes.defaultTopNCount + ) { + this.setState({ iframeReloadKey: (this.state.iframeReloadKey || 0) + 1 }); } - componentDidUpdate(prevProps, prevState, snapshot) { - super.componentDidUpdate(prevProps, prevState, snapshot) - const { attributes, setAttributes } = this.props - const prevAttributes = prevProps.attributes || {} - if ( - prevAttributes.defaultValues !== attributes.defaultValues || - prevAttributes.filterType !== attributes.filterType || - prevAttributes.param !== attributes.param || - prevAttributes.app !== attributes.app || - prevAttributes.defaultValueCriteria !== attributes.defaultValueCriteria || - prevAttributes.defaultTopNEnabled !== attributes.defaultTopNEnabled || - prevAttributes.defaultTopNCount !== attributes.defaultTopNCount - ) { - this.setState({ iframeReloadKey: (this.state.iframeReloadKey || 0) + 1 }) - } - - if (attributes && attributes.filterType === 'single-select' && attributes.defaultTopNEnabled && attributes.defaultTopNCount > 1) { - setAttributes({ defaultTopNCount: 1 }) - } + if ( + attributes && + attributes.filterType === "single-select" && + attributes.defaultTopNEnabled && + attributes.defaultTopNCount > 1 + ) { + setAttributes({ defaultTopNCount: 1 }); } - - updateDefaultValues(value) { - const { attributes: { defaultValues }, setAttributes } = this.props - const arr = (defaultValues || '').toString().split(',').map(v => v.trim()).filter(v => v.length > 0) - const valStr = typeof value === 'boolean' ? (value ? 'true' : 'false') : String(value) - if (arr.indexOf(valStr) > -1) { - const updated = arr.filter(v => v !== valStr).join(',') - setAttributes({ defaultValues: updated }) - } else { - const updated = [...arr, valStr].join(',') - setAttributes({ defaultValues: updated }) - } + } + + updateDefaultValues(value) { + const { + attributes: { defaultValues }, + setAttributes, + } = this.props; + const arr = (defaultValues || "") + .toString() + .split(",") + .map((v) => v.trim()) + .filter((v) => v.length > 0); + const valStr = + typeof value === "boolean" ? (value ? "true" : "false") : String(value); + if (arr.indexOf(valStr) > -1) { + const updated = arr.filter((v) => v !== valStr).join(","); + setAttributes({ defaultValues: updated }); + } else { + const updated = [...arr, valStr].join(","); + setAttributes({ defaultValues: updated }); } - - selectDefaultValue(value) { - const { setAttributes } = this.props - setAttributes({ defaultValues: value }) + } + + selectDefaultValue(value) { + const { setAttributes } = this.props; + setAttributes({ defaultValues: value }); + } + + render() { + const { + isSelected, + setAttributes, + attributes: { + group, + placeHolder, + param, + app, + csvValue, + isRange, + allLabel, + alphabeticalSort, + ascOrder, + noneLabel, + startLabel, + endLabel, + useSingleColumn, + enableTextSearch, + filterType, + defaultValues, + showNoDataOption, + defaultValueCriteria, + hiddenFilters, + allNoneSameBehaviour, + autoApply, + closeOnSelect, + useFilterItems, + dvzProxyDatasetId, + defaultTopNEnabled, + defaultTopNCount, + parentFilter, + }, + } = this.props; + + const iframeStyles = { + height: "65px", + width: "100%", + border: "none", + overflow: "hidden", + }; + const selectedFilters = this.state.filters + ? this.state.filters.filter( + (f) => f.param == param && f.type != "Boolean", + ) + : null; + const filterAnyType = this.state.filters + ? this.state.filters.filter((f) => f.param == param) + : null; + + const filter = + selectedFilters && selectedFilters.length > 0 ? selectedFilters[0] : null; + const datasets = [{ label: "Select Dataset", value: "0" }]; + if (this.state.datasets) { + this.state.datasets.forEach((d) => { + datasets.push({ label: d.label, value: d.id }); + }); } - render() { - const { - isSelected, setAttributes, attributes: { - group, - placeHolder, - param, - app, - csvValue, - isRange, - allLabel, - alphabeticalSort, - ascOrder, - noneLabel, - startLabel, - endLabel, - useSingleColumn, - enableTextSearch, - filterType, - defaultValues, - showNoDataOption, - defaultValueCriteria, - hiddenFilters, - allNoneSameBehaviour, - autoApply, - closeOnSelect, - useFilterItems, - dvzProxyDatasetId, - defaultTopNEnabled, - defaultTopNCount, - parentFilter - } - } = this.props; - - const iframeStyles = { height: '65px', 'width': '100%', border: 'none', 'overflow': 'hidden' } - const selectedFilters = this.state.filters ? this.state.filters.filter(f => f.param == param && f.type != 'Boolean') : null - const filterAnyType = this.state.filters ? this.state.filters.filter(f => f.param == param) : null - - const filter = selectedFilters && selectedFilters.length > 0 ? selectedFilters[0] : null - const datasets = [{ label: 'Select Dataset', value: '0' }] - if (this.state.datasets) { - this.state.datasets.forEach(d => { - datasets.push({ label: d.label, value: d.id }) - }) - } - - return ([isSelected && ( - - - - setAttributes({ group })} - help={__('Internal name for this filter group.')} - /> - - - - - { - setAttributes({ app: app, hiddenFilters: [] }) - }} - options={this.state.apps} - help={__('Select the API application source.')} - /> - - - {isSupersetAPI(app, this.state.apps) && - - - { - setAttributes({ - dvzProxyDatasetId: newDatasetId, - dimension1: 'none', - dimension2: 'none' - - }) - this.setState({ dimensions: [], measures: [], filters: [], categories: [] }) - // this.loadMetadataForSuperset(app, newDatasetId) - }} - options={datasets} - help={__('Select the dataset from the API.')} - /> - - } - - - {app && app !== 'csv' && - - { - if (param != '') { - const type = this.state.filters.filter(f => f.param === param)[0].type - setAttributes({ param, type, hiddenFilters: [], defaultValues: "" }) - } else { - setAttributes({ param: "", type: "", hiddenFilters: [], defaultValues: "" }) - } - }} - help={__('Select the main filter parameter.')} - /> - - - - - - { - if (parentFilter && parentFilter !== "") { - const parentFilterObj = this.state.filters.find(f => f.value === parentFilter); - if (parentFilterObj) { - setAttributes({ parentFilter, parentFilterParam: parentFilterObj.param }); - } - } else { - setAttributes({ parentFilter: "", parentFilterParam: "" }); - } - }} /> - - - } - {app && app === 'csv' && - - setAttributes({ param })} - help={__("The column name in the CSV.")} - > - - - setAttributes({ csvValue })} - help={__("Comma separated values.")} - > - - - { - setAttributes({ defaultValueCriteria: defaultValueCriteria }) - }} - options={[{ - value: DEFAULT_VALUE_INPUT, label: 'Enter default value' - }, { value: LOWEST_VALUE, label: 'Lowest value in filter data' }, { - value: HIGHEST_VALUE, label: 'Highest value in filter data' - }]} - help={__('How to determine the default value.')} - /> - - {defaultValueCriteria === DEFAULT_VALUE_INPUT && - setAttributes({ defaultValues })} - help={__("Manually specified default values.")} - > - } - - - } - + return [ + isSelected && ( + + + + + setAttributes({ group })} + help={__("Internal name for this filter group.")} + /> + + + + + { + setAttributes({ app: app, hiddenFilters: [] }); + }} + options={this.state.apps} + help={__("Select the API application source.")} + /> + + + {isSupersetAPI(app, this.state.apps) && ( + + { + setAttributes({ + dvzProxyDatasetId: newDatasetId, + dimension1: "none", + dimension2: "none", + }); + this.setState({ + dimensions: [], + measures: [], + filters: [], + categories: [], + }); + // this.loadMetadataForSuperset(app, newDatasetId) + }} + options={datasets} + help={__("Select the dataset from the API.")} + /> + + )} + + + {app && app !== "csv" && ( + + {this.state.filters && ( + <> - { - setAttributes({ filterType: filterType, isRange: filterType == "range" }) - }} - options={app === 'csv' ? [{ - label: "Multi select", - value: "multi-select" - }, { label: "Single select", value: "single-select" }, { - label: "Range", - value: "range" - }] : [{ label: "Multi select", value: "multi-select" }, { - label: "Single select", - value: "single-select" - }, { label: "Range", value: "range" }]} - help={__('Display as multi-select, single-select, or range.')} - /> + { + if (param != "") { + const type = this.state.filters.filter( + (f) => f.param === param, + )[0].type; + setAttributes({ + param, + type, + hiddenFilters: [], + defaultValues: "", + }); + } else { + setAttributes({ + param: "", + type: "", + hiddenFilters: [], + defaultValues: "", + }); + } + }} + help={__("Select the main filter parameter.")} + /> - {isRange && - setAttributes({ startLabel })} - help={__('Label for the start of the range.')} - /> - } - {isRange && - setAttributes({ endLabel })} - help={__('Label for the end of the range.')} - /> - } - - {app !== 'csv' && - - setAttributes({ useFilterItems: !useFilterItems, filters: [], hiddenFilters: [] })} /> - - setAttributes({ useFilterItems: !useFilterItems, filters: [], hiddenFilters: [] })} /> + { + if (parentFilter && parentFilter !== "") { + const parentFilterObj = this.state.filters.find( + (f) => f.value === parentFilter, + ); + if (parentFilterObj) { + setAttributes({ + parentFilter, + parentFilterParam: parentFilterObj.param, + }); + } + } else { + setAttributes({ + parentFilter: "", + parentFilterParam: "", + }); + } + }} + /> - {useFilterItems && + + )} + + )} + {app && app === "csv" && ( + + + setAttributes({ param })} + help={__("The column name in the CSV.")} + > + + + setAttributes({ csvValue })} + help={__("Comma separated values.")} + > + + + { + setAttributes({ + defaultValueCriteria: defaultValueCriteria, + }); + }} + options={[ + { + value: DEFAULT_VALUE_INPUT, + label: "Enter default value", + }, + { + value: LOWEST_VALUE, + label: "Lowest value in filter data", + }, + { + value: HIGHEST_VALUE, + label: "Highest value in filter data", + }, + ]} + help={__("How to determine the default value.")} + /> + + {defaultValueCriteria === DEFAULT_VALUE_INPUT && ( + + + setAttributes({ defaultValues }) + } + help={__("Manually specified default values.")} + > + + )} + + )} + + + { + setAttributes({ + filterType: filterType, + isRange: filterType == "range", + }); + }} + options={ + app === "csv" + ? [ + { + label: "Multi select", + value: "multi-select", + }, + { label: "Single select", value: "single-select" }, + { + label: "Range", + value: "range", + }, + ] + : [ + { label: "Multi select", value: "multi-select" }, + { + label: "Single select", + value: "single-select", + }, + { label: "Range", value: "range" }, + ] + } + help={__("Display as multi-select, single-select, or range.")} + /> + + + {isRange && ( + + setAttributes({ startLabel })} + help={__("Label for the start of the range.")} + /> + + )} + {isRange && ( + + setAttributes({ endLabel })} + help={__("Label for the end of the range.")} + /> + + )} + + {app !== "csv" && ( + + + + setAttributes({ + useFilterItems: !useFilterItems, + filters: [], + hiddenFilters: [], + }) } - {!useFilterItems && - {(selectedFilters || []).map((f, index) => { - return ( - ) - })} - + /> + + + + setAttributes({ + useFilterItems: !useFilterItems, + filters: [], + hiddenFilters: [], + }) } - } - {app != 'csv' && !isRange && filterAnyType && filterAnyType.length > 0 && ( - - - { - if (!defaultTopNEnabled) { - setAttributes({ defaultTopNEnabled: true, defaultTopNCount: filterType === 'single-select' ? 1 : (defaultTopNCount || 1) }) - } else { - setAttributes({ defaultTopNEnabled: false }) - } - }} - help={__('Enable selecting the first N items by default.')} - /> - - {defaultTopNEnabled && ( - - { - const n = parseInt(val, 10); - if (filterType === 'single-select') { - setAttributes({ defaultTopNCount: 1 }) - } else { - setAttributes({ defaultTopNCount: isNaN(n) ? 0 : n }) - } - }} - help={filterType === 'single-select' ? __('Single-select caps Top N to 1.') : __('Number of items to preselect when enabled.')} - /> - - )} - {!defaultTopNEnabled && ( - - )} - + /> + + {useFilterItems && ( + )} - - - setAttributes({ placeHolder })} - help={__('Placeholder text shown when no selection is made.')} - /> - - {!isRange && - setAttributes({ allLabel })} - help={__('Label for the "Select All" option.')} - /> - } - {!isRange && - setAttributes({ noneLabel })} - help={__('Label for the "Deselect All" option.')} - /> - } - - - - setAttributes({ alphabeticalSort: !alphabeticalSort })} - help={__("Sort items alphabetically.")} - /> - - - setAttributes({ ascOrder: !ascOrder })} - help={__("Sort in ascending order.")} - /> - - - setAttributes({ useSingleColumn: !useSingleColumn })} - help={__("Force single column layout for dropdown items.")} - /> - - - setAttributes({ enableTextSearch: !enableTextSearch })} - help={__("Allow users to search within the dropdown.")} + {!useFilterItems && ( + + {(selectedFilters || []).map((f, index) => { + return ( + - + ); + })} + + )} + + )} + {app != "csv" && + !isRange && + filterAnyType && + filterAnyType.length > 0 && ( + + + { + if (!defaultTopNEnabled) { + setAttributes({ + defaultTopNEnabled: true, + defaultTopNCount: + filterType === "single-select" + ? 1 + : defaultTopNCount || 1, + }); + } else { + setAttributes({ defaultTopNEnabled: false }); + } + }} + help={__( + "Enable selecting the first N items by default.", + )} + /> + + {defaultTopNEnabled && ( - setAttributes({ showNoDataOption: !showNoDataOption })} - help={__("Show a message when filter list is empty is empty.")} - /> + { + const n = parseInt(val, 10); + if (filterType === "single-select") { + setAttributes({ defaultTopNCount: 1 }); + } else { + setAttributes({ + defaultTopNCount: isNaN(n) ? 0 : n, + }); + } + }} + help={ + filterType === "single-select" + ? __("Single-select caps Top N to 1.") + : __("Number of items to preselect when enabled.") + } + /> - {filterType === "multi-select" && <> - - setAttributes({ closeOnSelect: !closeOnSelect })} - help={__("Automatically close dropdown after selection.")} - /> - - - setAttributes({ allNoneSameBehaviour: !allNoneSameBehaviour })} - help={__("Treat 'All' and 'None' selections identically.")} - /> - - } - - - - - setAttributes({ autoApply: !autoApply })} - help={__("Automatically apply filter changes without a submit button.")} - /> - - - + )} + {!defaultTopNEnabled && ( + + )} - - - ), - - (
- - {this.state.react_ui_url && ( -