feat(query-builder): migrate QueryBuilderWidgetV1 from antd to core-components - #29849
feat(query-builder): migrate QueryBuilderWidgetV1 from antd to core-components#29849chirag-madlani wants to merge 93 commits into
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nput Replace @react-awesome-query-builder/antd widgets with core-components. Two new widgets using Input component: - OMTextWidget: string input values - OMNumberWidget: numeric input with type="number" All tests passing, TypeScript strict compilation verified. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…support Implements Task 3 of the query builder migration from Ant Design to openmetadata-ui-core-components. Provides async-capable single-select widget wrapping core Select component. Includes handling for both static list values and async fetch callbacks, with proper TypeScript typing. - Converts listValues (array or object format) to SelectItemType[] - Supports async data loading via asyncFetch callback - Properly disables when readonly - Fully tested with 2 core test cases (render + disabled state) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ith async support Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…and ButtonGroup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…m core-component widgets Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ate button renderers to core-components - AdvancedSearchClassBase: replace BasicConfig value with OMConfig from QueryBuilderOMConfig; BasicConfig is now type-only - AdvancedSearchUtils: renderAdvanceSearchButtons uses Button (core), X and Trash01 icons from @untitledui/icons; removes @ant-design/icons and antd Button imports - QueryBuilderUtils: renderQueryBuilderFilterButtons and renderJSONLogicQueryBuilderButtons use Button (core) and X/Plus from @untitledui/icons; removes antd and @ant-design/icons imports Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…and button renderers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-components, clean up LESS - Replace antd Card/Row/Col/Skeleton/Alert/Button/Divider/Typography with @openmetadata/ui-core-components equivalents - Replace @ant-design/icons InfoCircleOutlined with @untitledui/icons InfoCircle - Remove all .ant-* selectors from LESS; replace Less variable refs with CSS custom properties (--color-*) - Update skeleton test selector from .ant-skeleton.ant-skeleton-active to [aria-hidden="true"] (core Skeleton uses aria-hidden) - Update padding class test from .ant-col/.p-t-sm to .tw\\:pt-2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated 7 test files to import from @react-awesome-query-builder/ui instead of @react-awesome-query-builder/antd, and replaced AntdConfig with BasicConfig. Applied UI checkstyle (organize-imports, lint:fix, prettier) on all modified test files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…invalid type cast, wire JSONLogicSearchClassBase to OMConfig - OMDateWidget: replace getInputType(operator) with fieldType prop — operator values like "equal"/"less" never contain "time"/"datetime"; fieldType is the correct discriminant - OMDateWidget: fix tw:bg-disabled_subtle → tw:bg-disabled-subtle (underscore → dash matches CSS token) - OMNumberWidget: remove impossible `as number & null` intersection cast; Number(v) is already number - JSONLogicSearchClassBase: import OMConfig and set baseConfig = OMConfig so JSON-logic query builder uses OM-styled widgets consistently with AdvancedSearchClassBase Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ocument native input in OMDateWidget
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
| async (search: string) => { | ||
| if (!asyncFetch) { | ||
| return; | ||
| } | ||
| const result = await asyncFetch(search); | ||
| setAllItems( | ||
| (result.values as ListItem[]).map((item) => ({ | ||
| id: String(item.value), | ||
| label: String(item.title ?? item.value), | ||
| })) | ||
| ); | ||
| }, | ||
| [asyncFetch] | ||
| ); |
There was a problem hiding this comment.
The multi-select adapter always calls asyncFetch(search) and discards the returned hasMore state. Fetchers such as enum/custom-property autocomplete accept an offset and can return more pages, so values after the first page can never be loaded or selected in the query builder.
| useEffect(() => { | ||
| const currentIds = new Set(selectedItems.items.map((i) => i.id)); | ||
| const targetIds = new Set(valueArray); | ||
|
|
||
| for (const id of targetIds) { | ||
| if (!currentIds.has(id)) { | ||
| const item = allItems.find((i) => i.id === id); | ||
| if (item) { | ||
| selectedItems.append(item); | ||
| } | ||
| } | ||
| } | ||
| for (const item of selectedItems.items) { | ||
| if (!targetIds.has(item.id)) { | ||
| selectedItems.remove(item.id); | ||
| } | ||
| } | ||
| }, [valueArray.join(',')]); |
There was a problem hiding this comment.
When a saved async multiselect filter is rendered, allItems is initially empty, so the sync effect cannot append chips for the current valueArray. After the async options arrive, the effect does not rerun for the same value, leaving persisted owner, tag, tier, or custom-property filters visually unselected even though the tree still contains their values.
| value={value !== null && value !== undefined ? String(value) : ''} | ||
| onChange={(v: string) => setValue(v === '' ? null : Number(v))} |
There was a problem hiding this comment.
Intermediate Numbers Store NaN
Number(v) is stored for every non-empty number-input string. Browser number inputs can emit intermediate values like 1e, -, or ., which convert to NaN; that value then enters the query tree and can produce an invalid or non-matching generated filter.
| value={value !== null && value !== undefined ? String(value) : ''} | |
| onChange={(v: string) => setValue(v === '' ? null : Number(v))} | |
| value={value !== null && value !== undefined ? String(value) : ''} | |
| onChange={(v: string) => { | |
| if (v === '') { | |
| setValue(null); | |
| return; | |
| } | |
| const nextValue = Number(v); | |
| if (Number.isFinite(nextValue)) { | |
| setValue(nextValue); | |
| } | |
| }} |
The OMSelectWidget aggregate autocomplete calls the ES aggregate endpoint which requires entities to be indexed. When the test ran immediately after beforeAll created the schemas, ES hadn't finished ingesting them, so the aggregate returned empty buckets and the dropdown never showed the expected option — causing the "Database Schema" field tests to flake on first attempt but pass on retry (by which time ES had caught up). Poll the aggregate endpoint after entity creation and block until both schemas appear in the index before the test body starts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs blocked the react-aria migration E2E suite: 1. DataContractsSemanticRules: locators referenced `.ant-select` (removed with the antd migration) — dropped to just `.group--field` and `.rule--operator` so RAQB's own CSS classes are used directly. 2. selectOption async timeout: the old antd implementation waited for a loading-spinner to detach (default 60s action timeout) on every call, which incidentally polled ES until a freshly-created entity was indexed. The new react-aria version fired one `loadAsync` from the initial `fill()` and only retried the _click_, so a slow ES index returned an empty popup for the full 30 s and timed out. Fix: re-fill `optionTitle` at the start of every retry iteration (fires a fresh `onInputChange` → `loadAsync`), raise the inner `click` timeout to 3 000 ms, and raise `toPass` to 60 000 ms to match the old spinner-wait budget. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This reverts commit 61001a3.
The selectOption helper already retries for up to 30 s with toPass — each retry re-fills the combobox which triggers a fresh aggregate fetch, so the suite self-heals if ES hasn't indexed the schema yet. The beforeAll block added up to 120 s of shard overhead (2 schemas × 60 s worst-case) that timing-baseline.json doesn't capture, pushing chromium-01 past the 1500 s execution budget and timing out the shard. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Code Review
|
| Compact |
|
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source
|



