Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .claude/rules/frontend-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ paths: "openmetadata-ui/src/main/resources/ui/**/*.{ts,tsx}"
Applies to UI `*.{ts,tsx}`. Styling/tokens are in `frontend-styling.md`; component-library choice in
`component-library.md`; strings/i18n in `i18n.md`; Playwright in `frontend-playwright.md`. For the
**formatting procedure** invoke the `ui-checkstyle` skill — do not hand-edit formatting.
Compliant reference: `openmetadata-ui/src/main/resources/ui/src/components/ActivityFeed/ActivityFeedCardNew/ActivityFeedcardNew.component.tsx`
with its interface in a sibling `*.interface.ts`; forms reference
`openmetadata-ui/src/main/resources/ui/docs/formutils.md`.
**Folder structure and file naming for new code:
`openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md`** — read it before creating any new
file. Forms reference `openmetadata-ui/src/main/resources/ui/docs/formutils.md`.

## Component patterns

- **File naming**: components `ComponentName.component.tsx`, interfaces `ComponentName.interface.ts`
(props interfaces live in the `.interface.ts` file). *(Adherence is partial across the tree; follow
it for new files.)*
- **Folder structure**: layers stay top-level (`components/`, `pages/`, `rest/`, `utils/`, `hooks/`);
inside each, group by `domain/feature/` — `components/governance/glossary/GlossaryList/`. Domains:
`discovery`, `governance`, `observability`, `insights`, `platform`; cross-cutting features
(`lineage`, `data-contract`, `entity`, `activity-feed`) sit at the domain level, not inside one.
- **File naming (new code)**: one stem, suffix = role — `GlossaryList.tsx`, `.types.ts`, `.utils.ts`,
`.constants.ts`, `.style.less`, `.test.tsx`, `.mock.ts`. Pure logic goes in `*.utils.ts` (no React,
no JSX) so it is testable without rendering.
*(Legacy uses `.component.tsx`/`.interface.ts` — don't rename; the suffix marks migration status.)*
- **No `index.ts` barrel** inside a component folder — `no-internal-barrel-imports` reports it.
- **Functional components only** — no class components.
- **State**: `useState` with proper typing; multiple loading states as one object
(`useState<Record<string, boolean>>({})`).
Expand Down
26 changes: 22 additions & 4 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,27 @@ make unit_ingestion_dev_env # For Python changes

**IMPORTANT: When reviewing UI pull requests, you MUST follow the comprehensive guidelines in [/openmetadata-ui/UI_PR_REVIEW_GUIDELINES.md](../openmetadata-ui/UI_PR_REVIEW_GUIDELINES.md) and [/openmetadata-ui/src/main/resources/ui/playwright/PLAYWRIGHT_DEVELOPER_HANDBOOK.md](../openmetadata-ui/src/main/resources/ui/playwright/PLAYWRIGHT_DEVELOPER_HANDBOOK.md)**

**Folder structure and file naming are specified in
[/openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md](../openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md)**
— consult it for any newly added file under `ui/src/`.

#### Structure & Naming
- ✅ **REQUIRE**: new files placed as `<layer>/<domain>/<feature>/` — layers are `components/`,
`pages/`, `rest/`, `utils/`, `hooks/`; domains are `discovery`, `governance`, `observability`,
`insights`, `platform`. Cross-cutting features (`lineage`, `data-contract`, `entity`,
`activity-feed`) sit at the domain level.
- ✅ **REQUIRE**: new files named with one stem + role suffix — `GlossaryList.tsx`, `.types.ts`,
`.utils.ts`, `.constants.ts`, `.style.less`, `.test.tsx`, `.mock.ts`
- ❌ **REJECT**: an `index.ts` barrel inside a component folder (`no-internal-barrel-imports`)
- ⚠️ **DO NOT** ask for existing `.component.tsx` / `.interface.ts` files to be renamed — the suffix
marks migration status

### Critical UI Standards to Enforce

#### Type Safety (Zero Tolerance)
- ❌ **REJECT**: Any use of `any` type in TypeScript
- ✅ **REQUIRE**: Proper type imports from `generated/` or `@rjsf/utils`
- ✅ **REQUIRE**: Defined interfaces for all component props in `.interface.ts` files
- ✅ **REQUIRE**: Defined types for all component props `.types.ts` for new files, `.interface.ts` in legacy ones

#### Internationalization (Zero Tolerance)
- ❌ **REJECT**: Any hardcoded string literals in UI components
Expand All @@ -599,9 +614,12 @@ make unit_ingestion_dev_env # For Python changes
- ✅ **REQUIRE**: Navigation with `useNavigate`, not direct history manipulation

#### File Naming (Must Follow)
- ✅ **REQUIRE**: Components named as `ComponentName.component.tsx`
- ✅ **REQUIRE**: Interfaces named as `ComponentName.interface.ts`
- ✅ **REQUIRE**: Custom hooks prefixed with `use` and placed in `src/hooks/`
- ✅ **REQUIRE**: new files use one stem + role suffix — `GlossaryList.tsx`, `GlossaryList.types.ts`,
`GlossaryList.utils.ts`, `GlossaryList.constants.ts`, `GlossaryList.style.less`,
`GlossaryList.test.tsx`, `GlossaryList.mock.ts`
- ⚠️ **DO NOT** ask for existing `.component.tsx` / `.interface.ts` files to be renamed — the suffix
marks migration status
- ✅ **REQUIRE**: Custom hooks prefixed with `use` and placed in `src/hooks/<domain>/`

### PR Review Checklist

Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ on functionality over education. Do not add unnecessary blank lines between pros
for repositories, Factory/Registry for dispatch, Strategy/Adapter/Observer, the ingestion
Source→Sink pipeline, …) with the canonical class to copy each from. Extend the established pattern
rather than inventing a parallel one.
- `openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md` — **the UI folder structure and file
naming spec.** Read before creating any new file under `openmetadata-ui/.../ui/src/`. Layers stay
top-level (`components/`, `pages/`, `rest/`, `utils/`, `hooks/`) and are grouped inside by
`domain/feature/`; new files use one stem with a role suffix (`GlossaryList.tsx`, `.types.ts`,
`.utils.ts`, `.test.tsx`). Legacy `.component.tsx`/`.interface.ts` files stay as they are.

