Skip to content

Feat/UI/refactor add domain form#26951

Open
siddhant1 wants to merge 85 commits intomainfrom
feat/ui/refactor-add-domain-form
Open

Feat/UI/refactor add domain form#26951
siddhant1 wants to merge 85 commits intomainfrom
feat/ui/refactor-add-domain-form

Conversation

@siddhant1
Copy link
Copy Markdown
Member

@siddhant1 siddhant1 commented Apr 2, 2026

Summary

Refactors the Add Domain / Sub-Domain / Data Product form onto the @openmetadata/ui-core-components stack. The form now uses HookForm, FormField, typed FieldTypes, and useFormDrawer — the ad-hoc Ant Design + RJSF pieces are gone. Shared form plumbing moves into the core components library so other forms can reuse it.

What changed

AddDomainForm (consumer)

  • New hook-form–driven component with typed DomainFormValues and a DomainFormSelectItem shape (tags / owners / experts / domainType / domains all flow through the same select contract).
  • New pure helper transformDomainFormData(formData, type, parentDomain) builds the CreateDomain or CreateDataProduct API payload: merges glossary terms into tags, packages color + iconURL into style, resolves the data-product parent-domain fallback, and strips UI-only fields.
  • Cover image upload, icon picker, color picker, and glossary tag suggestion all driven by the shared field renderer.
  • Drawer flow uses a submitAndClose helper + stable add-domain-form test-id; scroll-to-error on validation failure.
  • Icon+color row, name+displayName row, description wrapper, and CTA row now use the core Box primitive instead of raw tw:flex divs.

Core components (openmetadata-ui-core-components)

  • form-field restructured into typed, single-responsibility field renderers (color-picker-field, icon-picker-field, render-field-element, form-item-label, split form-field.types).
  • Autocomplete forwards onBlur; FormField forwards onFocus.
  • Alert guards against empty-string helperText.
  • render-field-element no longer special-cases a MULTIPLE_SELECTION_FIELD_TYPES set — callers declare multiplicity explicitly.
  • Color / icon pickers and the field wrapper now compose the core Button, Typography, and Box primitives instead of native <button> / <span> / <div> — addresses @anuj-kumary's review feedback on this PR.

Callers migrated to the new form

DomainListPage, DomainDetails, AddSubDomainModal, DataProductListPage, and both Marketplace widgets (MarketplaceDomainsWidget, MarketplaceDataProductsWidget) now invoke transformDomainFormData before POSTing.

Tests

  • New: unit tests for transformDomainFormData covering domain, sub-domain, and data-product payload shapes — tag + glossary merging, style packaging, owner / expert extraction, null domainTypeundefined, missing expert name → '', empty-collection handling, and the data-product parent-domain fallback (9 cases).
  • Playwright: DataMarketplace, DataProducts, DataProductAndSubdomains, DomainUIInteractions, Domains specs updated to target the new drawer test-ids and tag-option selectors; shared playwright/utils/domain.ts helpers adjusted.
  • AddDomainForm.test.tsx component tests updated for the new renderer and hook-form harness.

Type of change

  • Improvement

Checklist

  • I have read the CONTRIBUTING document.
  • Unit tests added for the new helper and updated for the refactor.
  • Playwright specs updated alongside the UI changes.

Summary by Gitar

  • Playwright enhancements:
    • Added comprehensive test suite for Domain asset dryRun interactions, verifying move confirmations and warning modal behavior.
    • Implemented API utility helpers in domain.ts for managing domain assets via dryRun and commit workflows.
  • Data Handling:
    • Switched from getActiveAnnouncement to getActiveAnnouncements in DomainDetails to support updated announcement entity fetching.

This will update automatically on new commits.

Siddhant and others added 2 commits April 1, 2026 17:16
Migrate AddDomainForm from Ant Design to @openmetadata/ui-core-components
using HookForm, getField, and FieldTypes. Add onFocus prop support to
AutocompleteBase, add rules prop to FormField, and export form-field
components from the core library.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Switch FieldTypes.SELECT to use Select with Select.Item children
  for proper icon/avatar/supportingText support
- Pass fontSize through SelectContext so items respect the fontSize prop
- Show colored-initial avatars for users and team icons via Avatar
- Show tag color dots using Dot component on tag options
- Replace custom glossary terms autocomplete with MUIGlossaryTagSuggestion

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@siddhant1 siddhant1 requested review from a team, chirag-madlani and karanh37 as code owners April 2, 2026 05:41
Copilot AI review requested due to automatic review settings April 2, 2026 05:41
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 2, 2026

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Domain “Add” form UI to use @openmetadata/ui-core-components + react-hook-form (instead of Ant Design Form), while introducing reusable form-field building blocks in openmetadata-ui-core-components to support the new form patterns.

