Skip to content

Commit 343bc0a

Browse files
authored
Merge pull request #43 from VectorInstitute/add_active_users_metric
Add active users metric
2 parents a0ddf68 + a176fb1 commit 343bc0a

File tree

4 files changed

+46
-24
lines changed

4 files changed

+46
-24
lines changed

services/analytics/app/components/templates-table.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ export function TemplatesTable({ templates }: TemplatesTableProps) {
4747
</Tooltip>
4848
</th>
4949
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
50-
<Tooltip content="Sum of all workspace lifetime hours (from creation to now) for this template" position="right">
51-
Total Hours
50+
<Tooltip content="Number of unique users who have used this template in the last 7 days">
51+
Active Users
5252
</Tooltip>
5353
</th>
5454
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
55-
<Tooltip content="Average workspace lifetime hours across all workspaces for this template" position="right">
56-
Avg Hours
55+
<Tooltip content="Sum of all workspace lifetime hours (from creation to now) for this template" position="right">
56+
Total Hours
5757
</Tooltip>
5858
</th>
5959
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
@@ -95,11 +95,13 @@ export function TemplatesTable({ templates }: TemplatesTableProps) {
9595
{template.active_workspaces}
9696
</span>
9797
</td>
98-
<td className="px-6 py-4 text-right text-sm text-slate-700 dark:text-slate-300">
99-
{template.total_workspace_hours.toLocaleString()}h
98+
<td className="px-6 py-4 text-right text-sm">
99+
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-vector-violet/10 text-vector-violet border border-vector-violet/30">
100+
{template.unique_active_users}
101+
</span>
100102
</td>
101103
<td className="px-6 py-4 text-right text-sm text-slate-700 dark:text-slate-300">
102-
{template.avg_workspace_hours.toLocaleString()}h
104+
{template.total_workspace_hours.toLocaleString()}h
103105
</td>
104106
<td className="px-6 py-4 text-right">
105107
<Link

services/analytics/app/template/[templateName]/template-teams-content.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Link from 'next/link';
55
import { ArrowLeft, Users } from 'lucide-react';
66
import type { User } from '@vector-institute/aieng-auth-core';
77
import type { AnalyticsSnapshot, TeamMetrics } from '@/lib/types';
8+
import { Tooltip } from '@/app/components/tooltip';
89

910
interface TemplateTeamsContentProps {
1011
user: User | null;
@@ -154,7 +155,7 @@ export default function TemplateTeamsContent({ user, templateName }: TemplateTea
154155
{/* Main Content */}
155156
<div className="max-w-7xl mx-auto px-4 md:px-8 pb-8">
156157
{/* Summary Cards */}
157-
<div className="grid gap-6 md:grid-cols-4 mb-8 animate-fade-in">
158+
<div className="grid gap-6 md:grid-cols-3 mb-8 animate-fade-in">
158159
<div className="bg-white dark:bg-slate-800 rounded-2xl shadow-xl border-2 border-slate-200 dark:border-slate-700 p-6">
159160
<div className="text-sm font-semibold text-slate-600 dark:text-slate-400 uppercase tracking-wider mb-2">
160161
Total Workspaces
@@ -181,15 +182,6 @@ export default function TemplateTeamsContent({ user, templateName }: TemplateTea
181182
{template.total_workspace_hours.toLocaleString()}h
182183
</div>
183184
</div>
184-
185-
<div className="bg-white dark:bg-slate-800 rounded-2xl shadow-xl border-2 border-slate-200 dark:border-slate-700 p-6">
186-
<div className="text-sm font-semibold text-slate-600 dark:text-slate-400 uppercase tracking-wider mb-2">
187-
Avg Hours
188-
</div>
189-
<div className="text-3xl font-bold text-slate-900 dark:text-white">
190-
{template.avg_workspace_hours.toLocaleString()}h
191-
</div>
192-
</div>
193185
</div>
194186

195187
{/* Teams Table */}
@@ -213,16 +205,24 @@ export default function TemplateTeamsContent({ user, templateName }: TemplateTea
213205
Team
214206
</th>
215207
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
216-
Workspaces
208+
<Tooltip content="Number of workspaces created by this team from this template">
209+
Workspaces
210+
</Tooltip>
217211
</th>
218212
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
219-
Total Hours
213+
<Tooltip content="Number of unique team members who have used workspaces in the last 7 days">
214+
Active Users
215+
</Tooltip>
220216
</th>
221217
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
222-
Avg Hours
218+
<Tooltip content="Sum of all workspace lifetime hours for this team">
219+
Total Hours
220+
</Tooltip>
223221
</th>
224222
<th className="px-6 py-4 text-right text-xs font-semibold text-slate-700 dark:text-slate-300 uppercase tracking-wider">
225-
Active Days
223+
<Tooltip content="Number of days with activity in the last 7 days for this team" position="right">
224+
Active Days
225+
</Tooltip>
226226
</th>
227227
</tr>
228228
</thead>
@@ -240,11 +240,13 @@ export default function TemplateTeamsContent({ user, templateName }: TemplateTea
240240
<td className="px-6 py-4 text-right text-sm text-slate-700 dark:text-slate-300">
241241
{team.workspaces_for_template}
242242
</td>
243-
<td className="px-6 py-4 text-right text-sm text-slate-700 dark:text-slate-300">
244-
{team.total_workspace_hours.toLocaleString()}h
243+
<td className="px-6 py-4 text-right text-sm">
244+
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-vector-violet/10 text-vector-violet border border-vector-violet/30">
245+
{team.unique_active_users}
246+
</span>
245247
</td>
246248
<td className="px-6 py-4 text-right text-sm text-slate-700 dark:text-slate-300">
247-
{team.avg_workspace_hours.toLocaleString()}h
249+
{team.total_workspace_hours.toLocaleString()}h
248250
</td>
249251
<td className="px-6 py-4 text-right text-sm text-vector-turquoise">
250252
{team.active_days}

services/analytics/lib/metrics.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,18 @@ export function aggregateByTeam(workspaces: WorkspaceMetrics[]): TeamMetrics[] {
261261
// Sort members by last active (most recent first)
262262
members.sort((a, b) => new Date(b.last_active).getTime() - new Date(a.last_active).getTime());
263263

264+
// Count unique active users (users with at least one active workspace in last 7 days)
265+
const activeUsers = new Set<string>();
266+
teamWorkspaces.forEach((workspace) => {
267+
if (workspace.activity_status === 'active') {
268+
activeUsers.add(workspace.owner_github_handle);
269+
}
270+
});
271+
264272
return {
265273
team_name: teamName,
266274
total_workspaces: teamWorkspaces.length,
275+
unique_active_users: activeUsers.size,
267276
total_workspace_hours: Math.round(totalWorkspaceHours),
268277
avg_workspace_hours: Math.round(avgWorkspaceHours * 10) / 10,
269278
active_days: activeDates.size,
@@ -370,12 +379,19 @@ export function calculateTemplateMetrics(
370379
teamDistribution[workspace.team_name] = count + 1;
371380
});
372381

382+
// Count unique active users for this template (users with at least one active workspace in last 7 days)
383+
const activeUsers = new Set<string>();
384+
activeWorkspaces.forEach((workspace) => {
385+
activeUsers.add(workspace.owner_github_handle);
386+
});
387+
373388
return {
374389
template_id: template.id,
375390
template_name: template.name,
376391
template_display_name: template.display_name,
377392
total_workspaces: templateWorkspaces.length,
378393
active_workspaces: activeWorkspaces.length,
394+
unique_active_users: activeUsers.size,
379395
total_workspace_hours: Math.round(totalWorkspaceHours),
380396
avg_workspace_hours: Math.round(avgWorkspaceHours * 10) / 10,
381397
team_distribution: teamDistribution,

services/analytics/lib/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export interface TeamMetrics {
138138

139139
// Counts
140140
total_workspaces: number;
141+
unique_active_users: number; // Number of unique users with activity in last 7 days
141142

142143
// Time-based metrics
143144
total_workspace_hours: number; // Sum of all workspace lifetime hours
@@ -187,6 +188,7 @@ export interface TemplateMetrics {
187188
template_display_name: string;
188189
total_workspaces: number;
189190
active_workspaces: number;
191+
unique_active_users: number; // Number of unique users with activity in last 7 days
190192
total_workspace_hours: number; // Sum of all workspace lifetime hours for this template
191193
avg_workspace_hours: number; // Average workspace lifetime hours
192194
team_distribution: Record<string, number>;

0 commit comments

Comments
 (0)