### Skills (invoke by name; procedures, not rules)

Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@

| Doc | Purpose | Read when | Modified | Freshness |
|---|---|---|---|---|
| `openmetadata-ui/src/main/resources/ui/DEVELOPER_HANDBOOK.md` | **UI folder structure + file naming spec.** Layers (`components/`, `pages/`, `rest/`, `utils/`, `hooks/`) stay top-level, grouped inside by `domain/feature/`; five domains (`discovery`, `governance`, `observability`, `insights`, `platform`) with cross-cutting features at the domain level. New files use one stem + role suffix (`GlossaryList.tsx`, `.types.ts`, `.utils.ts`, `.test.tsx`); legacy uses `.component.tsx`/`.interface.ts`. Also covers imports, barrels, routing and state locations | **Before creating any new file under `ui/src/`**, or when deciding where code belongs | 2026-08-21 | CURRENT |
| `openmetadata-ui/src/main/resources/ui/specs/` | **Machine-readable design system** (41 files). `README.md` declares two stacks — **go-forward = UntitledUI + Tailwind (`tw:`)**, **legacy (deprecated) = Ant Design + Less** — plus `foundations/*` (color, spacing, typography, radius, elevation, motion), `tokens/*` (Tailwind-utility + master token reference), `untitled/*` (go-forward component specs), and legacy `components/*` | **Before writing or modifying any UI code** — start at `specs/README.md`, then the `foundations`/`tokens` and the `untitled/<component>.md` (or legacy `components/*`) spec for what you touch | 2026-07-27 | CURRENT ⁶ |
| `openmetadata-ui/src/main/resources/ui/docs/colors.md` | Semantic color-token system (`tw:bg-primary`, `tw:text-fg-*`, `tw:border-*`) with light/dark values + the mandatory `ring`→`border` migration (§2.3.1) | Before writing/reviewing any Tailwind color class or dark-mode styling, or when tempted to use `ring-*` or a raw hex | 2026-07-23 | CURRENT |
| `openmetadata-ui/src/main/resources/ui/docs/formutils.md` | The modern react-hook-form + react-aria form stack (`FieldProp`, `getField`/`FormFields`/`HookForm`) vs the legacy antd `@utils/formUtils` API | Before building/modifying any UI form — which API to use, and wiring to `useFormDrawerWithHook` + a pure transform | 2026-07-15 | CURRENT |
Expand All @@ -95,4 +96,4 @@

