- Replace deprecated Alert `message` prop with `title`
- Update login test snapshots for antd 6.4.2 DOM changes
- Remove unused `useCallback` import in OfflineBanner
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add offline-friendly error handling and network status awareness
Add ErrorBoundary to catch render errors (including chunk load failures from
React.lazy), replacing the previous white-screen crash with a friendly Result
page. Add a network status model (useModel('network')) and OfflineBanner that
shows when the user goes offline. Make request error messages offline-aware.
Clean up dead PWA/ServiceWorker code in global.tsx that never fired.
- ErrorBoundary: catches all render errors, distinguishes chunk load failures
(offline vs online messages), uses antd Result with retry/home buttons
- OfflineBanner: Alert banner in ProLayout content area when offline
- network model: navigator.onLine + online/offline event listeners
- requestErrorConfig: offline-aware error messages in errorHandler
- global.tsx: remove dead sw.offline/sw.updated event listeners
- defaultSettings.ts: remove unused pwa flag
- locales: replace dead PWA i18n keys with network/error keys (8 locales)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: resolve intermittent "Can't resolve 'tailwindcss'" on Windows (#11747)
Set globalThis.__tw_resolve in postcss.config.js to bypass
enhanced-resolve's CachedInputFileSystem, which caches stale
negative results on Windows (e.g. when Windows Defender scans
node_modules). Also fix @source path from "./src" to "."
since the directive is relative to the CSS file location.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: address PR review feedback for offline features
- Use getIntl() with i18n key in requestErrorConfig instead of hardcoded
English strings (matches CodeRabbit, Gemini, Copilot feedback)
- Add SSR guard for navigator.onLine in requestErrorConfig (Gemini)
- Replace <a> wrapping <Button> with <Button href> for valid HTML
- Extract getSubTitleId helper to eliminate nested ternary
- Move OfflineBanner to rootContainer layer to cover layout:false
routes (login, register) that lack ProLayout
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* revert: remove unrelated tailwindcss and config changes
These changes belong in a separate PR:
- postcss.config.js: Windows tailwindcss resolve workaround
- src/tailwind.css: @source path change
- config/md-raw-loader.cjs: trailing newline fix
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: offlineBanner uses getIntl() and inline network state
OfflineBanner is rendered inside rootContainer, which is the outermost
wrapper in Umi's provider chain. useModel('network') and useIntl()
require provider context (dataflowProvider, i18nProvider) that doesn't
exist at this level, causing runtime crashes. Switch to getIntl() (which
accesses the global intl singleton) and inline navigator.onLine state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: make ErrorBoundary reactive to network state and move OfflineBanner outside
- ErrorBoundary now tracks isOnline via state + event listeners instead
of reading navigator.onLine once at render time, so the subtitle
updates when the user goes back online
- OfflineBanner moved outside ErrorBoundary in rootContainer so it
remains visible even when ErrorBoundary shows the error fallback
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: add defaultMessage fallback to requestErrorConfig formatMessage calls
Ensures a readable string is shown when the locale key is missing,
instead of the raw key id.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: match umi chunk error format and add defaultMessage fallbacks
1. isChunkLoadError regex now matches "Failed to load chunk" (Umi format)
in addition to "Loading chunk" (webpack format), fixing the error page
showing generic "Something went wrong" instead of friendly offline text
2. All formatMessage calls in ErrorBoundary and OfflineBanner include
defaultMessage fallbacks, fixing empty Alert banner when getIntl()
returns before locale initialization completes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: show offline-friendly error page when network is unavailable
When offline and navigating to an unvisited route, the ErrorBoundary
displayed a generic "Something went wrong" page instead of the friendly
offline/crunk-load error message. This happened because:
1. isChunkLoadError could miss errors when React wraps them or the error
name doesn't exactly match — now also checks error.stack and adds a
case-insensitive "chunkloaderror" pattern
2. When offline, ANY render error is overwhelmingly likely a chunk load
failure — new isNetworkRelatedError() treats offline as network-related
3. The subtitle defaultMessage was wrong: it used isOffline instead of
combining both networkRelated and isOffline dimensions
4. handleRetry only reloaded for isChunkLoadError — now also reloads when
offline (resetting state can't re-fetch the chunk)
5. Auto-reloads the page when network comes back online during an error
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: replace deprecated Alert `message` prop with `title`
antd v6 deprecated the `message` prop on Alert in favor of `title`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: replace ProLayout's default ErrorBoundary with our offline-aware version
ProLayout has a built-in ErrorBoundary (@ant-design/pro-utils) that
catches chunk load errors BEFORE our root-level ErrorBoundary, rendering
a generic "Something went wrong." Result page. This masked our custom
offline-friendly error handling entirely.
Pass our ErrorBoundary as ProLayout's ErrorBoundary prop so it catches
errors inside the content area with proper offline/chunk-error detection,
while the root-level ErrorBoundary still guards the outer app shell.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor: simplify ErrorBoundary, remove over-engineering
Remove speculative additions that didn't address the root cause:
- isNetworkRelatedError: assuming all render errors are chunk errors
when offline masks genuine bugs
- CHUNK_ERROR_PATTERNS const and error.stack scanning: the original
isChunkLoadError already matches utoopack's ChunkLoadError format
- getTitleId/getSubTitleId helpers: single-call-site abstractions
- Card wrapper: unnecessary inside ProLayout content area
- Offline-aware handleRetry: chunk errors should be the only trigger
for reload, not any error while offline
Kept the real improvements:
- Correct 3-way defaultMessage for subtitle (offline chunk / online
chunk / render error)
- Auto-reload on network recovery when in error state
- ProLayout ErrorBoundary prop (the actual fix in previous commit)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor: simplify offline handling and fix OfflineBanner not showing
1. OfflineBanner: use `useModel('network')` instead of duplicating
online/offline listener logic, fix `title` → `message` prop
(Alert in banner mode uses `message`, not `title`)
2. ErrorBoundary: extract shared renderErrorFallback(), split into
ErrorBoundaryClass (for ProLayout's ComponentClass prop) and
ErrorBoundary (FC wrapper using useModel('network')). When isOnline
prop is provided, class skips own event listeners; when unset,
falls back to navigator.onLine tracking.
3. requestErrorConfig: consolidate duplicate offline check — check
navigator.onLine once before the error.request branch instead of
duplicating the same intl message in two branches.
4. ProLayout now uses ErrorBoundaryClass directly (satisfies the
ComponentClass type requirement).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: useModel context null error — rootContainer is outside model provider
rootContainer is the outermost React wrapper, rendered BEFORE the
dataflow/model provider. Components inside it cannot use useModel().
- ErrorBoundary: revert to pure class component with own online/offline
listeners (no hooks). ProLayout ErrorBoundary prop requires
ComponentClass anyway.
- OfflineBanner: revert to own useState+useEffect listeners (same reason
— outside model provider in rootContainer).
- Delete unused src/models/network.ts (no consumers left).
- Remove ErrorBoundaryClass named export, keep default export only.
- Fix Alert `title` → `message` prop (banner mode uses message).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: move OfflineBanner into ProLayout childrenRender
rootContainer is outside ProLayout, causing layout issues (empty
ant-layout-header inserted). Move OfflineBanner into childrenRender
where it renders inside the ProLayout content area as intended.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: wrap error Result in Card, style OfflineBanner with margin and showIcon
- ErrorBoundary: wrap Result in <Card variant="borderless"> for proper
card styling
- OfflineBanner: remove `banner` prop (was causing header layout issues),
add `showIcon` for warning icon, add `marginBottom: 16` for spacing
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: error boundary wrap in Layout.Content for padding, move offline banner to page top
- errorBoundary: replace Card with Layout.Content (padding: 24) to match
the 403/exception page style, since ErrorBoundary renders outside
ProLayout's Layout.Content
- offlineBanner: move back to rootContainer (above ProLayout) to display
at page top as a full-width banner, restore `banner` prop
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: error boundary use Card style matching 403 page, offline banner fixed top center
- errorBoundary: use Card variant="borderless" wrapping Result, matching
the 403/404 exception page style for consistency
- offlineBanner: use fixed positioning at top center of header area with
pointer-events passthrough, max-width 480px, small margin
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: add padding around error boundary Card for consistent layout
ErrorBoundary replaces Layout.Content when catching errors, so the
Card has no outer padding. Wrap in a div with padding: 24 to match
the ProLayout content area spacing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add soft retry for chunk errors and update all locales
Split the single retry button into two actions:
- "Retry" (soft): clears failed chunk scripts and resets ErrorBoundary
state for chunk load errors only
- "Reload Page" (hard): full page refresh, available for all errors
Update all 8 locale files with new app.error.reload key and change
app.error.retry from "refresh/reload" to "retry" semantics.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: remove non-functional soft retry and simplify ErrorBoundary
- Remove removeFailedChunkScripts() — nothing marks scripts with
data-failed and the bundler caches rejected promises, so soft retry
was a no-op that misleads users
- Remove Retry button; keep Reload Page + Back Home for all errors
- Remove unused app.error.retry locale key from all 8 locales
- Evaluate navigator.onLine directly in render instead of caching in
instance field, so error UI always reflects current network status
- Limit handleOnline auto-reload to chunk load errors only, preventing
data loss from indiscriminate reload on render errors
- Remove offline event listener (no longer needed without isOnline cache)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: make ErrorBoundary reactive to network state changes
- Move isOnline into component state so error fallback UI updates
when network status changes (online/offline events trigger re-render)
- Tighten isChunkLoadError regex: replace broad /imported module/i
with specific /Failed to fetch dynamically imported module/i to
avoid false positives on unrelated runtime errors
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add retry button for chunk errors, simplify DOM, rename pwa→network
- Add Retry button for chunk load errors that remounts children via
key increment, forcing React.lazy to re-execute import() without
a full page reload
- Remove wrapper divs: Card padding applied directly via style,
Alert positioned directly without outer container
- Rename pwa.ts → network.ts across all 8 locales (keys no longer
PWA-specific) and update imports in locale index files
- Add app.error.retry locale key to all 8 locales
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* style: remove unnecessary comment in components index and ErrorBoundary
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* fix: resolve CF Worker Date.now() returning 0 at module level
In Cloudflare Workers, module-level Date.now() evaluates to 0 during
initialization, causing all time-dependent data (visitData dates,
offlineChartData times, activities updatedAt) to render as epoch-zero
values (1970-01-01, 0:00). This broke the analysis dashboard charts
on the preview site.
Convert static module-level data exports to functions that generate
data at request time, ensuring Date.now() returns the current time.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add Google Analytics (GA4) configuration
Add ga_v2 tracking ID G-59NF1VHHPF via Umi Max analytics plugin.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add gradient celebration title to Welcome page
Set PageContainer title to "欢迎使用 Ant Design Pro V6 🎉" with
blue-to-purple gradient text. Added i18n key for all 8 locales.
The sidebar menu label remains "欢迎" unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: apply gradient only to V6 text, not entire title
Use react-intl rich text interpolation to wrap only "V6" with
the gradient class. Updated all 8 locale strings to use {v6}
placeholder. Emoji moved outside i18n string.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Add v6 release link in both READMEs
- Update tech stack references (Umi Max 4, utoopack, Tailwind CSS v4)
- Add AI Assistant feature in feature list
- Update Templates section to match current routes
- Remove Opera from browser support table
- Add "What's New in v6" section in cheatsheets
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Remove package-lock.json from .gitignore
- Add package-lock.json to biome ignore list
- Split json pattern in lint-staged config
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>