{
background: var(--color-danger-bg);
color: var(--color-danger);
}
+
+.inline-feedback--hint {
+ gap: 6px;
+ border: 0;
+ background: transparent;
+ padding: 0;
+ font-size: var(--text-sm);
+}
+
+.inline-feedback--hint .inline-feedback__glyph {
+ width: 14px;
+ height: 14px;
+}
+
+.inline-feedback--hint.inline-feedback--info {
+ color: var(--color-action);
+}
+
+.inline-feedback--auth {
+ gap: 0;
+ border-color: color-mix(
+ in srgb,
+ var(--color-danger) 34%,
+ var(--color-border-subtle)
+ );
+ background: var(--color-danger-bg);
+ color: var(--color-danger);
+ padding: 8px 10px;
+ font-size: var(--text-label-xs);
+ line-height: 1.55;
+}
+
+.inline-feedback--auth .inline-feedback__glyph {
+ display: none;
+}
+
+.inline-feedback--toast {
+ position: fixed;
+ z-index: var(--z-drawer);
+ bottom: 26px;
+ left: 50%;
+ width: max-content;
+ max-width: calc(100vw - 32px);
+ transform: translateX(-50%);
+ border: 0;
+ border-radius: 8px;
+ background: var(--color-text);
+ color: var(--color-surface);
+ padding: 8px 14px;
+ box-shadow: var(--shadow-overlay);
+ font-size: 12.5px;
+}
+
+.inline-feedback--toast .inline-feedback__glyph {
+ display: none;
+}
diff --git a/web/src/components/ui/SegmentedControl.vue b/web/src/components/ui/SegmentedControl.vue
index 80c58a58..79c6d9f6 100644
--- a/web/src/components/ui/SegmentedControl.vue
+++ b/web/src/components/ui/SegmentedControl.vue
@@ -7,14 +7,20 @@ export interface SegmentedControlOption {
disabled?: boolean
}
-defineProps<{
- modelValue: string
- label: string
- options: SegmentedControlOption[]
- controlsId?: string
- idPrefix?: string
- scrollable?: boolean
-}>()
+withDefaults(
+ defineProps<{
+ modelValue: string
+ label: string
+ options: SegmentedControlOption[]
+ controlsId?: string
+ idPrefix?: string
+ scrollable?: boolean
+ appearance?: 'joined' | 'pills'
+ }>(),
+ {
+ appearance: 'joined',
+ },
+)
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
@@ -57,7 +63,10 @@ function handleSegmentKeydown(event: KeyboardEvent): void {
>
diff --git a/web/src/components/ui/SkeletonBlock.vue b/web/src/components/ui/SkeletonBlock.vue
index 9932de2f..240fa49f 100644
--- a/web/src/components/ui/SkeletonBlock.vue
+++ b/web/src/components/ui/SkeletonBlock.vue
@@ -2,10 +2,12 @@
withDefaults(
defineProps<{
height?: string
+ width?: string
rounded?: boolean
}>(),
{
height: '1rem',
+ width: '100%',
rounded: true,
},
)
@@ -15,7 +17,7 @@ withDefaults(
@@ -23,7 +25,8 @@ withDefaults(
diff --git a/web/src/features/home/ConsumptionRanking.vue b/web/src/features/home/ConsumptionRanking.vue
index d7fe9f4c..845275c2 100644
--- a/web/src/features/home/ConsumptionRanking.vue
+++ b/web/src/features/home/ConsumptionRanking.vue
@@ -5,14 +5,21 @@ import { useI18n } from 'vue-i18n'
import type { HomeRankings, HomeStatisticsRef } from '@/app/resources/home'
import DataTable from '@/components/ui/DataTable.vue'
import SegmentedControl from '@/components/ui/SegmentedControl.vue'
+import SkeletonBlock from '@/components/ui/SkeletonBlock.vue'
import { formatEstimatedCost, formatInteger, formatTokens } from '@/lib/format'
type RankingDimension = 'models' | 'groups' | 'accessKeys'
-const props = defineProps<{
- rankings: HomeRankings
- range: string
-}>()
+const props = withDefaults(
+ defineProps<{
+ rankings: HomeRankings
+ range: string
+ loading?: boolean
+ }>(),
+ {
+ loading: false,
+ },
+)
const { locale, t } = useI18n()
const dimension = ref('models')
@@ -65,7 +72,9 @@ function tokenCellAttributes(totalTokens: number): { title: string; 'aria-label'
@@ -103,14 +112,24 @@ function tokenCellAttributes(totalTokens: number): { title: string; 'aria-label'
-
+
+
+ |
+
+ |
+
+
+
|
{{ t('home.ledger.ranking.empty') }}
|
- | {{ modelName(row.model) }} |
+ {{ modelName(row.model) }} |
{{ referenceName(row.group, 'group') }} |
{{ formatInteger(row.request_count, locale) }}
@@ -129,7 +148,9 @@ function tokenCellAttributes(totalTokens: number): { title: string; 'aria-label'
- | {{ referenceName(row.group, 'group') }} |
+
+ {{ referenceName(row.group, 'group') }}
+ |
{{ formatInteger(row.request_count, locale) }}
|
@@ -147,7 +168,9 @@ function tokenCellAttributes(totalTokens: number): { title: string; 'aria-label'
- | {{ referenceName(row.access_key, 'accessKey') }} |
+
+ {{ referenceName(row.access_key, 'accessKey') }}
+ |
{{ formatInteger(row.request_count, locale) }}
|
@@ -171,15 +194,15 @@ function tokenCellAttributes(totalTokens: number): { title: string; 'aria-label'
diff --git a/web/src/features/home/GatewayConnection.vue b/web/src/features/home/GatewayConnection.vue
index 620f180d..7652ba3a 100644
--- a/web/src/features/home/GatewayConnection.vue
+++ b/web/src/features/home/GatewayConnection.vue
@@ -1,5 +1,5 @@
|