Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 23, 2025

Describe your changes:

Migrated MUI form components from openmetadata-ui to openmetadata-ui-core-components as pure, reusable components without custom business logic.

Created in @openmetadata/ui-core-components:

  • MUITextField - Pure MUI TextField wrapper (no sanitization, memoized)
  • MUIForm - HTML form wrapper using MUI Box (properly typed with ComponentProps)
  • MUIFormItem - FormControl wrapper for labels/helper text

Updated openmetadata-ui:

  • Changed formUtils.tsx to import MUITextField from core library
  • Moved sanitization logic inline for TEXT_MUI/PASSWORD_MUI field types
  • Removed local MUITextField component
  • Added test coverage for MUI field types

Before:

// In openmetadata-ui/src/components/common/MUITextField/MUITextField.tsx
const MUITextField: FC<MUITextFieldProps> = ({ value, onChange, ...props }) => {
  const handleChange = (e) => {
    const sanitizedValue = getSanitizeContent(e.target.value); // Business logic in component
    onChange?.(e);
  };
  return <TextField onChange={handleChange} {...props} />;
};

After:

// In openmetadata-ui-core-components (pure component)
const MUITextField: FC<MUITextFieldProps> = ({ size = 'small', ...props }) => {
  return <TextField fullWidth size={size} {...props} />;
};

// In formUtils.tsx (business logic in consumer)
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
  const sanitizedValue = getSanitizeContent(e.target.value);
  onChange?.({ ...e, target: { ...e.target, value: sanitizedValue } });
};

Type Safety:

  • MUIForm uses proper TypeScript typing with ComponentProps<'form'> for event handlers
  • No as any type casts, following ESLint rules
  • All components are fully typed without type assertions

Sanitization preserved in formUtils for security. Form.Item retained for Ant Design state management. No breaking changes.

Type of change:

  • Improvement

Checklist:

  • I have read the CONTRIBUTING document.
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added tests around the new logic.
Original prompt

Objective

Move MUI components used in form utils from openmetadata-ui to openmetadata-ui-core-components as pure components without custom logic. Start with TextField and create new MUI wrappers for Form and FormItem (not using Ant Design wrappers).

Tasks

1. Create Pure MUI Components in openmetadata-ui-core-components

Create the following components in openmetadata-ui-core-components/src/main/resources/ui/src/components/:

A. MUITextField Component

Path: openmetadata-ui-core-components/src/main/resources/ui/src/components/MUITextField/MUITextField.tsx

  • Create a pure TextField component wrapping @mui/material/TextField
  • Remove the sanitization logic (no getSanitizeContent)
  • Keep only essential props:
    • variant?: 'outlined' | 'filled' | 'standard'
    • size?: 'small' | 'medium'
    • All standard TextField props from MUI
  • Default size to 'small'
  • Use memo for optimization
  • Add proper TypeScript interface extending TextFieldProps from @mui/material

Example structure:

import { TextField, TextFieldProps } from '@mui/material';
import { FC, memo } from 'react';

interface MUITextFieldProps extends Omit<TextFieldProps, 'variant' | 'size'> {
  variant?: 'outlined' | 'filled' | 'standard';
  size?: 'small' | 'medium';
}

const MUITextField: FC<MUITextFieldProps> = ({
  size = 'small',
  ...props
}) => {
  return (
    <TextField
      fullWidth
      size={size}
      {...props}
    />
  );
};

export default memo(MUITextField);

B. MUIForm Component

Path: openmetadata-ui-core-components/src/main/resources/ui/src/components/MUIForm/MUIForm.tsx

  • Create a pure form wrapper component (NOT using Ant Design's Form)
  • Use native HTML <form> element with MUI styling
  • Support common form props:
    • onSubmit
    • onReset
    • children
    • className
    • id
  • Add MUI Box wrapper for consistent styling

Example structure:

import { Box, BoxProps } from '@mui/material';
import { FC, FormEvent, ReactNode } from 'react';

interface MUIFormProps extends Omit<BoxProps, 'component' | 'onSubmit'> {
  onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
  onReset?: (event: FormEvent<HTMLFormElement>) => void;
  children: ReactNode;
}

const MUIForm: FC<MUIFormProps> = ({
  onSubmit,
  onReset,
  children,
  ...boxProps
}) => {
  return (
    <Box
      component="form"
      onSubmit={onSubmit}
      onReset={onReset}
      {...boxProps}
    >
      {children}
    </Box>
  );
};

export default MUIForm;

C. MUIFormItem Component

Path: openmetadata-ui-core-components/src/main/resources/ui/src/components/MUIFormItem/MUIFormItem.tsx

  • Create a pure form field wrapper component
  • Handle label, error display, helper text
  • Support form field layout
  • NOT using Ant Design's Form.Item

Example structure:

import { Box, FormControl, FormHelperText } from '@mui/material';
import { FC, ReactNode } from 'react';

interface MUIFormItemProps {
  label?: ReactNode;
  error?: boolean;
  helperText?: ReactNode;
  required?: boolean;
  children: ReactNode;
  className?: string;
  id?: string;
  fullWidth?: boolean;
}

const MUIFormItem: FC<MUIFormItemProps> = ({
  label,
  error,
  helperText,
  required,
  children,
  className,
  id,
  fullWidth = true,
}) => {
  return (
    <FormControl
      fullWidth={fullWidth}
      error={error}
      required={required}
      className={className}
      id={id}
    >
      {label}
      {children}
      {helperText && (
        <FormHelperText>{helperText}</FormHelperText>
      )}
    </FormControl>
  );
};

export default MUIFormItem;

2. Export Components from Core Library

Update openmetadata-ui-core-components/src/main/resources/ui/src/components/index.ts:

export { default as MUITextField } from './MUITextField/MUITextField';
export { default as MUIForm } from './MUIForm/MUIForm';
export { default as MUIFormItem } from './MUIFormItem/MUIFormItem';
export * from './Button';
export * from './checkbox-icons';
export { default as SnackbarContent } from './SnackbarContent';

3. Update openmetadata-ui to Use Core Components

A. Update MUITextField import in formUtils

File: openmetadata-ui/src/main/resources/ui/src/utils/formUtils.tsx

Change line 53 from:

import MUITextField from '../components/common/MUITextField/MUITextField';

To:

import { MUITextField } from '@openmetadata/ui-core-components';

B. Create a wrapper component (optional) for sanitization

Path: openmetadata-ui/src/main/resources/ui/src/components/common/MUITextField/MUITextFieldWithSanitization.tsx

If sanitization is still needed in specific places:

import { MUITextField } from '@openmetadata/ui-core-components';
import { ChangeEvent, FC, useCallback } from 'react';
import { getSanitizeContent } from '../../../utils/sanitize.utils';

// Wrapper that adds sanitization on top of pure MUITextField
const MUITextFieldWithSanitization: F...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

Copilot AI and others added 4 commits December 23, 2025 07:49
Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copilot AI changed the title [WIP] Move MUI components from openmetadata-ui to openmetadata-ui-core-components Move MUI form components to core library as pure components Dec 23, 2025
Copilot AI requested a review from karanh37 December 23, 2025 07:57
@karanh37
Copy link
Contributor

@copilot We shouldn't be using any in the code, follow the eslint rules.
Also update password field

Co-authored-by: karanh37 <33024356+karanh37@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 23, 2025

@copilot We shouldn't be using any in the code, follow the eslint rules.
Also update password field

Fixed in commit 6ee1e83. Replaced as any type casts with proper ComponentProps<'form'> typing for onSubmit and onReset handlers. Both TEXT_MUI and PASSWORD_MUI fields already have consistent implementations with sanitization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants