mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
refactor: improve periodic usage charts
This commit is contained in:
@@ -1,19 +1,47 @@
|
||||
<script lang="ts">
|
||||
import { BarChart, Legend, type LegendData } from '$lib/charts';
|
||||
import { accumulateFromEndingTotal } from '$lib/layout/usage.svelte';
|
||||
import { Card, SecondaryTabs, SecondaryTabsItem } from '$lib/components';
|
||||
import { page } from '$app/state';
|
||||
import { BarChart, Legend, type LegendData } from '$lib/charts';
|
||||
import { Card, SecondaryTabs, SecondaryTabsItem } from '$lib/components';
|
||||
import { clampMin, formatNumberWithCommas } from '$lib/helpers/numbers';
|
||||
import { accumulateFromEndingTotal } from '$lib/layout/usage.svelte';
|
||||
import { type Models } from '@appwrite.io/console';
|
||||
import { formatNumberWithCommas, clampMin } from '$lib/helpers/numbers';
|
||||
import { Layout, Typography } from '@appwrite.io/pink-svelte';
|
||||
import type { EChartsOption } from 'echarts';
|
||||
|
||||
export let title: string;
|
||||
export let total: number[];
|
||||
export let path: string = null;
|
||||
export let count: Models.Metric[][];
|
||||
export let legendData: LegendData[];
|
||||
export let showHeader: boolean = true;
|
||||
export let legendNumberFormat: 'comma' | 'abbreviate' = 'comma';
|
||||
type Props = {
|
||||
title: string;
|
||||
total: number[];
|
||||
path?: string | null;
|
||||
count: Models.Metric[][];
|
||||
legendData: LegendData[];
|
||||
showHeader?: boolean;
|
||||
legendNumberFormat?: 'comma' | 'abbreviate';
|
||||
isCumulative?: boolean;
|
||||
options?: EChartsOption | null;
|
||||
};
|
||||
|
||||
let {
|
||||
title,
|
||||
total,
|
||||
path = null,
|
||||
count,
|
||||
legendData,
|
||||
showHeader = true,
|
||||
legendNumberFormat = 'comma',
|
||||
isCumulative = true,
|
||||
options = null
|
||||
}: Props = $props();
|
||||
|
||||
const formatted = $derived(page.params.period === '24h' ? 'hours' : 'days');
|
||||
const totalCount = $derived(clampMin(total.reduce((a, b) => a + b, 0)));
|
||||
const series = $derived(
|
||||
count.map((metrics, index) => ({
|
||||
name: legendData[index].name,
|
||||
data: isCumulative
|
||||
? accumulateFromEndingTotal(metrics, total[index])
|
||||
: metrics.map((metric) => [metric.date, metric.value])
|
||||
}))
|
||||
);
|
||||
</script>
|
||||
|
||||
<div>
|
||||
@@ -41,19 +69,12 @@
|
||||
|
||||
<Card>
|
||||
{#if count}
|
||||
{@const totalCount = clampMin(total.reduce((a, b) => a + b, 0))}
|
||||
|
||||
<Layout.Stack gap="xs">
|
||||
<Typography.Title>{formatNumberWithCommas(totalCount)}</Typography.Title>
|
||||
<Typography.Text>Total {title.toLocaleLowerCase()}</Typography.Text>
|
||||
</Layout.Stack>
|
||||
<div class="multiple-chart-container u-flex-vertical u-gap-16">
|
||||
<BarChart
|
||||
formatted={page.params.period === '24h' ? 'hours' : 'days'}
|
||||
series={count.map((c, index) => ({
|
||||
name: legendData[index].name,
|
||||
data: accumulateFromEndingTotal(c, total[index])
|
||||
}))} />
|
||||
<BarChart {formatted} {options} {series} />
|
||||
|
||||
{#if legendData}
|
||||
<Legend
|
||||
|
||||
+23
-6
@@ -1,21 +1,38 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { clampMin } from '$lib/helpers/numbers';
|
||||
import { formatNum } from '$lib/helpers/string';
|
||||
import { Container, UsageMultiple } from '$lib/layout';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
export let data;
|
||||
let { data }: PageProps = $props();
|
||||
|
||||
$: reads = data.databaseReads;
|
||||
$: readsTotal = data.databaseReadsTotal;
|
||||
const reads = $derived(data.databaseReads ?? []);
|
||||
const readsTotal = $derived(clampMin(reads.reduce((sum, item) => sum + item.value, 0)));
|
||||
|
||||
$: writes = data.databaseWrites;
|
||||
$: writesTotal = data.databaseWritesTotal;
|
||||
const writes = $derived(data.databaseWrites ?? []);
|
||||
const writesTotal = $derived(clampMin(writes.reduce((sum, item) => sum + item.value, 0)));
|
||||
|
||||
const usagePath = $derived(
|
||||
`${base}/project-${page.params.region}-${page.params.project}/databases/database-${page.params.database}/usage`
|
||||
);
|
||||
</script>
|
||||
|
||||
<Container databasesMainScreen>
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
path={usagePath}
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
isCumulative={false}
|
||||
options={{
|
||||
yAxis: {
|
||||
axisLabel: {
|
||||
formatter: formatNum
|
||||
}
|
||||
}
|
||||
}}
|
||||
legendNumberFormat="abbreviate"
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
|
||||
+47
-6
@@ -1,24 +1,65 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import { Container, UsageMultiple } from '$lib/layout';
|
||||
import { InputSelect } from '$lib/elements/forms';
|
||||
import { clampMin } from '$lib/helpers/numbers';
|
||||
import { formatNum } from '$lib/helpers/string';
|
||||
import { Layout } from '@appwrite.io/pink-svelte';
|
||||
import type { PageData } from './$types';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
export let data: PageData;
|
||||
let { data }: PageProps = $props();
|
||||
|
||||
$: reads = data.databasesReads;
|
||||
$: readsTotal = data.databasesReadsTotal;
|
||||
const reads = $derived(data.databasesReads ?? []);
|
||||
const readsTotal = $derived(clampMin(reads.reduce((sum, item) => sum + item.value, 0)));
|
||||
|
||||
$: writes = data.databasesWrites;
|
||||
$: writesTotal = data.databasesWritesTotal;
|
||||
const writes = $derived(data.databasesWrites ?? []);
|
||||
const writesTotal = $derived(clampMin(writes.reduce((sum, item) => sum + item.value, 0)));
|
||||
|
||||
const usagePath = $derived(
|
||||
`${base}/project-${page.params.region}-${page.params.project}/databases/usage`
|
||||
);
|
||||
</script>
|
||||
|
||||
<Container>
|
||||
<Layout.Stack gap="l">
|
||||
<div
|
||||
style:max-width="250px"
|
||||
style:--input-background-color="var(--bgcolor-neutral-primary)">
|
||||
<InputSelect
|
||||
on:change={(e) => goto(`${usagePath}/${e.detail}`)}
|
||||
id="period"
|
||||
options={[
|
||||
{
|
||||
label: '24 hours',
|
||||
value: '24h'
|
||||
},
|
||||
{
|
||||
label: '30 days',
|
||||
value: '30d'
|
||||
},
|
||||
{
|
||||
label: '90 days',
|
||||
value: '90d'
|
||||
}
|
||||
]}
|
||||
value={page.params.period ?? '30d'} />
|
||||
</div>
|
||||
|
||||
<UsageMultiple
|
||||
title="Reads and writes"
|
||||
showHeader={false}
|
||||
total={[readsTotal, writesTotal]}
|
||||
count={[reads, writes]}
|
||||
isCumulative={false}
|
||||
options={{
|
||||
yAxis: {
|
||||
axisLabel: {
|
||||
formatter: formatNum
|
||||
}
|
||||
}
|
||||
}}
|
||||
legendNumberFormat="abbreviate"
|
||||
legendData={[
|
||||
{ name: 'Reads', value: readsTotal },
|
||||
|
||||
Reference in New Issue
Block a user