Skip to content

Conversation

@ItzNotABug
Copy link
Member

@ItzNotABug ItzNotABug commented Sep 10, 2025

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

    • Charts can opt out of built-in visual styling and accept a new option to control chart update/merge behavior.
    • Cards gain an option to make inner content fill available height.
    • Seeded fake data generators for chart previews.
    • New simple and extended skeleton metric components for overview pages.
  • Performance

    • Client-side caching for usage data and a minimum loading display time to avoid flicker; loading state exposed.
  • UX Improvements

    • Period selectors disabled while loading; consistent skeleton-driven loading and improved no-data presentation.

✏️ Tip: You can customize this high-level summary in your review settings.

@ItzNotABug ItzNotABug self-assigned this Sep 10, 2025
@appwrite
Copy link

appwrite bot commented Sep 10, 2025

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (2)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code
 console-cloud
688b7c18002b9b871a8f
Ready Ready View Logs Preview URL QR Code

Tip

Preview deployments create instant URLs for every branch and commit

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds/loading-aware UI and data plumbing across the project overview area. New public props: applyStyles on line chart, setOptionConfig on charts, and fullHeightChild on Card. Introduces two fake-data generators (generateFakeBarChartData, generateFakeLineChartData) and two skeleton components (extended.svelte, simple.svelte). Overview pages (bandwidth, requests, +layout) now read { period, loading } from $props(), use derived data to switch between real and fake data while loading, and render skeletons. The overview store adds hash-based caching, a loadingProjectUsage flag with a minimum display time, and new UI state/column exports.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Pre-merge checks

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix: usage shifts' is vague and non-descriptive. It uses generic terminology ('usage shifts') without clearly explaining what the actual problem or solution is, making it difficult for reviewers to understand the primary change. Replace with a more specific title that describes the actual issue being fixed, such as 'Fix: prevent layout shifts in usage overview component' or 'Fix: add skeleton loaders to reduce usage data loading shifts'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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%" on Layout.Stack only 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 for lh unit 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: Add lh fallback 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-invoking handle on initial load.

onMount(handle) + afterNavigate(handle) can both fire on first render. Consider keeping only afterNavigate, 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 blank
src/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 loading

If network is undefined, chartData becomes undefined. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 5b98696 and 60d6ead.

⛔ Files ignored due to path filters (11)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/routes/(console)/project-[region]-[project]/overview/intro-dark.png is excluded by !**/*.png
  • src/routes/(console)/project-[region]-[project]/overview/intro-light.png is excluded by !**/*.png
  • src/routes/(console)/project-[region]-[project]/overview/onboard-1-dark-desktop.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-1-dark-mobile.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-1-light-desktop.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-1-light-mobile.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-2-dark-desktop.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-2-dark-mobile.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-2-light-desktop.svg is excluded by !**/*.svg
  • src/routes/(console)/project-[region]-[project]/overview/onboard-2-light-mobile.svg is 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-svelte and @appwrite.io/pink-icons-svelte in 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.

fullHeightChild is clear and defaulting to false avoids behavior changes.

src/routes/(console)/project-[region]-[project]/overview/+layout.svelte (1)

111-121: Nice: passing loading through to child charts aligns with the skeleton flow.

This is consistent and reduces perceived layout shift during fetch.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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:

  1. Race condition: Concurrent loads can result in older responses overwriting newer data. Without tracking the in-flight request, lastParamsHash can be set out of order.

  2. Stuck loading on errors: If the API call throws, loadingProjectUsage remains true indefinitely. Combined with the minTime delay, 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: requests can be undefined.

The derived requests value uses a type assertion but doesn't guarantee the value exists. At line 46, requests.map() will throw if requests is undefined. While the author previously stated "not when not loading", there's no guarantee that $usage?.requests is populated when loading becomes false.

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 network is always an array and eliminates the need for optional chaining.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df7f405 and 7cb4a5a.

📒 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7cb4a5a and 00c4496.

📒 Files selected for processing (2)
  • src/lib/components/card.svelte
  • src/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 finally block, addressing the previous issue where the loading UI could get stuck if $usage was falsy. The reset of $usage to null before loading ensures a clean state transition.


94-96: LGTM: Clean code organization.

The consolidated updateCommandGroupRanks call and computed path variable 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 the SimpleValueSkeleton components will effectively prevent layout shifts during data loading.


105-120: Skeleton loading pattern correctly implemented with proper prop passing.

Both the Bandwidth and Requests components accept the loading prop and correctly use it to display loading states. The implementation consistently applies skeleton loading throughout to prevent layout shifts during data fetching.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 requests doesn't guarantee an array—if $usage?.requests is undefined, requests remains undefined and .map() will throw. During page transitions (e.g., when $usage is set to null), reactive statements can evaluate before loading updates, 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 for setOptionConfig, while bar and line use undefined. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 00c4496 and 6ccc7cb.

📒 Files selected for processing (5)
  • src/lib/charts/bar.svelte
  • src/lib/charts/base.svelte
  • src/lib/charts/line.svelte
  • src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte
  • src/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.svelte
  • src/lib/charts/line.svelte
  • src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte
  • src/routes/(console)/project-[region]-[project]/overview/requests.svelte
  • src/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.svelte
  • src/lib/charts/line.svelte
  • src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte
  • src/routes/(console)/project-[region]-[project]/overview/requests.svelte
  • src/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.svelte
  • src/lib/charts/line.svelte
  • src/routes/(console)/project-[region]-[project]/overview/bandwidth.svelte
  • src/routes/(console)/project-[region]-[project]/overview/requests.svelte
  • src/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.svelte
  • src/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.svelte
  • src/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 setOptionConfig prop 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 applyStyles prop 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 period and loading from $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 fade transitions with |local modifier 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants