mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-14 05:18:54 +00:00
feat(webui): user and group search filter on usage and charts views
Add a "Filter users or groups" search input to UsageView, mirroring OverviewView's model search (same Input component, icon, and clear-button styling). Case-insensitive, trimmed substring match: - A user matches when its own name contains the query. - A group matches when its own name contains the query OR it has at least one matching member. Groups accordion shows only matching groups, sorted through the existing Groups toolbar unchanged. A group that matches only via a member auto-expands (using the same tested override semantics as Overview's provider search); a group matched by its own name is not force-expanded, since the match is already visible on its collapsed trigger row. The nested members table inside an expanded group shows every member when the group matched by name, and only the matching members when it matched via a member. The flat Users table filters to matching users, plus every member of a name-matched group. The Total card and ChartsView's chart rendering are untouched by the filter. ChartsView's scope picker (Select) gets the identical search input, filtering the user/group option list it offers. "Total" always stays in the list, and the currently selected scope is always kept in the list even if a new query would otherwise hide it, so an active chart is never torn down or re-labeled by narrowing the picker. Generalize lib/provider-expand.ts into lib/search-expand.ts: the same two-set (manuallyExpanded/manuallyCollapsed) auto-expand/override state machine now drives both Overview's providers and Usage's groups, keyed on generic string ids instead of provider names specifically. OverviewView.vue is updated to the renamed computeExpandedItems/toggleItemExpand exports; its own behavior is unchanged. The moved spec (search-expand.spec.ts) keeps all 9 original cases plus 2 new ones pinning the same semantics against non-provider (group-shaped) ids. Add lib/usage-search.ts with the shared user/group matching helpers (userMatches, groupNameMatches, membersOfGroup, matchingMembersOfGroup, groupMatches) so UsageView and ChartsView share one matching implementation, with its own vitest spec. UsageTable.vue gains an optional emptyMessage prop (threaded to DataTable) so UsageView can show a "no users match ..."/"no groups match ..." message under an active filter, matching Overview's own alias-search empty-state pattern. No backend/Go logic changes; filtering is client-side over the already-polled GET /admin/api/usage response.
This commit is contained in:
@@ -19,6 +19,8 @@ const props = defineProps<{
|
||||
entries: AdminUsageEntryView[]
|
||||
secondaryColumnLabel: string
|
||||
secondaryValue: (entry: AdminUsageEntryView) => string
|
||||
/** Shown in the empty-state row when entries is empty — e.g. a filtered-search "no X match ..." message. Falls through to DataTable's own 'none' default when omitted. */
|
||||
emptyMessage?: string
|
||||
}>()
|
||||
|
||||
const columns = computed(() => usageColumns(props.idLabel, props.secondaryColumnLabel, props.secondaryValue))
|
||||
@@ -28,6 +30,7 @@ const columns = computed(() => usageColumns(props.idLabel, props.secondaryColumn
|
||||
<DataTable
|
||||
:columns="columns"
|
||||
:data="entries"
|
||||
:empty-message="emptyMessage"
|
||||
:row-class="(entry) => (entry.storeDown ? 'bg-destructive/10' : undefined)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user