Changes:

  • Refactor AddDomainForm to react-hook-form + ui-core-components fields (icon picker, color picker, tag/domain/user selectors, etc.).
  • Add a new shared form-field system to openmetadata-ui-core-components (Field, getField, FormItemLabel, FieldTypes, etc.) and export it from the components entrypoint.
  • Extend core select/autocomplete plumbing (e.g., SelectContext now includes fontSize; autocomplete can invoke an onFocus callback).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx Rebuilds the Domain/Data Product form using react-hook-form + ui-core-components fields and a custom imperative ref bridge.
openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.interface.ts Replaces AntD FormInstance with a custom DomainFormRef contract for submit/reset/validate.
openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.test.tsx Updates tests/mocks to align with the refactored form and new ref behavior.
openmetadata-ui-core-components/src/main/resources/ui/src/components/index.ts Exports the newly added form-field primitives/types.
openmetadata-ui-core-components/src/main/resources/ui/src/components/base/select/select.tsx Adds fontSize to SelectContext and provides it via SelectContext.Provider.
openmetadata-ui-core-components/src/main/resources/ui/src/components/base/select/select-item.tsx Uses fontSize from context to control item label/supporting text typography.
openmetadata-ui-core-components/src/main/resources/ui/src/components/base/form/hook-form.tsx Adds rules support to FormField props for react-hook-form validation.
openmetadata-ui-core-components/src/main/resources/ui/src/components/base/autocomplete/autocomplete.tsx Adds onFocus passthrough (used to resize popover on focus) during trigger focus.
openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/form-item-label.tsx New shared label component with required marker, tooltip, and beta badge.
openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/form-field.types.ts New shared types/enums for form fields (FieldTypes, FieldProp, etc.).
openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/form-field.tsx New implementation of Field/getField rendering for multiple input types.

