-
Notifications
You must be signed in to change notification settings - Fork 208
Fix: usage shifts #2345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix: usage shifts #2345
Conversation
Console (appwrite/console)Project ID: Sites (2)
Tip Preview deployments create instant URLs for every branch and commit |
WalkthroughAdds/loading-aware UI and data plumbing across the project overview area. New public props: Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Pre-merge checks❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (11)
src/lib/charts/line.svelte (1)
17-29: Avoid mutating incoming series; return new objects to prevent side-effects.The current map mutates each series object. Prefer immutable mapping to keep props pure and avoid subtle bugs when the same series array is reused elsewhere.
Apply:
- series={series.map((s) => { - s.type = 'line'; - s.stack = 'total'; - s.lineStyle = { - shadowBlur: applyStyles ? 38 : undefined, - shadowColor: applyStyles ? Colors.Primary : undefined, - shadowOffsetY: applyStyles ? 15 : undefined, - shadowOffsetX: 0, - width: applyStyles ? undefined : 2 - }; - s.showSymbol = false; - - return s; - })} + series={series.map((s) => ({ + ...s, + type: 'line', + stack: s.stack ?? 'total', + lineStyle: { + ...s.lineStyle, + shadowBlur: applyStyles ? 38 : undefined, + shadowColor: applyStyles ? Colors.Primary : undefined, + shadowOffsetY: applyStyles ? 15 : undefined, + shadowOffsetX: 0, + width: applyStyles ? undefined : 2 + }, + showSymbol: false + }))}src/lib/components/card.svelte (1)
49-73: Ensure the parent container can actually stretch to 100% height.Setting
height="100%"onLayout.Stackonly works if the Card variant (Link/Button/Base) also participates in a height-constrained layout. If you see no effect, add a fallback inline style to the stack.Example tweak:
- <Layout.Stack gap="xl" height={fullHeightChild ? '100%' : undefined}> + <Layout.Stack + gap="xl" + height={fullHeightChild ? '100%' : undefined} + style={fullHeightChild ? 'min-height:100%' : undefined}>(Repeat for the other two branches.)
src/routes/(console)/project-[region]-[project]/overview/(components)/skeletons/extended.svelte (2)
30-47: Minor a11y: mark container busy and announce updates politely.- <div class="overlay-container"> + <div class="overlay-container" aria-busy={loading} aria-live="polite">
54-59: Provide a safe fallback forlhunit to reduce cross-browser layout jitter.- .overlay-container { - display: grid; - min-height: 1lh; + .overlay-container { + display: grid; + min-height: 1em; /* fallback */ + min-height: 1lh;src/routes/(console)/project-[region]-[project]/overview/(components)/skeletons/simple.svelte (2)
19-39: Minor a11y: mark busy and announce politely.- <div class="overlay-container"> + <div class="overlay-container" aria-busy={loading} aria-live="polite">
46-51: Addlhfallback to avoid layout differences across browsers.- .overlay-container { - display: grid; - min-height: 1lh; + .overlay-container { + display: grid; + min-height: 1em; /* fallback */ + min-height: 1lh;src/routes/(console)/project-[region]-[project]/overview/+layout.svelte (2)
37-39: Avoid double-invokinghandleon initial load.
onMount(handle)+afterNavigate(handle)can both fire on first render. Consider keeping onlyafterNavigate, or gate the first call.Example:
let first = true; afterNavigate(() => { if (first) { first = false; handle(); return; } handle(); });
98-98: Remove debug log.Stray console log in production.
- $: console.log(`$loadingProjectUsage: ${$loadingProjectUsage}`); + // Intentionally left blanksrc/routes/(console)/project-[region]-[project]/overview/store.ts (1)
54-57: Minor: avoid store.get for static columns
get(devKeyColumns)freezes the current value at module init. Since columns are static, just spread the literal to keep things simple.Apply this diff:
-export const keyColumns = readable<Column[]>([ - ...get(devKeyColumns), - { id: 'scopes', title: 'Scopes', type: 'string', width: { min: 120 } } -]); +const baseDevKeyColumns: Column[] = [ + { id: 'name', title: 'Name', type: 'string', width: { min: 120 } }, + { id: 'last_accessed', title: 'Last accessed', type: 'datetime', width: { min: 120 } }, + { id: 'expiration', title: 'Expiration date', type: 'datetime', width: { min: 120 } } +]; +export const devKeyColumns = readable<Column[]>(baseDevKeyColumns); +export const keyColumns = readable<Column[]>([ + ...baseDevKeyColumns, + { id: 'scopes', title: 'Scopes', type: 'string', width: { min: 120 } } +]);src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte (2)
46-47: Guard chart data when not loadingIf
networkis undefined,chartDatabecomesundefined. Safer to default to[]to avoid surprises in downstream consumers.Apply this diff:
- let chartData = $derived(loading ? fakeBarChartData : network?.map((e) => [e.date, e.value])); + let chartData = $derived( + loading ? fakeBarChartData : (network?.map((e) => [e.date, e.value]) ?? []) + );
57-71: Micro: avoid double compute in axis label formatter
humanFileSize(+value)is called twice. Cache once.Apply this diff:
- formatter: (value: number) => { - return loading - ? '-- MB' - : !value - ? '0' - : `${humanFileSize(+value).value} ${humanFileSize(+value).unit}`; - } + formatter: (value: number) => { + if (loading) return '-- MB'; + if (!value) return '0'; + const hf = humanFileSize(+value); + return `${hf.value} ${hf.unit}`; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (11)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamlsrc/routes/(console)/project-[region]-[project]/overview/intro-dark.pngis excluded by!**/*.pngsrc/routes/(console)/project-[region]-[project]/overview/intro-light.pngis excluded by!**/*.pngsrc/routes/(console)/project-[region]-[project]/overview/onboard-1-dark-desktop.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-1-dark-mobile.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-1-light-desktop.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-1-light-mobile.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-2-dark-desktop.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-2-dark-mobile.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-2-light-desktop.svgis excluded by!**/*.svgsrc/routes/(console)/project-[region]-[project]/overview/onboard-2-light-mobile.svgis excluded by!**/*.svg
📒 Files selected for processing (10)
package.json(1 hunks)src/lib/charts/line.svelte(2 hunks)src/lib/components/card.svelte(3 hunks)src/lib/helpers/faker.ts(1 hunks)src/routes/(console)/project-[region]-[project]/overview/(components)/skeletons/extended.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/(components)/skeletons/simple.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/+layout.svelte(3 hunks)src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/requests.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/store.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/routes/(console)/project-[region]-[project]/overview/store.ts (2)
src/lib/helpers/string.ts (1)
hash(77-84)src/lib/stores/sdk.ts (1)
sdk(142-165)
🔇 Additional comments (4)
package.json (1)
27-29: Lockfile consistency verified
Both@appwrite.io/pink-svelteand@appwrite.io/pink-icons-sveltein pnpm-lock.yaml resolve to commit 1489b16 with no lingering duplicate versions.src/lib/charts/line.svelte (1)
20-21: Confirm that stacking is intended for all line series.
stack = 'total'changes chart semantics; verify this is desired for every caller of .src/lib/components/card.svelte (1)
20-21: Prop addition LGTM; name reads well.
fullHeightChildis clear and defaulting to false avoids behavior changes.src/routes/(console)/project-[region]-[project]/overview/+layout.svelte (1)
111-121: Nice: passingloadingthrough to child charts aligns with the skeleton flow.This is consistent and reduces perceived layout shift during fetch.
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/overview/requests.svelte
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/overview/requests.svelte
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/overview/requests.svelte
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/routes/(console)/project-[region]-[project]/overview/store.ts (1)
19-60: Critical: Race conditions and stuck loading state remain unaddressed.The past review comment on lines 20-42 identified two critical issues that are still present:
Race condition: Concurrent loads can result in older responses overwriting newer data. Without tracking the in-flight request,
lastParamsHashcan be set out of order.Stuck loading on errors: If the API call throws,
loadingProjectUsageremainstrueindefinitely. Combined with theminTimedelay, this creates a poor UX where the UI is stuck in a loading state.Apply the diff from the previous review comment to add try/finally blocks and in-flight request tracking:
export const usage = cachedStore< Models.UsageProject, { load: (start: string, end: string, period: ProjectUsageRange) => Promise<void>; } >('projectUsage', function ({ set }) { const minTime = 1250; let lastParamsHash: string | null = null; + let inflightParamsHash: string | null = null; return { load: async (start, end, period) => { const currentData = get(usage); const currentParamsHash = hash([ page.params.project, page.params.region, start, end, period.toString() ]); // don't hit the API call if we have the data! if (lastParamsHash === currentParamsHash && currentData && !isDev) { loadingProjectUsage.set(false); return; } const initTime = Date.now(); loadingProjectUsage.set(true); + inflightParamsHash = currentParamsHash; - const usages = await sdk - .forProject(page.params.region, page.params.project) - .project.getUsage({ - startDate: start, - endDate: end, - period - }); - - const elapsed = Date.now() - initTime; - const remainingTime = minTime - elapsed; - - if (remainingTime >= 0) { - await sleep(remainingTime); - } - - set(usages); - lastParamsHash = currentParamsHash; - loadingProjectUsage.set(false); + try { + const usages = await sdk + .forProject(page.params.region, page.params.project) + .project.getUsage({ + startDate: start, + endDate: end, + period + }); + + // Ignore stale responses + if (inflightParamsHash !== currentParamsHash) return; + + const elapsed = Date.now() - initTime; + const remainingTime = minTime - elapsed; + + if (remainingTime >= 0) { + await sleep(remainingTime); + } + + set(usages); + lastParamsHash = currentParamsHash; + } catch (err) { + console.error('Failed to load project usage', err); + } finally { + // Only clear loading if this request is still the latest + if (inflightParamsHash === currentParamsHash) { + loadingProjectUsage.set(false); + inflightParamsHash = null; + } + } } }; });src/routes/(console)/project-[region]-[project]/overview/requests.svelte (1)
38-47: Runtime risk:requestscan be undefined.The derived
requestsvalue uses a type assertion but doesn't guarantee the value exists. At line 46,requests.map()will throw ifrequestsis undefined. While the author previously stated "not when not loading", there's no guarantee that$usage?.requestsis populated whenloadingbecomesfalse.Apply this diff to add defensive checks:
let requests = $derived( - $usage?.requests as unknown as Array<{ + ($usage?.requests ?? []) as Array<{ date: number; value: number; }> ); let chartData = $derived( - loading ? fakeLineChartData : [...requests.map((e) => [e.date, e.value])] + loading ? fakeLineChartData : requests.map((e) => [e.date, e.value]) );
🧹 Nitpick comments (1)
src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte (1)
38-47: Consider improving type safety and null handling.While line 47 uses optional chaining (
network?.map()), the type assertion pattern at lines 38-43 is similar to requests.svelte and could be more defensive. Consider explicitly defaulting to an empty array:let network = $derived( - $usage?.network as unknown as Array<{ + ($usage?.network ?? []) as Array<{ date: number; value: number; }> ); let bandwidth = $derived(humanFileSize(totalMetrics($usage?.network))); -let chartData = $derived(loading ? fakeBarChartData : network?.map((e) => [e.date, e.value])); +let chartData = $derived(loading ? fakeBarChartData : network.map((e) => [e.date, e.value]));This ensures
networkis always an array and eliminates the need for optional chaining.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/lib/helpers/faker.ts(1 hunks)src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/requests.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/overview/store.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/helpers/faker.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/routes/(console)/project-[region]-[project]/overview/store.ts (3)
src/lib/helpers/string.ts (1)
hash(77-84)src/lib/system.ts (1)
isDev(28-28)src/lib/stores/sdk.ts (1)
sdk(147-170)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (2)
src/routes/(console)/project-[region]-[project]/overview/requests.svelte (1)
85-100: LGTM! Dispatch issue resolved.The sequential
toggle(event); dispatch(...)pattern correctly ensures both functions execute. This addresses the previous review comment about the short-circuit issue.src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte (1)
84-106: LGTM! Dispatch issue resolved.The sequential
toggle(event); dispatch(...)pattern correctly addresses the previous short-circuit issue, ensuring both the menu toggle and period change dispatch execute as expected.
src/routes/(console)/project-[region]-[project]/overview/requests.svelte
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte (1)
220-224: Consider removing or documenting the commented Realtime component.The commented-out Realtime card lacks context about whether it's intended for future implementation or should be removed. If it's a placeholder for upcoming work, consider adding a TODO comment with an explanation or issue reference; otherwise, remove it to keep the codebase clean.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/lib/components/card.sveltesrc/routes/(console)/project-[region]-[project]/overview/+layout.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/components/card.svelte
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports
Files:
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
src/routes/**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Files:
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
**/*.{ts,tsx,js,jsx,svelte,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration
Files:
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development
Files:
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
src/routes/**
📄 CodeRabbit inference engine (AGENTS.md)
Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names
Files:
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (5)
src/routes/(console)/project-[region]-[project]/overview/+layout.svelte (5)
24-24: LGTM: Imports and context setup support skeleton loading pattern.The new imports (
loadingProjectUsage,SimpleValueSkeleton) and the overview-action context are well-integrated for managing loading states and enabling actionable UI components.Also applies to: 32-32, 36-36
41-49: LGTM: Loading state management properly fixed.The loading flag is now unconditionally cleared in the
finallyblock, addressing the previous issue where the loading UI could get stuck if$usagewas falsy. The reset of$usagetonullbefore loading ensures a clean state transition.
94-96: LGTM: Clean code organization.The consolidated
updateCommandGroupRankscall and computedpathvariable improve readability while maintaining the same functionality.
122-218: LGTM: Well-structured metric cards with consistent skeleton pattern.The skeleton loading implementation across all metric cards (Database, Storage, Auth, Functions) is consistent and follows a clear pattern. The null-safe access patterns (
$usage?.rowsTotal ?? 0) prevent runtime errors, and theSimpleValueSkeletoncomponents will effectively prevent layout shifts during data loading.
105-120: Skeleton loading pattern correctly implemented with proper prop passing.Both the
BandwidthandRequestscomponents accept theloadingprop and correctly use it to display loading states. The implementation consistently applies skeleton loading throughout to prevent layout shifts during data fetching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/routes/(console)/project-[region]-[project]/overview/requests.svelte (1)
38-47: Add defensive fallback for requests during page transitions.The type assertion in
requestsdoesn't guarantee an array—if$usage?.requestsis undefined,requestsremains undefined and.map()will throw. During page transitions (e.g., when$usageis set tonull), reactive statements can evaluate beforeloadingupdates, causing a runtime error.Apply optional chaining with a fallback:
🔎 Suggested fix
let chartData = $derived( - loading ? fakeLineChartData : [...requests.map((e) => [e.date, e.value])] + loading ? fakeLineChartData : [...(requests ?? []).map((e) => [e.date, e.value])] );
🧹 Nitpick comments (1)
src/lib/charts/bar.svelte (1)
9-13: Consider aligning default values across chart components.Base uses
{}as the default forsetOptionConfig, while bar and line useundefined. Though functionally equivalent (undefined falls back to Base's default), using consistent defaults would improve clarity.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/lib/charts/bar.sveltesrc/lib/charts/base.sveltesrc/lib/charts/line.sveltesrc/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.svelte
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports
Files:
src/lib/charts/base.sveltesrc/lib/charts/line.sveltesrc/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.sveltesrc/lib/charts/bar.svelte
**/*.{ts,tsx,js,jsx,svelte,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration
Files:
src/lib/charts/base.sveltesrc/lib/charts/line.sveltesrc/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.sveltesrc/lib/charts/bar.svelte
**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development
Files:
src/lib/charts/base.sveltesrc/lib/charts/line.sveltesrc/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.sveltesrc/lib/charts/bar.svelte
src/routes/**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Files:
src/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.svelte
src/routes/**
📄 CodeRabbit inference engine (AGENTS.md)
Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names
Files:
src/routes/(console)/project-[region]-[project]/overview/bandwidth.sveltesrc/routes/(console)/project-[region]-[project]/overview/requests.svelte
🧠 Learnings (2)
📓 Common learnings
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/project-[region]-[project]/overview/requests.svelte
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: e2e
- GitHub Check: build
🔇 Additional comments (5)
src/lib/charts/base.svelte (1)
18-22: LGTM - Clean ECharts option configuration support.The
setOptionConfigprop correctly enables callers to control how ECharts merges and updates options, following the ECharts API design.Also applies to: 62-62
src/lib/charts/line.svelte (1)
10-10: LGTM - Loading-aware styling properly implemented.The
applyStylesprop cleanly toggles between styled (with shadows) and minimal (width-only) line rendering, appropriate for distinguishing real data from loading placeholders.Also applies to: 26-30
src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte (2)
27-33: LGTM - Safe data handling with optional chaining.The component properly destructures
periodandloadingfrom$props()and uses optional chaining (network?.map) to safely handle undefined data during loading states or transitions.Also applies to: 47-47
110-155: LGTM - Smooth loading transitions properly implemented.The chart/no-data states use
fadetransitions with|localmodifier and absolute positioning for smooth visual transitions. The conditional rendering correctly switches between loading/data states.src/routes/(console)/project-[region]-[project]/overview/requests.svelte (1)
101-140: LGTM - Consistent loading-aware rendering with transitions.The chart rendering logic mirrors the bandwidth component's approach with fade transitions, absolute positioning, and proper conditional rendering based on loading and data presence.

What does this PR do?
Fixes the usage layout shift.
Test Plan
Manual.
Before -
Screen.Recording.2025-09-10.at.1.02.05.PM.mov
After -
shifts-fixed.mov
Related PRs and Issues
N/A.
Have you read the Contributing Guidelines on issues?
Yes.
Summary by CodeRabbit
New Features
Performance
UX Improvements
✏️ Tip: You can customize this high-level summary in your review settings.