@lightupai/polaris 0.0.47 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/web/app.ts +8 -4
- package/src/web/views.ts +30 -0
package/package.json
CHANGED
package/src/web/app.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getSessionPromptCounts,
|
|
16
16
|
getProjectEvents,
|
|
17
17
|
getRecentSignups,
|
|
18
|
+
listUsers,
|
|
18
19
|
type Sql,
|
|
19
20
|
} from "../service/db";
|
|
20
21
|
import { layout, nav } from "./layout";
|
|
@@ -250,7 +251,8 @@ export function createApp(sql: Sql) {
|
|
|
250
251
|
}
|
|
251
252
|
} catch { /* _system project may not exist yet */ }
|
|
252
253
|
|
|
253
|
-
// Query
|
|
254
|
+
// Query team members, projects, sessions, and prompt counts
|
|
255
|
+
const teamMembers = await listUsers(sql, payload.org_id);
|
|
254
256
|
const projects = (await listProjects(sql, payload.org_id)).filter((p) => p.name !== "_system");
|
|
255
257
|
const allSessions = (await listSessions(sql, payload.org_id)).filter((s) => s.project !== "_system");
|
|
256
258
|
const promptCounts = await getSessionPromptCounts(sql, payload.org_id);
|
|
@@ -288,6 +290,7 @@ export function createApp(sql: Sql) {
|
|
|
288
290
|
cliInstalled,
|
|
289
291
|
hasConnectedSession,
|
|
290
292
|
totalPrompts: Array.from(promptCounts.values()).reduce((a, b) => a + b, 0),
|
|
293
|
+
teamMembers: teamMembers.map((u) => ({ name: u.name, email: u.email })),
|
|
291
294
|
};
|
|
292
295
|
|
|
293
296
|
if (hasConnectedSession) {
|
|
@@ -328,10 +331,11 @@ export function createApp(sql: Sql) {
|
|
|
328
331
|
const mockToken = "preview-token";
|
|
329
332
|
const base = { token: mockToken, userName: mockUser.name, orgName: mockOrg.name, orgSlug: "lightup-data" as string | null, email: mockUser.email };
|
|
330
333
|
|
|
334
|
+
const mockTeam = [{ name: mockUser.name, email: mockUser.email }, { name: "Alice Chen", email: "alice@lightup.ai" }, { name: "Laura Mowry", email: "laura@lightup.ai" }];
|
|
331
335
|
const fresh = { ...base, orgSlug: null, slackConnected: false, cliInstalled: false, hasConnectedSession: false, totalPrompts: 0 };
|
|
332
|
-
const slackDone = { ...base, slackConnected: true, cliInstalled: false, hasConnectedSession: false, totalPrompts: 0 };
|
|
333
|
-
const cliDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: false, totalPrompts: 0 };
|
|
334
|
-
const allDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: true, totalPrompts: 127 };
|
|
336
|
+
const slackDone = { ...base, slackConnected: true, cliInstalled: false, hasConnectedSession: false, totalPrompts: 0, teamMembers: mockTeam };
|
|
337
|
+
const cliDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: false, totalPrompts: 0, teamMembers: mockTeam };
|
|
338
|
+
const allDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: true, totalPrompts: 127, teamMembers: mockTeam };
|
|
335
339
|
|
|
336
340
|
return layout(`
|
|
337
341
|
<div class="max-w-5xl mx-auto px-6 py-12">
|
package/src/web/views.ts
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
import { nav, slackIcon, type NavOpts } from "./layout";
|
|
5
5
|
import type { SessionFixture, ProjectFixture, DeviceFixture } from "./fixtures";
|
|
6
6
|
|
|
7
|
+
interface TeamMember {
|
|
8
|
+
name: string;
|
|
9
|
+
email: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
interface ViewContext {
|
|
8
13
|
token: string;
|
|
9
14
|
userName: string;
|
|
@@ -14,6 +19,7 @@ interface ViewContext {
|
|
|
14
19
|
cliInstalled: boolean;
|
|
15
20
|
hasConnectedSession: boolean;
|
|
16
21
|
totalPrompts: number;
|
|
22
|
+
teamMembers?: TeamMember[];
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
function navOpts(ctx: ViewContext): NavOpts {
|
|
@@ -48,6 +54,24 @@ function statusBadge(label: string, done: boolean): string {
|
|
|
48
54
|
: `<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-500">${label}</span>`;
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
// --- Team members ---
|
|
58
|
+
|
|
59
|
+
function renderTeamMembers(members: TeamMember[], currentEmail: string): string {
|
|
60
|
+
if (members.length === 0) return "";
|
|
61
|
+
return `
|
|
62
|
+
<div class="mt-3 bg-white border border-gray-200 rounded-lg divide-y divide-gray-100">
|
|
63
|
+
${members.map((m) => {
|
|
64
|
+
const isYou = m.email === currentEmail;
|
|
65
|
+
return `
|
|
66
|
+
<div class="px-4 py-2.5 flex items-center gap-3">
|
|
67
|
+
<div class="w-7 h-7 rounded-full bg-polaris-600 flex items-center justify-center text-white text-xs font-bold shrink-0">${m.name.charAt(0).toUpperCase()}</div>
|
|
68
|
+
<p class="text-sm text-gray-900">${m.name}${isYou ? ' <span class="text-xs text-gray-400">(you)</span>' : ""}</p>
|
|
69
|
+
<span class="text-xs text-gray-400 ml-auto">${m.email}</span>
|
|
70
|
+
</div>`;
|
|
71
|
+
}).join("")}
|
|
72
|
+
</div>`;
|
|
73
|
+
}
|
|
74
|
+
|
|
51
75
|
// --- Floor section ---
|
|
52
76
|
|
|
53
77
|
type StepState = "done" | "active" | "future";
|
|
@@ -67,11 +91,13 @@ function renderFloorSection(ctx: ViewContext, compact = false, state: StepState
|
|
|
67
91
|
const promptStat = ctx.totalPrompts > 0
|
|
68
92
|
? `<span class="text-xs text-gray-400 ml-auto">${ctx.totalPrompts} prompt${ctx.totalPrompts !== 1 ? "s" : ""}</span>`
|
|
69
93
|
: '';
|
|
94
|
+
const teamCount = ctx.teamMembers?.length ?? 0;
|
|
70
95
|
return `
|
|
71
96
|
<div>
|
|
72
97
|
<div class="flex items-baseline gap-2 mb-3">
|
|
73
98
|
<h2 class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Floor</h2>
|
|
74
99
|
${statusBadge("Connected", true)}
|
|
100
|
+
${teamCount > 0 ? `<span class="text-xs text-gray-400">${teamCount} member${teamCount !== 1 ? "s" : ""}</span>` : ""}
|
|
75
101
|
</div>
|
|
76
102
|
<div class="bg-white border border-gray-200 rounded-lg px-5 py-3 flex items-center gap-3">
|
|
77
103
|
<div class="w-8 h-8 rounded-lg bg-[#4A154B] flex items-center justify-center shrink-0">
|
|
@@ -81,6 +107,7 @@ function renderFloorSection(ctx: ViewContext, compact = false, state: StepState
|
|
|
81
107
|
${ctx.orgSlug ? `<span class="text-xs text-gray-400 font-mono">${ctx.orgSlug}</span>` : ''}
|
|
82
108
|
${promptStat}
|
|
83
109
|
</div>
|
|
110
|
+
${ctx.teamMembers ? renderTeamMembers(ctx.teamMembers, ctx.email) : ""}
|
|
84
111
|
</div>`;
|
|
85
112
|
}
|
|
86
113
|
|
|
@@ -88,12 +115,14 @@ function renderFloorSection(ctx: ViewContext, compact = false, state: StepState
|
|
|
88
115
|
const slugLabel = ctx.orgSlug
|
|
89
116
|
? `<span class="text-xs text-gray-400 font-mono">${ctx.orgSlug}</span>`
|
|
90
117
|
: '';
|
|
118
|
+
const teamCount = ctx.teamMembers?.length ?? 0;
|
|
91
119
|
|
|
92
120
|
return `
|
|
93
121
|
<div>
|
|
94
122
|
<div class="flex items-baseline gap-2 mb-3">
|
|
95
123
|
<h2 class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Floor</h2>
|
|
96
124
|
${statusBadge("Connected", true)}
|
|
125
|
+
${teamCount > 0 ? `<span class="text-xs text-gray-400">${teamCount} member${teamCount !== 1 ? "s" : ""}</span>` : ""}
|
|
97
126
|
</div>
|
|
98
127
|
<div class="bg-white border border-gray-200 rounded-lg px-5 py-3 flex items-center gap-3">
|
|
99
128
|
<div class="w-8 h-8 rounded-lg bg-[#4A154B] flex items-center justify-center shrink-0">
|
|
@@ -102,6 +131,7 @@ function renderFloorSection(ctx: ViewContext, compact = false, state: StepState
|
|
|
102
131
|
<p class="text-sm font-medium text-gray-900">Slack</p>
|
|
103
132
|
${slugLabel}
|
|
104
133
|
</div>
|
|
134
|
+
${ctx.teamMembers ? renderTeamMembers(ctx.teamMembers, ctx.email) : ""}
|
|
105
135
|
</div>`;
|
|
106
136
|
}
|
|
107
137
|
|