Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
"@ai-sdk/svelte": "^1.1.24",
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@6031134",
"@appwrite.io/pink-icons": "0.25.0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@2cf27e0",
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@1489b16",
"@appwrite.io/pink-legacy": "^1.0.3",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@fb8b1ed",
"@appwrite.io/pink-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-svelte@1489b16",
"@faker-js/faker": "^9.9.0",
"@popperjs/core": "^2.11.8",
"@sentry/sveltekit": "^8.38.0",
Expand Down
20 changes: 10 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions src/lib/charts/line.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
export let series: LineSeriesOption[];
export let options: EChartsOption = null;
export let formatted: 'days' | 'hours' = 'days';

export let applyStyles: boolean = true;
</script>

<Base
Expand All @@ -16,10 +18,11 @@
s.type = 'line';
s.stack = 'total';
s.lineStyle = {
shadowBlur: 38,
shadowColor: Colors.Primary,
shadowOffsetY: 15,
shadowOffsetX: 0
shadowBlur: applyStyles ? 38 : undefined,
shadowColor: applyStyles ? Colors.Primary : undefined,
shadowOffsetY: applyStyles ? 15 : undefined,
shadowOffsetX: 0,
width: applyStyles ? undefined : 2
};
s.showSymbol = false;

Expand Down
8 changes: 5 additions & 3 deletions src/lib/components/card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
danger?: boolean;
style?: string;
class?: string;
fullHeightChild?: boolean;
};

type ButtonProps = {
Expand All @@ -40,19 +41,20 @@
export let padding: $$Props['padding'] = 'm';
export let radius: $$Props['radius'] = 'm';
export let variant: $$Props['variant'] = 'primary';
export let fullHeightChild: $$Props['fullHeightChild'] = false;

$: resolvedClasses = [classes].filter(Boolean).join(' ');
</script>

{#if href}
<Card.Link class={resolvedClasses} {href} {style} {padding} {radius} {variant} on:click>
<Layout.Stack gap="xl">
<Layout.Stack gap="xl" height={fullHeightChild ? '100%' : undefined}>
<slot />
</Layout.Stack>
</Card.Link>
{:else if isButton}
<Card.Button class={resolvedClasses} {style} {padding} {radius} {variant} on:click>
<Layout.Stack gap="xl">
<Layout.Stack gap="xl" height={fullHeightChild ? '100%' : undefined}>
<slot />
</Layout.Stack>
</Card.Button>
Expand All @@ -64,7 +66,7 @@
{padding}
{radius}
{variant}>
<Layout.Stack gap="xl">
<Layout.Stack gap="xl" height={fullHeightChild ? '100%' : undefined}>
<slot />
</Layout.Stack>
</Card.Base>
Expand Down
27 changes: 27 additions & 0 deletions src/lib/helpers/faker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,30 @@ function generateSingleValue(column: Columns): string | number | boolean | null
}
}
}

function seededRandom(seed: number) {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
}

export function generateFakeBarChartData(seed = 1) {
const fakeData: [number, number][] = [];
const now = Date.now();
for (let i = 23; i >= 0; i--) {
const val = seededRandom(seed + i) * 1_000_000;
fakeData.push([now - i * 60 * 60 * 1000, Math.round(val)]);
}
return fakeData;
}
Comment on lines +206 to +214
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Stabilize timestamps to prevent loading-state chart reflows.

Using Date.now() on each render can shift x-axis and trigger re-layout. Accept a baseTimeMs parameter (defaulted once) so repeated calls during the same loading session produce consistent timestamps.

