Skip to content

[ESLint 2a] Fix @typescript-eslint/no-use-before-define + promote to error - #31952

Open
ShaileshParmar11 wants to merge 1 commit into
mainfrom
ShaileshParmar11/eslint-02a-use-before-define
Open

[ESLint 2a] Fix @typescript-eslint/no-use-before-define + promote to error#31952
ShaileshParmar11 wants to merge 1 commit into
mainfrom
ShaileshParmar11/eslint-02a-use-before-define

Conversation

@ShaileshParmar11

@ShaileshParmar11 ShaileshParmar11 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What

Chunk 2a of the type-safety split. The original bundled type-safety PR (#30990) covered no-explicit-any + no-non-null-assertion + no-use-before-define (~369 violations). Per the one-rule-per-PR approach, it's being split into per-rule chunks; this is the first (smallest).

Clears all 15 @typescript-eslint/no-use-before-define violations and promotes the rule warnerror so CI blocks any regression.

How (behavior-preserving)

  • 6 safe reorders — hoisted pure helpers (formatLatencyAverage, getDefaultScheduleFromPeriod, hasPopulatedTableRows, GlossaryTermDomainWidget, a useRef) above their first use; no intervening deps moved.
  • 9 documented disablesactiveTab (derived below from tabs), loadDomains (useCallback defined below), and two mutual-recursion pairs (scheduleNextPoll/pollOnce, handleSpecialServiceConfig/handleDatabaseConfigSource) — all runtime-safe (referenced only inside callbacks that run after definition), can't be reordered without moving the error.

Verified

  • no-use-before-define = 0 across all src; the rule is now error.
  • No new errors introduced. 240 tests pass across the 12 touched suites.

Closes #31951. Part of epic #30977.

Note: main currently has 10 pre-existing jsx-a11y errors in two test-mock files (from a race with #30989's merge) — fixed separately in #31948, independent of this PR.

Greptile Summary

The PR promotes @typescript-eslint/no-use-before-define from warning to error after resolving the current violations.

  • Reorders pure utilities, a component declaration, and an unconditional ref above their first uses.
  • Adds targeted suppressions for deferred callbacks and intentional mutual recursion.
  • Makes future violations fail UI lint checks.

Confidence Score: 5/5

The PR appears safe to merge because the declaration reorders and targeted lint suppressions preserve the existing runtime behavior.

The moved declarations remain pure or unconditional, deferred callbacks cannot execute before initialization in the inspected flows, and no concrete lint, build, or runtime regression remains.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/eslint.config.mjs Promotes the TypeScript use-before-definition rule to an error without changing its options.
openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/TestCaseFormDrawer.tsx Moves an unconditional drawer callback ref above the JSX closure that captures it, preserving hook and callback behavior.
openmetadata-ui/src/main/resources/ui/src/components/Domain/DomainDetails/DomainDetails.component.tsx Documents intentional deferred references to the rendered active tab without changing navigation logic.
openmetadata-ui/src/main/resources/ui/src/components/DomainListing/components/DomainTreeView.tsx Documents the deferred reference between selection handling and the later child-domain loader.
openmetadata-ui/src/main/resources/ui/src/pages/AuditLogsPage/AuditLogsPage.tsx Documents intentional mutual recursion in the self-scheduling export polling loop.
openmetadata-ui/src/main/resources/ui/src/utils/ApplicationUtils.tsx Moves the pure latency formatter above its first invocation without modifying its implementation.
openmetadata-ui/src/main/resources/ui/src/utils/CronExpressionUtils.ts Moves the pure default-schedule helper above its caller without changing schedule selection.
openmetadata-ui/src/main/resources/ui/src/utils/CustomProperty.utils.ts Moves the table-row predicate above serialization code that invokes it, preserving validation semantics.
openmetadata-ui/src/main/resources/ui/src/utils/GlossaryTerm/GlossaryTermWidgetUtils.tsx Moves the glossary domain widget component above the widget factory that references it.
openmetadata-ui/src/main/resources/ui/src/utils/ServiceConnectionDetailsUtils.tsx Documents intentional mutual recursion in service-configuration traversal without altering the traversal.

Reviews (1): Last reviewed commit: "style(ui): fix @typescript-eslint/no-use..." | Re-trigger Greptile

…rror

Clear all 15 no-use-before-define violations: 6 safe reorders (hoist pure
helpers above first use) + 9 documented disables for mutual-recursion /
derived-below cases that can't be reordered without moving the error.
Promote the rule warn->error so CI blocks regressions.

Chunk 2a of the type-safety split (was bundled PR #30990). 0 new errors,
240 tests pass. Part of epic #30977.
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

✅ PR checks passed

The linked issue has a description and all required Shipping project fields set. Thanks!

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Aug 24, 2026
@gitar-bot

gitar-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown
Code Review ✅ Approved

Fixes 15 @typescript-eslint/no-use-before-define violations and promotes the rule from warning to error in the ESLint configuration. No issues found.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ UI Checkstyle passed — lint findings in changed files

🔍 ESLint findings in this PR's files — 0 error(s), 41 warning(s)

Errors block the build. Warnings do not yet — they are rules whose backlog is still
being worked down, listed so this PR does not add to it. See docs/ui-code-quality-gate.md.

0 error(s), 41 warning(s) across 8 changed file(s).

Count Rule
16 react-hooks/exhaustive-deps
9 sonarjs/cyclomatic-complexity
9 sonarjs/no-duplicate-string
2 openmetadata-imports/no-lower-layer-page-imports
2 openmetadata-imports/no-internal-barrel-imports
2 sonarjs/expression-complexity
1 openmetadata-imports/review-sequential-api-calls
All findings
Location Rule Message
🟡 src/components/DataQuality/AddDataQualityTest/components/TestCaseFormDrawer.tsx:39:1 openmetadata-imports/no-lower-layer-page-imports Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here.
🟡 src/components/DataQuality/AddDataQualityTest/components/TestCaseFormDrawer.tsx:93:29 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 17 which is greater than 10 authorized.","cost":7,"secondaryLocations":[{"line":93,"column":28,"endLine":93,"endColumn"
🟡 src/components/DataQuality/AddDataQualityTest/components/TestCaseFormDrawer.tsx:190:9 openmetadata-imports/review-sequential-api-calls Review these sequential API requests. If they are independent, start them together with Promise.all/Promise.allSettled; keep sequencing only when data-dependent
🟡 src/components/DataQuality/AddDataQualityTest/components/TestCaseFormDrawer.tsx:241:55 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 4 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:118:1 openmetadata-imports/no-internal-barrel-imports Import the internal module directly instead of its index barrel so unrelated siblings do not enter the bundle graph.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:156:24 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 29 which is greater than 10 authorized.","cost":19,"secondaryLocations":[{"line":156,"column":23,"endLine":156,"endColu
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:263:13 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 3 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:322:6 react-hooks/exhaustive-deps React Hook useCallback has missing dependencies: 'domain.fullyQualifiedName' and 't'. Either include them or remove the dependency array.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:324:9 react-hooks/exhaustive-deps The 'handleTabChange' function makes the dependencies of useCallback Hook (at line 433) change on every render. To fix this, wrap the definition of 'handleTabCh
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:324:9 react-hooks/exhaustive-deps The 'handleTabChange' function makes the dependencies of useCallback Hook (at line 606) change on every render. To fix this, wrap the definition of 'handleTabCh
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:397:26 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 4 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:415:13 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 3 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:571:26 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 5 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:721:5 react-hooks/exhaustive-deps React Hook useCallback has missing dependencies: 'closeSubDomainDrawer' and 't'. Either include them or remove the dependency array.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:826:29 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 4 times.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:930:6 react-hooks/exhaustive-deps React Hook useMemo has missing dependencies: 'activeTab', 'addSubDomain', 'getEntityFeedCount', 'isVersionsView', 'onAddDataProduct', 'onDeleteSubDomain', and '
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:961:6 react-hooks/exhaustive-deps React Hook useEffect has missing dependencies: 'fetchActiveAnnouncement', 'fetchActivityCount', 'fetchDataProducts', 'fetchDomainAssets', 'fetchDomainPermission
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:974:6 react-hooks/exhaustive-deps React Hook useMemo has an unnecessary dependency: 'isSubDomain'. Either exclude it or remove the dependency array.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:982:5 react-hooks/exhaustive-deps React Hook useMemo has a missing dependency: 'tabs'. Either include it or remove the dependency array.
🟡 src/components/Domain/DomainDetails/DomainDetails.component.tsx:982:6 react-hooks/exhaustive-deps React Hook useMemo has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:204:5 react-hooks/exhaustive-deps React Hook useCallback has missing dependencies: 'loadDomains' and 'selectDomain'. Either include them or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:229:13 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 3 times.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:230:23 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 4 times.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:237:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'selectDomain'. Either include it or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:462:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'updateNested'. Either include it or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:478:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'loadRootDomains'. Either include it or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:490:6 react-hooks/exhaustive-deps React Hook useEffect has missing dependencies: 'hasActiveFilters', 'loadDomains', and 'searchDomain'. Either include them or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:594:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'updateDomainInHierarchy'. Either include it or remove the dependency array.
🟡 src/components/DomainListing/components/DomainTreeView.tsx:765:9 sonarjs/expression-complexity Reduce the number of conditional operators (4) used in the expression (maximum allowed 3).
🟡 src/components/DomainListing/components/DomainTreeView.tsx:792:31 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 15 which is greater than 10 authorized.","cost":5,"secondaryLocations":[{"line":792,"column":30,"endLine":792,"endColum
🟡 src/components/DomainListing/components/DomainTreeView.tsx:948:6 react-hooks/exhaustive-deps React Hook useMemo has a missing dependency: 'handleAction'. Either include it or remove the dependency array.
🟡 src/pages/AuditLogsPage/AuditLogsPage.tsx:30:1 openmetadata-imports/no-internal-barrel-imports Import the internal module directly instead of its index barrel so unrelated siblings do not enter the bundle graph.
🟡 src/pages/AuditLogsPage/AuditLogsPage.tsx:86:26 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 16 which is greater than 10 authorized.","cost":6,"secondaryLocations":[{"line":86,"column":25,"endLine":86,"endColumn"
🟡 src/pages/AuditLogsPage/AuditLogsPage.tsx:421:20 sonarjs/no-duplicate-string Define a constant instead of duplicating this literal 3 times.
🟡 src/utils/CronExpressionUtils.ts:204:3 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 12 which is greater than 10 authorized.","cost":2,"secondaryLocations":[{"line":204,"column":2,"endLine":204,"endColumn
🟡 src/utils/CustomProperty.utils.ts:34:3 sonarjs/expression-complexity Reduce the number of conditional operators (6) used in the expression (maximum allowed 3).
🟡 src/utils/CustomProperty.utils.ts:164:12 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 14 which is greater than 10 authorized.","cost":4,"secondaryLocations":[{"line":164,"column":11,"endLine":164,"endColum
🟡 src/utils/CustomProperty.utils.ts:310:15 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 24 which is greater than 10 authorized.","cost":14,"secondaryLocations":[{"line":310,"column":14,"endLine":310,"endColu
🟡 src/utils/GlossaryTerm/GlossaryTermWidgetUtils.tsx:19:1 openmetadata-imports/no-lower-layer-page-imports Pages are route-level composition modules. Move the shared implementation/type to a lower layer instead of importing a page from here.
🟡 src/utils/ServiceConnectionDetailsUtils.tsx:136:39 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 14 which is greater than 10 authorized.","cost":4,"secondaryLocations":[{"line":136,"column":38,"endLine":136,"endColum
🟡 src/utils/ServiceConnectionDetailsUtils.tsx:221:21 sonarjs/cyclomatic-complexity {"message":"Function has a complexity of 13 which is greater than 10 authorized.","cost":3,"secondaryLocations":[{"line":221,"column":20,"endLine":221,"endColum

Fix locally (fast - only checks files changed in this branch):

make ui-checkstyle-changed

@github-actions

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 67%
67.07% (80432/119921) 51.46% (49259/95715) 52.44% (14708/28045)

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

✅ Playwright Results — workflow succeeded

Validated commit 73ece11cc72a8a5f6a745525e5c9591af5c09eb8 in Playwright run 32720688230, attempt 1.

✅ 992 passed · ❌ 0 failed · 🟡 1 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky

Performance

Blocking targets: ✅ met · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 50m 20s

⏱️ Max setup 4m 19s · max shard execution 19m 38s · max shard-job elapsed before upload 22m 30s · reporting 6s

🌐 215.04 requests/attempt · 2.56 app boots/UI scenario · 39.39% common-shard skew

Optimization targets still in progress:

  • Common shard skew was 39.39% (convergence target: at most 15%).
  • Browser traffic was 215.04 requests per attempt (convergence target: fewer than 200).
  • Application boot ratio was 2.56 per UI scenario (2670 boots / 1044 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
✅ Shard chromium-01 132 0 0 0 0 0
✅ Shard chromium-02 166 0 0 0 0 0
🟡 Shard chromium-03 176 0 1 0 0 0
✅ Shard chromium-04 140 0 0 0 0 0
✅ Shard chromium-05 163 0 0 0 0 0
✅ Shard data-asset-rules-01 61 0 0 0 0 0
✅ Shard domain-isolation-01 16 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 26 0 0 0 0 0
✅ Shard ingestion-01 32 0 0 0 0 0
✅ Shard reindex-01 6 0 0 0 0 0
✅ Shard search-01 11 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0
🟡 1 flaky test(s) (passed on retry)
  • Pages/DataProductCertificationFilter.spec.tsfiltering by a certification narrows the listing (shard chromium-03, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

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 UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ESLint 2a] @typescript-eslint/no-use-before-define

1 participant