Modernize the frontend toolchain: Lingui 6, ESLint 9 and @dagrejs/dagre - #391
Conversation
Combines three toolchain upgrades whose lockfile changes are mutually conflicting (npm inserts their entries at the same alphabetical positions), so they ship as one change. Each part is independent in content: Lingui 5 -> 6: - .linguirc replaced by lingui.config.js (v6 removed string-based format config; po format now comes from @lingui/format-po) - i18n.loadLocaleData() calls removed (API removed in v6; plural rules come from Intl.PluralRules) from i18nLoader, enzymeHelpers and tests; the make-plural dependency is dropped with them - webpack rule relaxing fully-specified ESM resolution for node_modules (@lingui v6 is ESM-only and imports react/jsx-runtime without an extension, which react 17 cannot satisfy under strict resolution) - locale catalogs re-extracted and recompiled with the v6 toolchain; existing translations preserved (es: 1896 -> 1898 filled msgstr) ESLint 8 -> 9.39 with flat config: - eslint.config.mjs replaces .eslintrc.json/.eslintignore; the unmaintained eslint-config-airbnb and eslint-config-react-app (both capped at eslint ^8) are replaced by eslint-config-airbnb-extended; import rules move to import-x - eslint-plugin-i18next 5 -> 6 (options translated to the new schema, built-in default excludes spread in explicitly - the plugin merges options shallowly), eslint-plugin-react-hooks 4 -> 7 (the new React Compiler rules are off: the codebase predates them, ~105 sites), eslint-webpack-plugin 6 - rules newer than the airbnb@19 baseline are off for parity; formatting customizations move to @Stylistic equivalents - mechanical cleanup: import/* disable comments renamed to import-x/*, unused directives removed, three small code fixes (duplicate api import in contexts/Config.js, promise-executor return in setupTests.js, max-len directive rename in util/validators.js) - npm audit fix bumps transitive shell-quote past GHSA-w7jw-789q-3m8p - ESLint 10 is blocked: eslint-plugin-react, jsx-a11y, import-x and @babel/eslint-parser all cap at eslint ^9, and ESLint 10 removed the core formatting rules (the @Stylistic remaps here clear that hurdle in advance) dagre -> @dagrejs/dagre 3: - the maintained continuation, one import line in WorkflowUtils.js (the only consumer); the layout test now asserts geometry without library internals (the fork exposes rank/order metadata and picks sibling order within a rank differently); licenses/ui file renamed Known benign artifact: one unused eslint-disable directive warning in StatusLabel.js - the directive is required under the parallel styled-components PR's eslint-8 baseline, so it stays to keep that PR conflict-free; it can be removed after both merge.
There was a problem hiding this comment.
Pull request overview
This PR modernizes Ascender’s UI toolchain by upgrading Lingui to v6, migrating ESLint to v9 (flat config), and replacing the unmaintained dagre dependency with @dagrejs/dagre, with associated code/test and configuration updates.
Changes:
- Upgrade Lingui configuration to v6 (switch
.linguirc→lingui.config.js) and removemake-plurallocale data loading across app/tests. - Migrate ESLint to v9 flat config (
eslint.config.mjs) and update codebase eslint directives/rules to match the new plugin ecosystem (import-x,@stylistic, etc.). - Replace
dagrewith@dagrejs/dagreand update workflow layout tests to assert geometry without relying on library internals; adjust webpack to better handle ESM packages innode_modules.
Reviewed changes
Copilot reviewed 73 out of 84 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| licenses/ui/make-plural.txt | Removes license for dropped make-plural dependency. |
| licenses/ui/dagrejs-dagre.txt | Adds license for new @dagrejs/dagre dependency. |
| awx/ui/testUtils/enzymeHelpers.js | Removes Lingui plural data loading in test helpers; adjusts eslint comment usage. |
| awx/ui/testUtils/apiReusable.js | Updates eslint-disable rule name to import-x. |
| awx/ui/src/util/validators.test.js | Removes deprecated Lingui locale data loading in tests. |
| awx/ui/src/util/validators.js | Updates eslint-disable rule name to @stylistic/max-len. |
| awx/ui/src/util/lists.js | Updates eslint-disable rule name to import-x. |
| awx/ui/src/util/dates.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/util/auth.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/setupTests.js | Updates eslint rule name and reformats asyncFlush helper. |
| awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListDenyButton.js | Removes unnecessary eslint-disable for “useless fragment”. |
| awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListApproveButton.js | Removes unnecessary eslint-disable for “useless fragment”. |
| awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalList.js | Removes inline eslint disables and updates hook deps formatting. |
| awx/ui/src/screens/WorkflowApproval/shared/WorkflowApprovalUtils.test.js | Removes make-plural usage; updates Lingui activation in tests. |
| awx/ui/src/screens/User/UserTeams/UserTeamListItem.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/User/shared/index.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/screens/TopologyView/utils/useZoom__RTL.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/TopologyView/TopologyView__RTL.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/TopologyView/MeshGraph.js | Cleans up eslint disables around this usage in D3 callbacks. |
| awx/ui/src/screens/TopologyView/MeshGraph__RTL.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Visualizer.js | Narrows eslint-disable list to remaining relevant rules. |
| awx/ui/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.js | Removes unnecessary react-hooks/exhaustive-deps disable. |
| awx/ui/src/screens/Template/shared/PlaybookSelect.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Team/Team.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/screens/Team/shared/index.js | Updates eslint-disable rule name to import-x. |
| awx/ui/src/screens/Setting/shared/SharedFields.test.js | Removes deprecated Lingui locale data loading in tests. |
| awx/ui/src/screens/Organization/shared/index.js | Updates eslint-disable rule name to import-x. |
| awx/ui/src/screens/Organization/OrganizationList/OrganizationListItem.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/NotificationTemplate/constants.js | Updates eslint-disable rule name to import-x. |
| awx/ui/src/screens/Login/Login.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/screens/Job/JobOutput/useJobEvents.js | Removes file-level eslint-disable for destructuring assignment. |
| awx/ui/src/screens/Job/JobOutput/JobOutput.js | Removes file-level eslint-disable and removes inline exhaustive-deps suppression. |
| awx/ui/src/screens/Inventory/shared/Inventory.helptext.js | Removes file-level eslint-disable for destructuring assignment. |
| awx/ui/src/screens/Inventory/shared/ConstructedInventoryHint.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Inventory/InventoryList/InventoryList.js | Removes inline exhaustive-deps suppression. |
| awx/ui/src/screens/Inventory/InventoryHosts/InventoryHostItem.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventorySyncButton.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Inventory/ConstructedInventoryDetail/ConstructedInventoryDetail.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Instances/Shared/RemoveInstanceButton.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Instances/InstanceList/InstanceList.test.js | Removes make-plural usage and locale data loading in tests. |
| awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/MetadataStep.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/screens/Credential/shared/CredentialFormFields/CredentialField.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/locales/zu/messages.po | Catalog reformat/reordering consistent with updated Lingui extraction. |
| awx/ui/src/locales/zh/messages.po | Catalog reformat/reordering consistent with updated Lingui extraction. |
| awx/ui/src/locales/ko/messages.po | Catalog reformat/reordering consistent with updated Lingui extraction. |
| awx/ui/src/locales/fr/messages.po | Catalog reformat/reordering consistent with updated Lingui extraction. |
| awx/ui/src/i18nLoader.js | Removes make-plural imports and Lingui locale data loading calls. |
| awx/ui/src/contexts/Workflow.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/contexts/Kebabified.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/contexts/Config.js | Normalizes API imports and removes redundant SettingsAPI import/disable. |
| awx/ui/src/components/Workflow/WorkflowUtils.test.js | Updates layout test to assert geometry only (less coupled to dagre internals). |
| awx/ui/src/components/Workflow/WorkflowUtils.js | Switches from dagre to @dagrejs/dagre; removes unnecessary eslint-disable. |
| awx/ui/src/components/Sort/Sort.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/components/Search/AdvancedSearch.js | Removes inline exhaustive-deps suppression. |
| awx/ui/src/components/ResourceAccessList/DeleteRoleConfirmationModal.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/components/RelatedTemplateList/relatedTemplateHelpers.js | Removes unnecessary eslint-disable for default export preference. |
| awx/ui/src/components/ListHeader/ListHeader.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/components/FormField/FormField.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/components/ContentError/ContentError.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/components/AppContainer/AppContainer.js | Removes now-unneeded i18next/no-literal-string disables for translated attributes. |
| awx/ui/src/components/AddDropDownButton/AddDropDownButton.js | Removes file-level eslint-disable for “useless fragment”. |
| awx/ui/src/App.js | Removes i18next/no-literal-string disable in loading UI. |
| awx/ui/package.json | Upgrades Lingui and ESLint toolchain dependencies; replaces dagre with @dagrejs/dagre; updates lint script. |
| awx/ui/lingui.config.js | Adds Lingui v6 JS config and PO formatter wiring. |
| awx/ui/eslint.config.mjs | Adds ESLint v9 flat configuration (Airbnb-extended, import-x, stylistic, i18next, etc.). |
| awx/ui/config/webpack.config.js | Relaxes fully-specified ESM resolution for node_modules; updates ESLint plugin config handling for flat config. |
| awx/ui/.linguirc | Removes deprecated Lingui v5 JSON config file. |
| awx/ui/.eslintrc.json | Removes legacy ESLint config now replaced by flat config. |
| awx/ui/.eslintignore | Removes legacy ignore file now replaced by flat config ignores. |
cigamit
left a comment
There was a problem hiding this comment.
Tested and working. We will need to remove the warning in StatusLabel still.
|
Checked both comments against the actual flat config rather than assumption — neither directive is needed: |
|
@blaipr, we are going to be moving to long lines with Lingui to facilitate machines translations from POEdit. When, you think you are done with major changes, I'll be proceeding to extend the lines in the various JavaScript files that are currently broken with a line break and updating the Lingui configuration to output them. |
|
@TheWitness sounds good. The last big source change is #392 plus one route-tree follow-up after it merges, everything else open is small. I'll keep new strings on single lines, and happy to hold the follow-up if you want to go first. |
|
Check the |
|
Understood — adopted as the working convention going forward: long-line |
|
Took that pass over the 1. Machine translation translated the ICU syntax itself (~15 entries, worst in de/it). Lingui cannot parse these — the
2. React component tags corrupted (~20 entries, ja/ko/zh mostly): 3. Dropped/renumbered placeholders:
Separate observation: every locale still has ~48 folded multi-line entries, but those come from source (zu is ~1992/1996 untranslated — assuming that's intentional as a pseudo-locale.) |
SUMMARY
Modernizes three pieces of the frontend toolchain — Lingui 5 → 6, ESLint 8 → 9 (flat config) and the unmaintained dagre replaced by @dagrejs/dagre. They ship as one change because each regenerates
package-lock.jsonand their lockfile entries interleave; together the lockfile is regenerated once, cleanly.Lingui 5 → 6
.linguirc→lingui.config.js(+@lingui/format-po); removedi18n.loadLocaleData()everywhere (API deleted in v6; plurals come fromIntl.PluralRules) and the now-unusedmake-pluraldependency; webpack rule relaxing fully-specified ESM resolution (v6 is ESM-only, React 17 has no exports map); catalogs re-extracted with translations preserved (es: 1,896 → 1,898 filled msgstr).ESLint 8 → 9.39 flat config
eslint.config.mjsreplaces.eslintrc.json/.eslintignore; deadeslint-config-airbnb/eslint-config-react-app(capped at eslint ^8) replaced byeslint-config-airbnb-extended; import rules → import-x; i18next plugin 6 (option schema translated, shallow-merge defaults spread in); react-hooks 7 (new React-Compiler rules off — ~105 sites predate them, candidate follow-up); rules newer than the airbnb@19 baseline off for parity;npm audit fixclears GHSA-w7jw-789q-3m8p. ESLint 10 remains blocked by plugin peer ranges (react/jsx-a11y/import-x/babel-parser all ^9) and its removal of core formatting rules — the @Stylistic remaps here clear that hurdle in advance.dagre → @dagrejs/dagre 3
The maintained continuation; one import line in
WorkflowUtils.js(sole consumer); layout test now asserts geometry without library internals;licenses/uifile renamed.Known benign artifact: one unused-eslint-disable warning in
StatusLabel.js— the directive is required under #380's eslint-8 baseline, so it stays to keep #380 conflict-free; remove after both merge.Fully independent of every other open PR — verified by pairwise
git merge-treeagainst all of them.ISSUE TYPE
COMPONENT NAME
ASCENDER VERSION
ADDITIONAL INFORMATION