-export function generateFakeBarChartData(seed = 1) {
+export function generateFakeBarChartData(seed = 1, baseTimeMs = Date.now()) {
     const fakeData: [number, number][] = [];
-    const now = Date.now();
+    const now = baseTimeMs;
     for (let i = 23; i >= 0; i--) {
         const val = seededRandom(seed + i) * 1_000_000;
         fakeData.push([now - i * 60 * 60 * 1000, Math.round(val)]);
     }
     return fakeData;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function generateFakeBarChartData(seed = 1) {
const fakeData: [number, number][] = [];
const now = Date.now();
for (let i = 23; i >= 0; i--) {
const val = seededRandom(seed + i) * 1_000_000;
fakeData.push([now - i * 60 * 60 * 1000, Math.round(val)]);
}
return fakeData;
}
export function generateFakeBarChartData(seed = 1, baseTimeMs = Date.now()) {
const fakeData: [number, number][] = [];
const now = baseTimeMs;
for (let i = 23; i >= 0; i--) {
const val = seededRandom(seed + i) * 1_000_000;
fakeData.push([now - i * 60 * 60 * 1000, Math.round(val)]);
}
return fakeData;
}
🤖 Prompt for AI Agents
In src/lib/helpers/faker.ts around lines 206 to 214, the function uses
Date.now() each call which causes shifting x-axis; change the function to accept
an optional baseTimeMs parameter and use a module-level constant
initialBaseTimeMs = Date.now() as the default so the default is evaluated once
at module load; update the signature to accept baseTimeMs?: number, use
baseTimeMs ?? initialBaseTimeMs instead of Date.now() inside the loop, and leave
the rest of the logic unchanged so repeated calls during the same loading
session produce stable timestamps.


export function generateFakeLineChartData(seed = 2) {
const fakeData: [number, number][] = [];
const now = Date.now();
let value = seededRandom(seed) * 5000 + 5000;
for (let i = 23; i >= 0; i--) {
value += (seededRandom(seed + i) - 0.5) * 1000;
value = Math.max(0, value);
fakeData.push([now - i * 60 * 60 * 1000, Math.round(value)]);
}
return fakeData;
}
Comment on lines +216 to +226
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Same stabilization for line data.

-export function generateFakeLineChartData(seed = 2) {
+export function generateFakeLineChartData(seed = 2, baseTimeMs = Date.now()) {
     const fakeData: [number, number][] = [];
-    const now = Date.now();
+    const now = baseTimeMs;
     let value = seededRandom(seed) * 5000 + 5000;
     for (let i = 23; i >= 0; i--) {
         value += (seededRandom(seed + i) - 0.5) * 1000;
         value = Math.max(0, value);
         fakeData.push([now - i * 60 * 60 * 1000, Math.round(value)]);
     }
     return fakeData;
 }

Follow-up: Pass a single baseTimeMs from the parent (e.g., layout/store) to all loading charts so they share the same axis during a loading cycle.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function generateFakeLineChartData(seed = 2) {
const fakeData: [number, number][] = [];
const now = Date.now();
let value = seededRandom(seed) * 5000 + 5000;
for (let i = 23; i >= 0; i--) {
value += (seededRandom(seed + i) - 0.5) * 1000;
value = Math.max(0, value);
fakeData.push([now - i * 60 * 60 * 1000, Math.round(value)]);
}
return fakeData;
}
export function generateFakeLineChartData(seed = 2, baseTimeMs = Date.now()) {
const fakeData: [number, number][] = [];
const now = baseTimeMs;
let value = seededRandom(seed) * 5000 + 5000;
for (let i = 23; i >= 0; i--) {
value += (seededRandom(seed + i) - 0.5) * 1000;
value = Math.max(0, value);
fakeData.push([now - i * 60 * 60 * 1000, Math.round(value)]);
}
return fakeData;
}
🤖 Prompt for AI Agents
In src/lib/helpers/faker.ts around lines 216 to 226, generateFakeLineChartData
uses Date.now() internally which prevents multiple charts from sharing a single
synchronized axis; change the function signature to accept an optional
baseTimeMs (defaulting to Date.now()) and replace the local now = Date.now()
with now = baseTimeMs so callers can pass the same baseTimeMs to all charts
during a loading cycle; update all call sites (layout/store and any tests) to
pass the shared baseTimeMs from the parent so charts render on the same time
axis, and keep the seededRandom behavior unchanged.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import { Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';

let {
loading = false,
metricName,
resourceMetric = null
}: {
loading: boolean;
metricName: string;
resourceMetric?:
| string
| {
value: string;
unit: string;
}
| null;
} = $props();

function isMetricObject(
metric: typeof resourceMetric
): metric is { value: string; unit: string } {
return metric !== null && typeof metric === 'object';
}
</script>

<Layout.Stack gap="xxxs">
<Typography.Title>
<div class="overlay-container">
{#if loading}
<div class="overlay-item skeleton" transition:fade={{ duration: 300 }}>
<Skeleton height="100%" width="7.5rem" variant="line" style="opacity: 0.35" />
</div>
{:else if resourceMetric !== null}
<div class="overlay-item" transition:fade={{ duration: 300 }}>
{#if isMetricObject(resourceMetric)}
{resourceMetric.value}
<span style:line-height="0%" style:font-size="var(--font-size-0)">
{resourceMetric.unit}
</span>
{:else}
{resourceMetric}
{/if}
</div>
{/if}
</div>
</Typography.Title>

<Typography.Text>{metricName}</Typography.Text>
</Layout.Stack>

<style lang="scss">
.overlay-container {
display: grid;
min-height: 1lh;
align-items: stretch;
grid-template-areas: 'content';
}

.overlay-item {
grid-area: content;

&.skeleton {
display: flex;
align-items: center;
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import { Skeleton, Typography } from '@appwrite.io/pink-svelte';

let {
value,
resource,
unit = null,
loading = false
}: {
loading: boolean;
resource: string;
unit?: string;
value: string | number | boolean;
} = $props();
</script>

<Typography.Title>
<div class="overlay-container">
{#if loading}
<div class="overlay-item skeleton" transition:fade={{ duration: 300 }}>
<Skeleton
height="100%"
width="5rem"
variant="line"
style="opacity: 0.35; margin-bottom: 1rem; margin-inline-start: -2px" />
</div>
{:else}
<div class="overlay-item" transition:fade={{ duration: 300, delay: 150 }}>
{value}
{#if unit}
<span style:line-height="0%" style:font-size="var(--font-size-0)">
{unit}
</span>
{/if}
</div>
{/if}
</div>
</Typography.Title>

<Typography.Text>
{resource}
</Typography.Text>

<style lang="scss">
.overlay-container {
display: grid;
min-height: 1lh;
align-items: stretch;
grid-template-areas: 'content';
}

.overlay-item {
grid-area: content;

&.skeleton {
display: flex;
align-items: center;
}
}
</style>
Loading