Skip to content

Commit 88ce5d3

Browse files
authored
feat: Add selected counts to insights client filter (#7035)
1 parent 12c5665 commit 88ce5d3

File tree

4 files changed

+69
-3
lines changed

4 files changed

+69
-3
lines changed

.changeset/violet-rats-judge.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'hive': minor
3+
---
4+
5+
Add selected counts to insights client filter

packages/web/app/src/components/target/insights/Filters.tsx

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function OperationsFilter({
129129
/>
130130
);
131131
},
132-
[visibleOperations, selectedItems, onSelect],
132+
[visibleOperations, selectedItems, onSelect, clientFilteredOperations],
133133
);
134134

135135
return (
@@ -416,11 +416,19 @@ function ClientRow({
416416
...props
417417
}: {
418418
client: FragmentType<typeof ClientRow_ClientStatsValuesFragment>;
419+
clientOperationStats:
420+
| FragmentType<typeof ClientRow_ClientStatsValuesFragment>
421+
| false
422+
| undefined;
419423
selected: boolean;
420424
onSelect(id: string, selected: boolean): void;
421425
style: any;
422426
}): ReactElement {
423427
const client = useFragment(ClientRow_ClientStatsValuesFragment, props.client);
428+
const clientOperation =
429+
props.clientOperationStats === false
430+
? false
431+
: useFragment(ClientRow_ClientStatsValuesFragment, props.clientOperationStats);
424432
const requests = useFormattedNumber(client.count);
425433
const hash = client.name;
426434
const change = useCallback(() => {
@@ -429,6 +437,18 @@ function ClientRow({
429437
}
430438
}, [onSelect, hash, selected]);
431439

440+
const Totals = () => {
441+
if (clientOperation !== false) {
442+
return (
443+
<div className="flex shrink-0 text-right text-gray-500">
444+
<span>{clientOperation?.count ?? 0}</span>
445+
<span className="ml-1 truncate text-gray-600">/ {requests}</span>
446+
</div>
447+
);
448+
}
449+
return <div className="shrink-0 text-right text-gray-600">{requests}</div>;
450+
};
451+
432452
return (
433453
<div style={style} className="flex items-center gap-4 truncate">
434454
<Checkbox checked={selected} onCheckedChange={change} id={hash} />
@@ -437,7 +457,7 @@ function ClientRow({
437457
className="flex w-full cursor-pointer items-center justify-between gap-4 overflow-hidden"
438458
>
439459
<span className="grow overflow-hidden text-ellipsis">{client.name}</span>
440-
<div className="shrink-0 text-right text-gray-500">{requests}</div>
460+
<Totals />
441461
</label>
442462
</div>
443463
);
@@ -459,12 +479,16 @@ function ClientsFilter({
459479
isOpen,
460480
onFilter,
461481
clientStatsConnection,
482+
operationStatsConnection,
462483
selected,
463484
}: {
464485
onClose(): void;
465486
onFilter(keys: string[]): void;
466487
isOpen: boolean;
467488
clientStatsConnection: FragmentType<typeof ClientsFilter_ClientStatsValuesConnectionFragment>;
489+
operationStatsConnection?:
490+
| FragmentType<typeof ClientsFilter_ClientStatsValuesConnectionFragment>
491+
| undefined;
468492
selected?: string[];
469493
}): ReactElement {
470494
const clientConnection = useFragment(
@@ -520,21 +544,30 @@ function ClientsFilter({
520544
setSelectedItems([]);
521545
}, [setSelectedItems]);
522546

547+
const operationConnection = operationStatsConnection
548+
? useFragment(ClientsFilter_ClientStatsValuesConnectionFragment, operationStatsConnection)
549+
: null;
550+
523551
const renderRow = useCallback<ComponentType<ListChildComponentProps>>(
524552
({ index, style }) => {
525553
const client = visibleOperations[index].node;
554+
const operationStats =
555+
operationConnection == null
556+
? false
557+
: operationConnection.edges.find(e => e.node.name === client.name)?.node;
526558

527559
return (
528560
<ClientRow
529561
style={style}
530562
key={client.name}
531563
client={client}
564+
clientOperationStats={operationStats}
532565
selected={selectedItems.includes(client.name || '')}
533566
onSelect={onSelect}
534567
/>
535568
);
536569
},
537-
[visibleOperations, selectedItems, onSelect],
570+
[visibleOperations, selectedItems, onSelect, operationConnection],
538571
);
539572

540573
return (
@@ -577,6 +610,11 @@ function ClientsFilter({
577610
</Button>
578611
</div>
579612
<div className="grow pl-1">
613+
{operationStatsConnection && (
614+
<div className="text-right text-xs text-gray-600">
615+
<span className="text-gray-500">selected</span> / all operations
616+
</div>
617+
)}
580618
<AutoSizer>
581619
{({ height, width }) =>
582620
!height || !width ? (
@@ -605,6 +643,8 @@ const ClientsFilterContainer_ClientStatsQuery = graphql(`
605643
query ClientsFilterContainer_ClientStats(
606644
$targetSelector: TargetSelectorInput!
607645
$period: DateRangeInput!
646+
$filter: OperationStatsFilterInput
647+
$hasFilter: Boolean!
608648
) {
609649
target(reference: { bySelector: $targetSelector }) {
610650
id
@@ -618,6 +658,17 @@ const ClientsFilterContainer_ClientStatsQuery = graphql(`
618658
}
619659
}
620660
}
661+
filteredOperationStats: operationsStats(period: $period, filter: $filter)
662+
@include(if: $hasFilter) {
663+
clients {
664+
...ClientsFilter_ClientStatsValuesConnectionFragment
665+
edges {
666+
node {
667+
__typename
668+
}
669+
}
670+
}
671+
}
621672
}
622673
}
623674
`);
@@ -628,6 +679,7 @@ function ClientsFilterContainer({
628679
onClose,
629680
onFilter,
630681
selected,
682+
selectedOperationIds,
631683
organizationSlug,
632684
projectSlug,
633685
targetSlug,
@@ -640,6 +692,7 @@ function ClientsFilterContainer({
640692
organizationSlug: string;
641693
projectSlug: string;
642694
targetSlug: string;
695+
selectedOperationIds?: string[];
643696
}): ReactElement | null {
644697
const [query, refresh] = useQuery({
645698
query: ClientsFilterContainer_ClientStatsQuery,
@@ -650,6 +703,8 @@ function ClientsFilterContainer({
650703
targetSlug,
651704
},
652705
period,
706+
filter: selectedOperationIds ? { operationIds: selectedOperationIds } : undefined,
707+
hasFilter: !!selectedOperationIds?.length,
653708
},
654709
});
655710

@@ -672,6 +727,7 @@ function ClientsFilterContainer({
672727
return (
673728
<ClientsFilter
674729
clientStatsConnection={query.data.target.operationsStats.clients}
730+
operationStatsConnection={query.data.target.filteredOperationStats?.clients}
675731
selected={selected}
676732
isOpen={isOpen}
677733
onClose={onClose}
@@ -689,10 +745,12 @@ export function ClientsFilterTrigger({
689745
organizationSlug,
690746
projectSlug,
691747
targetSlug,
748+
selectedOperationIds,
692749
}: {
693750
period: DateRangeInput;
694751
onFilter(keys: string[]): void;
695752
selected?: string[];
753+
selectedOperationIds?: string[];
696754
organizationSlug: string;
697755
projectSlug: string;
698756
targetSlug: string;
@@ -713,6 +771,7 @@ export function ClientsFilterTrigger({
713771
onClose={toggle}
714772
period={period}
715773
selected={selected}
774+
selectedOperationIds={selectedOperationIds}
716775
onFilter={onFilter}
717776
/>
718777
</>

packages/web/app/src/pages/target-insights-operation.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ function OperationView({
9898
<ClientsFilterTrigger
9999
period={dateRangeController.resolvedRange}
100100
selected={selectedClients}
101+
selectedOperationIds={[operationHash]}
101102
onFilter={setSelectedClients}
102103
organizationSlug={organizationSlug}
103104
projectSlug={projectSlug}

packages/web/app/src/pages/target-insights.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ function OperationsView({
6262
targetSlug={targetSlug}
6363
period={dateRangeController.resolvedRange}
6464
selected={selectedClients}
65+
selectedOperationIds={selectedOperations}
6566
onFilter={setSelectedClients}
6667
/>
6768
<DateRangePicker

0 commit comments

Comments
 (0)