---

*Not indexed:* `docs/harness-audit/` exists in the working tree but is **untracked** (working audit notes, intentionally out of version control), so it is not part of the committed knowledge base.

Check warning on line 99 in docs/index.md

View workflow job for this annotation

GitHub Actions / harness-integrity

[dead-reference] path does not resolve: `docs/harness-audit/`

Check warning on line 99 in docs/index.md

View workflow job for this annotation

GitHub Actions / harness-integrity

[dead-reference] path does not resolve: `docs/harness-audit/`
19 changes: 15 additions & 4 deletions openmetadata-ui/UI_PR_REVIEW_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@ This document outlines the standards and best practices that must be followed wh

- [ ] **No `any` types**: Code must never use `any` type - use proper types or `unknown` with type guards
- [ ] **Proper type imports**: All types imported from existing definitions (e.g., `RJSFSchema` from `@rjsf/utils`, types from `generated/`)
- [ ] **Interface definitions**: All component props have defined interfaces in `.interface.ts` files
- [ ] **Prop types defined**: All component props have declared types — `.types.ts` for new files, `.interface.ts` in legacy ones
- [ ] **Type assertions**: Avoid type assertions unless absolutely necessary and well-justified
- [ ] **Discriminated unions**: Use discriminated unions for action types and state variants

## React Component Standards

### File Structure and Naming
- [ ] **Component files**: Named as `ComponentName.component.tsx`
- [ ] **Interface files**: Named as `ComponentName.interface.ts`

Full spec: [`src/main/resources/ui/DEVELOPER_HANDBOOK.md`](src/main/resources/ui/DEVELOPER_HANDBOOK.md).

- [ ] **Placement**: new files live at `<layer>/<domain>/<feature>/` — layers are `components/`,
`pages/`, `rest/`, `utils/`, `hooks/`; domains are `discovery`, `governance`, `observability`,
`insights`, `platform`. Cross-cutting features (`lineage`, `data-contract`, `entity`,
`activity-feed`) sit at the domain level
- [ ] **New file names**: one stem + role suffix — `GlossaryList.tsx`, `.types.ts`, `.utils.ts`,
`.constants.ts`, `.style.less`, `.test.tsx`, `.mock.ts`
- [ ] **Legacy files untouched**: do not ask for existing `.component.tsx` / `.interface.ts` files to
be renamed — the suffix marks migration status
- [ ] **No `index.ts` barrel** inside a component folder (`no-internal-barrel-imports`)
- [ ] **Business logic in `*.utils.ts`**: pure functions, no React or JSX, unit-testable without rendering
- [ ] **Functional components only**: No class components
- [ ] **Custom hooks**: Prefixed with `use`, placed in `src/hooks/`, return typed objects
- [ ] **Custom hooks**: Prefixed with `use`, placed in `src/hooks/<domain>/`, return typed objects

### Component Implementation
- [ ] **State management**: Uses `useState` with proper typing
Expand Down
Loading
Loading