Summary
@react-awesome-query-builder/antdimports with@react-awesome-query-builder/ui(API-identical, same version) across 14 production files and 8 test filesOMConfigfromBasicConfigwith new widget factories backed byopenmetadata-ui-core-components, eliminating Ant Design widget rendering inside query builder rulesQueryBuilderWidgetV1outer shell (Card, Alert, Skeleton, Divider, Typography) from antd to core-componentsAdvancedSearchUtilsandQueryBuilderUtilsfrom antdButton+@ant-design/iconsto coreButton+@untitledui/iconsNew widgets (
src/utils/queryBuilderWidgets/)OMTextWidgetInputOMNumberWidgetInput(numeric)OMSelectWidgetSelectwith async adapterOMMultiSelectWidgetMultiSelect+useListDatafromreact-statelyOMBooleanWidgetToggleOMDateWidget<input type="date/datetime-local/time">(coreDateInputis not publicly exported and requires@internationalized/dateobjects incompatible with RAQB string values)OMFieldSelectSelect(field/operator picker)OMConjsButtonGroup(AND/OR conjunction)All assembled into
src/utils/QueryBuilderOMConfig.tsxwhich exportsOMConfig.Test plan
QueryBuilderWidgetV1tests passsrc/utils/queryBuilderWidgets/)🤖 Generated with Claude Code
Greptile Summary
This PR migrates the query-builder UI from Ant Design to core components. The main changes are:
Confidence Score: 4/5
This is close, but the async multiselect paging path should be fixed before merging.
Files Needing Attention: openmetadata-ui/src/main/resources/ui/src/utils/queryBuilderWidgets/OMMultiSelectWidget.tsx
Important Files Changed
Reviews (32): Last reviewed commit: "fix unit test" | Re-trigger Greptile
Context used (3)