@columenlabs/lumen-ui 0.1.242 → 0.1.243

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.
@@ -174,9 +174,23 @@ function Providers({ client }) {
174
174
  return (_jsxs("div", { className: "flex flex-col", children: [_jsx(LumenExpandList, { children: rows.map((p) => (_jsx(OwnProviderKey, { client: client, p: p }, p.id))) }), ownSet && (_jsx(SettingField, { label: "Answers run on", info: "Your own key or plan first, with the shared credits behind it; or the shared credits first.", children: _jsx(LumenSelector, { label: "Answers run on", size: "sm", className: "w-44", value: s.pay, options: [
175
175
  { value: 'own', label: 'Your own first' },
176
176
  { value: 'app', label: 'Shared credits first' },
177
- ], onChange: (pay) => void apply('pay', () => client.settings({ pay: pay })) }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), _jsx(OwnKeyUsage, { client: client, always: ownSet })] }));
177
+ ], onChange: (pay) => void apply('pay', () => client.settings({ pay: pay })) }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), ownSet && _jsx(OwnCapUse, { s: s }), _jsx(OwnKeyUsage, { client: client, always: ownSet })] }));
178
178
  } }));
179
179
  }
180
+ /**
181
+ * How much of the person's own monthly cap is used: the same spend rows the cap is checked
182
+ * against, so this and the switch to shared credits never disagree.
183
+ */
184
+ function OwnCapUse({ s }) {
185
+ const used = s.spend.rows
186
+ .filter((r) => r.payer === 'own' && !r.free)
187
+ .reduce((a, r) => a + r.usd, 0);
188
+ const cap = s.caps.own;
189
+ const full = cap > 0 && used >= cap;
190
+ return (_jsx(SettingField, { label: "Used this month", info: full
191
+ ? 'Your cap is used up, so the shared credits pay until next month or until you raise the cap.'
192
+ : 'What your own keys and plan have spent this month, against your cap.', children: _jsxs("div", { className: "flex w-56 min-w-0 flex-col gap-1", children: [_jsx(ShareMeter, { value: cap > 0 ? used / cap : 1, label: `${usd(used)} of ${usd(cap)}`, wide: true }), full && _jsx("span", { className: "text-muted-foreground text-xs", children: "Cap reached: credits pay" })] }) }));
193
+ }
180
194
  /** One provider's shared key, which an admin sets for everyone. */
181
195
  function SharedProviderKey({ client, p }) {
182
196
  const { apply, refresh } = useApply(client);
@@ -119,17 +119,39 @@ export function OwnKeyUsage({ client, always }) {
119
119
  const sessions = all
120
120
  .filter((e) => e.at >= since && !seen.has(e.id) && seen.add(e.id))
121
121
  .sort((a, b) => b.at - a.at);
122
- const total = sessions.reduce((a, e) => a + (e.own_usd ?? 0), 0);
123
- return (_jsxs("div", { className: "flex flex-col gap-2 border-t border-border/60 pb-3 first:border-t-0", children: [_jsx(SettingField, { label: "Spent on your keys", info: "Each chat and run your own key or plan paid for, by its last use.", className: "border-t-0", end: _jsx(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: range, "aria-label": "Range", onValueChange: (v) => v && setRange(v), children: OWN_RANGES.map((r) => (_jsx(ToggleGroupItem, { value: r.id, "aria-label": `Last ${r.id}`, children: r.id }, r.id))) }) }), sessions.length ? (_jsx(DetailsTable, { head: [
122
+ // This month's own spend that no chat or run carries (spent before per-chat tracking), so the
123
+ // table never reads "nothing" while the cap's own numbers say otherwise.
124
+ const tagged = now.entries.reduce((a, e) => a + (e.own_usd ?? 0), 0);
125
+ const ownMonth = now.rows
126
+ .filter((r) => r.payer === 'own' && !r.free)
127
+ .reduce((a, r) => a + r.usd, 0);
128
+ const untracked = ownMonth - tagged >= 0.01 ? ownMonth - tagged : 0;
129
+ const total = sessions.reduce((a, e) => a + (e.own_usd ?? 0), 0) + untracked;
130
+ const earlier = 'Earlier this month, not per chat';
131
+ return (_jsxs("div", { className: "flex flex-col gap-2 border-t border-border/60 pb-3 first:border-t-0", children: [_jsx(SettingField, { label: "Spent on your keys", info: "Each chat and run your own key or plan paid for, by its last use.", className: "border-t-0", end: _jsx(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: range, "aria-label": "Range", onValueChange: (v) => v && setRange(v), children: OWN_RANGES.map((r) => (_jsx(ToggleGroupItem, { value: r.id, "aria-label": `Last ${r.id}`, children: r.id }, r.id))) }) }), sessions.length || untracked ? (_jsx(DetailsTable, { head: [
124
132
  { label: 'Session', grow: true },
125
133
  { label: 'Date', hideOnPhone: true },
126
134
  { label: 'Amount', right: true },
127
- ], rows: sessions.map((e) => ({
128
- key: e.id,
129
- cells: [
130
- _jsx("span", { className: "block truncate", title: e.title, children: e.title }, "n"),
131
- _jsx("time", { dateTime: new Date(e.at).toISOString(), title: new Date(e.at).toLocaleString(), children: when(e.at) }, "t"),
132
- usd(e.own_usd ?? 0),
133
- ],
134
- })), foot: ['Total', _jsx("span", { className: "max-md:hidden" }, "d"), usd(total)] })) : (_jsxs("p", { className: "text-muted-foreground text-sm", children: ["Nothing spent on your keys in the last ", range, "."] }))] }));
135
+ ], rows: [
136
+ ...sessions.map((e) => ({
137
+ key: e.id,
138
+ cells: [
139
+ _jsx("span", { className: "block truncate", title: e.title, children: e.title }, "n"),
140
+ _jsx("time", { dateTime: new Date(e.at).toISOString(), title: new Date(e.at).toLocaleString(), children: when(e.at) }, "t"),
141
+ usd(e.own_usd ?? 0),
142
+ ],
143
+ })),
144
+ ...(untracked
145
+ ? [
146
+ {
147
+ key: 'earlier',
148
+ cells: [
149
+ _jsx("span", { className: "block truncate text-muted-foreground", title: earlier, children: earlier }, "n"),
150
+ _jsx("span", {}, "t"),
151
+ usd(untracked),
152
+ ],
153
+ },
154
+ ]
155
+ : []),
156
+ ], foot: ['Total', _jsx("span", { className: "max-md:hidden" }, "d"), usd(total)] })) : (_jsxs("p", { className: "text-muted-foreground text-sm", children: ["Nothing spent on your keys in the last ", range, "."] }))] }));
135
157
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@columenlabs/lumen-ui",
3
- "version": "0.1.242",
3
+ "version": "0.1.243",
4
4
  "description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  "@codemirror/lang-javascript": "6.2.5",
50
50
  "@codemirror/lang-json": "6.0.2",
51
51
  "@codemirror/lang-sql": "6.10.0",
52
- "@columenlabs/lumen-ui-types": "0.1.242",
52
+ "@columenlabs/lumen-ui-types": "0.1.243",
53
53
  "@dnd-kit/core": "6.3.1",
54
54
  "@dnd-kit/sortable": "10.0.0",
55
55
  "@dnd-kit/utilities": "3.2.2",