summaryrefslogtreecommitdiff
path: root/frontend/src/components/Status.svelte
blob: ce2a7534c0a14e36d9a30a63d39819fa3bc2655d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script lang="ts">
  import { Alert } from '$lib/components/ui/alert';
  import * as Card from '$lib/components/ui/card';

  interface Props {
    error?: string | null;
    busy?: boolean;
    busyText?: string;
    empty?: string | boolean | null;
    emptyHint?: string;
    warnings?: string[];
  }
  let { error, busy, busyText = '加载中…', empty, emptyHint, warnings }: Props = $props();
</script>

{#if busy}
  <div class="text-muted-foreground flex items-center gap-2 py-3 text-sm" role="status">
    <span class="inline-block size-4 rounded-full border-2 border-primary border-t-transparent align-[-0.125em] animate-spin" aria-hidden="true"></span>
    {busyText}
  </div>
{:else if error}
  <Alert variant="destructive">
    <span aria-hidden="true">⚠</span>
    <span>{error}</span>
  </Alert>
{:else if empty !== null && empty !== undefined && empty !== false}
  <Card.Root class="border-dashed text-center py-8 px-4 text-muted-foreground">
    <p class="font-semibold mb-1">{empty}</p>
    {#if emptyHint}<p class="text-sm text-muted-foreground">{emptyHint}</p>{/if}
  </Card.Root>
{/if}
{#if warnings && warnings.length > 0}
  {#each warnings as w, i (i)}
    <Alert variant="default"><span aria-hidden="true">△</span><span>{w}</span></Alert>
  {/each}
{/if}