Comment on lines +114 to +121
if ('current' in targetRef) {
targetRef.current = value;

return () => {
if (targetRef.current === value) {
targetRef.current = null;
}
: null;

const iconField: FieldProp = {
name: 'iconURL',
id: 'root/iconURL',
label: t('label.icon'),
muiLabel: t('label.icon'),
required: false,
type: FieldTypes.ICON_PICKER_MUI,
helperText: iconTooltipDataRender(),
props: {
'data-testid': 'icon-url',
allowUrl: true,
placeholder: t('label.icon-url'),
backgroundColor: selectedColor,
defaultIcon:
};
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syncFormRef assigns to targetRef.current, but formRef is typed as Ref<DomainFormRef> where RefObject.current is readonly under @types/react v18. This will cause a TS error and/or require unsafe mutation of a readonly ref.

Consider changing DomainFormRefProp to accept MutableRefObject<DomainFormRef | null> (and/or RefObject separately) and casting inside this branch, or using useImperativeHandle with a forwarded ref instead of mutating .current directly.

Copilot uses AI. Check for mistakes.
Comment on lines +296 to +307
const fetchDomainOptions = useCallback(async (searchText = '') => {
try {
const domains = await searchDomains(searchText, 1);
const nextOptions = domains.map((domain: any) =>
mapEntityReferenceToOption({
displayName: domain.displayName,
fullyQualifiedName: domain.fullyQualifiedName,
id: domain.id,
name: domain.name,
type: EntityType.DOMAIN,
})
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

domains.map((domain: any) => ...) introduces an any in UI code. This breaks the repo’s zero-tolerance type-safety requirement and also hides the shape expected from searchDomains().

Prefer typing the response from searchDomains() (e.g., Domain[] or a minimal interface with id/name/displayName/fullyQualifiedName) and removing the any cast.

Copilot uses AI. Check for mistakes.
Comment on lines 677 to 693
const expertsField: FieldProp = {
id: 'root/experts',
label: t('label.expert-plural'),
},
formItemProps: {
valuePropName: 'value',
trigger: 'onChange',
initialValue: [],
},
};

const createPermission = useMemo(
() =>
checkPermission(Operation.Create, ResourceEntity.GLOSSARY, permissions),
[permissions]
);

const selectedOwners =
Form.useWatch<EntityReference | EntityReference[]>('owners', form) ?? [];

const ownersList = Array.isArray(selectedOwners)
? selectedOwners
: [selectedOwners];

const expertsList = Form.useWatch<EntityReference[]>('experts', form) ?? [];

const handleFormSubmit: FormProps['onFinish'] = (formData) => {
const updatedData = omit(
formData,
'color',
'iconURL',
'glossaryTerms'
// Keep 'coverImage' - parent will extract and remove it before API call
// Don't exclude 'domains' - we need it for DataProducts
);
const style = {
color: formData.color,
iconURL: formData.iconURL,
// Don't include coverImage here - it's not uploaded yet
// Parent will add it to style after upload
name: 'experts',
placeholder: t('label.select-field', {
field: t('label.expert-plural'),
}),
props: {
filterOption: () => true,
multiple: true,
onFocus: handleUserTeamFocus,
onSearchChange: (searchText: string) =>
debouncedUserTeamSearch(searchText),
options: userTeamOptions,
},
type: FieldTypes.USER_TEAM_SELECT,
};
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

experts in CreateDomain/CreateDataProduct is defined as a list of user/login names (string[]), but the options backing expertsField (userTeamOptions) include teams. Selecting a team here will submit a team name as an expert, which is likely invalid and can break creation.

Consider fetching users-only options for the experts field (or filtering userTeamOptions by type === EntityType.USER) so only users can be selected as experts.

Copilot uses AI. Check for mistakes.
Comment on lines +155 to 178
export const SelectContext = createContext<{
size: 'sm' | 'md';
fontSize: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
}>({
size: 'sm',
fontSize: 'md',
});

const Select = ({
placeholder = 'Select',
placeholderIcon,
size = 'sm',
fontSize = 'md',
children,
items,
label,
hint,
tooltip,
className,
...rest
}: SelectProps) => {
return (
<SelectContext.Provider value={{ size }}>
<SelectContext.Provider value={{ size, fontSize }}>
<AriaSelect
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SelectContext now requires fontSize in its value shape. This is a breaking change for existing SelectContext.Provider usages that only provide { size } (e.g., Select ComboBox / Autocomplete providers), and will either fail type-checking or make fontSize undefined downstream.

To avoid regressions, update all SelectContext.Provider values to include fontSize (or change the context type to make fontSize optional with a default).

Copilot uses AI. Check for mistakes.
@siddhant1 siddhant1 added the safe to test Add this label to run secure Github workflows on PRs label Apr 2, 2026
…rm PR

Fix jsx-sort-props errors in form-field.tsx, replace `any` with `Domain`
type, use MutableRefObject to fix readonly ref assignment, add missing
fontSize to SelectContext providers, and restrict experts field to
user-only options matching original behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y modules

Split the monolithic form-field.tsx (~1290 lines) into focused files:
- fields/color-picker-field.tsx and fields/icon-picker-field.tsx for standalone field components
- render-field-element.tsx for the central field type dispatch
- form-field.tsx reduced to thin Field/FormFields wrapper (~95 lines)

Replaced Record<string, unknown> FieldPropsMap with a properly typed interface,
eliminated all `as` casts and `unknown` types, and removed the unnecessary
select normalization layer (consumers pass correctly shaped SelectItemType data).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 2, 2026 06:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.test.tsx:253

  • The refactor changes submission/validation behavior substantially, but the “should handle form submission” test doesn’t assert that onSubmit is invoked or that the payload is correctly shaped (e.g., tags/owners/experts/domains mapping, coverImage file value). Strengthen this test to populate key fields, trigger submit, and verify the exact onSubmit arguments (and formRef.validateFields() behavior if that’s part of the external contract).
  it('should handle form submission', () => {
    render(<AddDomainForm {...defaultProps} />);

    const saveButton = screen.getByTestId('save-domain');
    fireEvent.click(saveButton);

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.

Comment on lines +83 to +85
<button
aria-label={`Select color ${color}`}
aria-pressed={isSelected}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use here core component button instead of native element ?

Siddhant and others added 2 commits April 22, 2026 16:31
Addresses @anuj-kumary's review on #26951: replace native <button>,
<span>, and flex-column <div> with core-library components wherever
they fit.

- color-picker-field: swatch <button> → Button; empty-state <span> →
  Typography; outer flex <div> → Box.
- icon-picker-field: tile <button> + trigger <button> → Button; all
  user-visible <span> (fallback "?", first-letter initial, empty state,
  URL panel label) → Typography; URL-panel wrapper → Box.
- form-field: field wrapper <div> → Box.
- render-field-element: COVER_IMAGE_UPLOAD wrapper <div> → Box.
- AddDomainForm (consumer): four flex-container <div> (icon+color row,
  name+displayName row, description wrapper, CTA row) → Box.

Grid layouts, positional wrappers, and inline-flex label spans are left
as native elements — Box/Typography would change layout or DOM
semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Runs eslint/prettier autofix that CI's lint-core-components expected.
- Bumps the icon-picker dropdown to 22rem and grid gap to gap-4 so the
  6-column icon grid has visible breathing room.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.

siddhant1 and others added 2 commits April 22, 2026 17:38
Refactored AddDomainForm renders Box unconditionally and Autocomplete / Avatar / Dot in the tag-suggestion and user-team paths. The existing jest.mock of @openmetadata/ui-core-components omitted these, so every render through AddDomainFormHarness threw "Element type is invalid", failing all 11 describe('AddDomainForm') tests on SonarCloud.

Add passthrough stubs (Autocomplete with .Item, Avatar, Box, Dot) to the mock so the component tree resolves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Siddhant and others added 2 commits April 23, 2026 13:27
The first batch in this test added two siblings from a mutuallyExclusive
glossary and relied on the server rejecting the save so the UI stayed
empty and `add-tag` remained clickable for the next batch.

TreeAsyncSelectList.handleChange now drops mutex siblings client-side
once its glossaries-list fetch resolves, so only one term reaches the
server, it saves successfully, tags become non-empty, and `add-tag`
is replaced by `edit-button`. The test then times out waiting for
`add-tag`. Whether the filter kicks in depends on a race between the
dropdown's `/api/v1/glossaries?fields=mutuallyExclusive` call and the
user clicks, which is why the test sometimes passed and sometimes
timed out at 3 minutes under CI load.

Remove the mutex batch (and the now-unused glossary1/term1/term2
fixtures). The mutex flow was never actually asserted here — it was
only used as a side channel to keep tags empty. The remaining
non-mutex batch + chart-level tagging + asset verification still cover
the add/remove-assets behavior end-to-end.

Local: 5/5 passes in ~7s each (was timing out at 180s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
URL-detection for the custom-icon preview no longer lives inside the core
picker. hasCustomImage (allowUrl + non-empty value + no selectedItem) is
enough to decide whether to render the <img>; matches main's identity of
keeping image-validity rules in consumer utils, not in the picker itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 30 out of 30 changed files in this pull request and generated no new comments.

Siddhant and others added 4 commits April 23, 2026 16:47
Strip changes that weren't required by the form-library migration so the
diff against main is purely the MUI → Untitled UI swap:

- utils/IconUtils.tsx + test: restore getEntityAvatarProps to main. The
  ICON_MAP[iconURL] lookup for stored icon names is new rendering
  behaviour, not needed by the form refactor.
- AddDomainForm.component.tsx: drop the getImageDimensions helper and
  the coverImage rules.validate block. On main that size/dimension
  check lived inside MUICoverImageUpload via maxSizeMB/maxDimensions
  props — keep the same principle (backend rejects on upload), don't
  reimplement it in the form.
- playwright DomainUIInteractions.spec.ts: restore the 'Invalid@Name#Test'
  input and .ant-form-item-explain-error selector. The branch had
  swapped both the test input and the assertion target; neither was
  required by the drawer testid migration.
- playwright Glossary.spec.ts: restore to match main. The 67-line
  flaky-batch deletion is unrelated to the Add Domain form migration.
- core form-item-label.tsx / form-field.types.ts / form-field.tsx:
  drop the unused isBeta / betaLabel props — no consumer sets them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hook-form defaults color / iconURL to '', which made the submit payload
include `style: { color: '', iconURL: '' }`. Because getEntityAvatarProps
uses ?? (not ||) for the brand-600 fallback, empty strings defeated the
default and avatars rendered with no background. Strip empty values at
the submit boundary so the POST payload matches what the Ant-based form
on main produced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Untitled UI icon picker stores preset icon selections as the icon's
name (e.g. 'Bank') in entity.style.iconURL. Main's getEntityAvatarProps
only handled http/absolute-path URLs, so any stored icon name fell through
to the entity-type default — the user's picked icon never showed up in
list views, tree views, cards, or detail headers.

Look up non-URL iconURL values in ICON_MAP and render the matching icon
component as the avatar's placeholderIcon. Unknown names still fall back
to the entity-type default. Restore the two tests that cover both paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Input didn't actually violate ENTITY_NAME_REGEX (`/^((?!::).)*$/`), and
the selector targeted the old AntD error class which the HookForm
refactor removed. Use a `::` input and match the message via text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Dedupes the 14-color swatch palette between ColorPickerField and
its icon-picker sibling into a single ENTITY_PALETTE_HEX export
under @/colors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

karanh37
karanh37 previously approved these changes Apr 28, 2026
Siddhant and others added 2 commits April 28, 2026 11:15
…tyles

Use ENTITY_PALETTE_HEX directly instead of re-exporting it as
DEFAULT_COLOR_OPTIONS, and express icon display/stroke-width via Tailwind
utilities so the picker fields no longer carry an inline style object.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Siddhant and others added 2 commits April 28, 2026 11:25
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
normalizeHexColor canonicalizes hex strings to uppercase, so both sides
of every comparison were already in the same case. Replace the
.toLowerCase() pairs with plain equality (and palette.some with
palette.includes), and drop the redundant array copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented Apr 28, 2026

Code Review ✅ Approved 10 resolved / 10 findings

Refactored the domain creation form to ensure type safety, correct payload transformation, and stable event handling. All identified validation, permission, and submission issues have been successfully resolved.

✅ 10 resolved
Quality: Untyped any used for domain search response

📄 openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx:299
Line 299 uses (domain: any) in the fetchDomainOptions callback, bypassing TypeScript checks on the domain object shape. This should use the proper domain type from the API response.

Bug: validateFields returns raw form data, not CreateDomain shape

📄 openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx:493-501 📄 openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx:436-450
The validateFields method (line 493-501) is typed to return Promise<CreateDomain | CreateDataProduct> but returns form.getValues() — the raw form data with separate color, iconURL, glossaryTerms, and unprocessed experts/owners arrays. The actual transformation (combining tags + glossaryTerms, building the style object, mapping experts to name strings, etc.) only happens inside handleFormSubmit.

Currently the only caller (useFormDrawerWithRef) discards the return value when formRef.submit is present, so it works by accident. However, the type contract is violated and any future caller relying on the return value will receive malformed API payloads.

Bug: onChange callback silently dropped for Switch/Checkbox/Slider

📄 openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/render-field-element.tsx:342-345 📄 openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/render-field-element.tsx:361-364 📄 openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/render-field-element.tsx:373-376
The onChange prop callback was removed from SWITCH, CHECKBOX, and SLIDER field type handlers in renderFieldElement. While no current consumers appear to pass onChange for these field types, this is a shared component library — removing the callback without deprecation silently breaks the contract for any consumer (including external ones) that may rely on it. The other field types (e.g., text, select) still forward onChange.

Bug: DataProduct submitted with empty domains array when no domain selected

📄 openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx:460-468
When creating a DataProduct, if neither formData.domains nor parentDomain has a fullyQualifiedName, the code now submits domains: []. Previously, the domains field was only set when a value existed. While this is type-safe (domains: string[]), the API likely requires at least one domain for a DataProduct. This could result in a server-side validation error or, worse, creation of an orphaned DataProduct with no domain association.

Bug: Submit handler expects objects but autocomplete stores string IDs

📄 openmetadata-ui/src/main/resources/ui/src/components/Domain/AddDomainForm/AddDomainForm.component.tsx:442-456 📄 openmetadata-ui-core-components/src/main/resources/ui/src/components/application/form-field/render-field-element.tsx:166-180
The new autocomplete fields store only string IDs via field.onChange(selectedItem.id) (render-field-element.tsx:178), but handleFormSubmit casts form values as full objects:

  • domains (line 464): formData.domains is a UUID string, cast as EntityReference. Accessing .fullyQualifiedName returns undefined, so CreateDataProduct.domains becomes [undefined].
  • tags (line 444): formData.tags is string[] of FQNs, cast as TagLabel[]. The submitted tags will be plain strings, not TagLabel objects.
  • owners (line 447): formData.owners is string[] of UUIDs, cast as EntityReference[]. Submitted as raw strings instead of entity references.
  • experts (line 446): Same issue — item.name on a string yields undefined, so all experts become ''.

This is a fundamental mismatch introduced by switching from Ant Design's form (which stored full objects in field values) to the new autocomplete (which stores only ID strings). The submit handler needs to map IDs back to full objects using the option lists.

...and 5 more resolved from earlier reviews

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.

Comment thread openmetadata-ui/src/main/resources/ui/src/utils/IconUtils.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.