@fonderie/react-admin-screens 0.4.0 → 0.5.0

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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/screens/AdminShell.tsx
2
2
  import { ConfigEditorScreen, ConfigListScreen } from "@fonderie/react-config-admin-screens";
3
3
  import { TemplateEditorScreen, TemplateListScreen } from "@fonderie/react-courier-admin-screens";
4
- import { useState as useState4 } from "react";
4
+ import { useState as useState5 } from "react";
5
5
 
6
6
  // src/styles.ts
7
7
  var styles = {
@@ -309,34 +309,146 @@ function RoutesScreen({ client }) {
309
309
 
310
310
  // src/screens/TokensScreen.tsx
311
311
  import { useAdminTokens } from "@fonderie/react-admin";
312
+ import { useState } from "react";
312
313
  import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
314
+ var ALL = ["read", "write", "secrets"];
313
315
  function TokensScreen({ client }) {
314
- const { report, isLoading, error } = useAdminTokens(client);
316
+ const { report, isLoading, error, issue, revoke } = useAdminTokens(client);
317
+ const [name, setName] = useState("");
318
+ const [scopes, setScopes] = useState(["read"]);
319
+ const [days, setDays] = useState("");
320
+ const [minted, setMinted] = useState(null);
321
+ const toggle = (s) => setScopes((prev) => prev.includes(s) ? prev.filter((x) => x !== s) : [...prev, s]);
315
322
  return /* @__PURE__ */ jsxs7("div", { style: styles.container, children: [
316
323
  /* @__PURE__ */ jsx7("h1", { style: styles.title, children: "Access" }),
317
- isLoading ? /* @__PURE__ */ jsx7("p", { style: styles.status, children: "Loading\u2026" }) : error ? /* @__PURE__ */ jsx7("p", { style: styles.error, role: "alert", children: error.explanation }) : report ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
318
- /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Admin token" }),
319
- /* @__PURE__ */ jsxs7("p", { children: [
320
- report.admin.ok ? /* @__PURE__ */ jsx7("span", { style: styles.ok, children: "strong" }) : /* @__PURE__ */ jsx7("span", { style: styles.bad, children: "weak" }),
321
- report.admin.problems.map((p) => /* @__PURE__ */ jsx7("div", { style: styles.bad, children: p.message }, p.message))
322
- ] }),
323
- /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Legacy per-brick tokens" }),
324
- report.legacy.length === 0 ? /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "None \u2014 every brick's admin surface goes through this token." }) : /* @__PURE__ */ jsx7("ul", { style: styles.list, children: report.legacy.map((l) => /* @__PURE__ */ jsxs7("li", { style: styles.row, children: [
325
- /* @__PURE__ */ jsx7("span", { style: styles.mono, children: l.module }),
324
+ error ? /* @__PURE__ */ jsx7("p", { style: styles.error, role: "alert", children: error.status === 401 ? "Issuing and revoking need the root token (the one in your deployment config)." : error.explanation }) : null,
325
+ /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Root token" }),
326
+ report ? /* @__PURE__ */ jsxs7("p", { children: [
327
+ report.admin.ok ? /* @__PURE__ */ jsx7("span", { style: styles.ok, children: "strong" }) : /* @__PURE__ */ jsx7("span", { style: styles.bad, children: "weak" }),
328
+ report.admin.problems.map((p) => /* @__PURE__ */ jsx7("div", { style: styles.bad, children: p.message }, p.message))
329
+ ] }) : null,
330
+ /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Issued tokens" }),
331
+ report?.issued === null ? /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "Issuing is off \u2014 give AdminModule a store and run its migrations." }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
332
+ minted ? /* @__PURE__ */ jsxs7("p", { style: styles.ok, children: [
333
+ "Copy this now \u2014 it is never shown again.",
326
334
  " ",
327
- /* @__PURE__ */ jsx7("span", { style: styles.muted, children: "still registers its standalone routes with its own token (deprecated)" })
328
- ] }, l.module)) })
329
- ] }) : null
335
+ /* @__PURE__ */ jsx7("span", { style: styles.mono, children: minted.token }),
336
+ " (",
337
+ minted.name,
338
+ ")"
339
+ ] }) : null,
340
+ /* @__PURE__ */ jsxs7(
341
+ "form",
342
+ {
343
+ style: styles.toolbar,
344
+ onSubmit: (e) => {
345
+ e.preventDefault();
346
+ const d = Number(days);
347
+ void issue({
348
+ name: name.trim(),
349
+ scopes,
350
+ ...days && Number.isInteger(d) && d > 0 ? { expiresInDays: d } : {}
351
+ }).then((t) => {
352
+ setMinted({ name: t.name, token: t.token });
353
+ setName("");
354
+ setDays("");
355
+ }).catch(() => {
356
+ });
357
+ },
358
+ children: [
359
+ /* @__PURE__ */ jsx7(
360
+ "input",
361
+ {
362
+ value: name,
363
+ onChange: (e) => setName(e.target.value),
364
+ placeholder: "name",
365
+ style: { ...styles.button, cursor: "text" },
366
+ "aria-label": "Name"
367
+ }
368
+ ),
369
+ ALL.map((s) => /* @__PURE__ */ jsxs7("label", { style: { ...styles.badge, cursor: "pointer" }, children: [
370
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: scopes.includes(s), onChange: () => toggle(s) }),
371
+ " ",
372
+ s
373
+ ] }, s)),
374
+ /* @__PURE__ */ jsx7(
375
+ "input",
376
+ {
377
+ value: days,
378
+ onChange: (e) => setDays(e.target.value),
379
+ placeholder: "days (optional)",
380
+ style: { ...styles.button, cursor: "text", width: 140 },
381
+ "aria-label": "Days"
382
+ }
383
+ ),
384
+ /* @__PURE__ */ jsx7(
385
+ "button",
386
+ {
387
+ type: "submit",
388
+ style: styles.button,
389
+ disabled: !name.trim() || scopes.length === 0 || isLoading,
390
+ children: "Issue"
391
+ }
392
+ )
393
+ ]
394
+ }
395
+ ),
396
+ report?.issued && report.issued.length > 0 ? /* @__PURE__ */ jsxs7("table", { style: styles.table, children: [
397
+ /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsxs7("tr", { children: [
398
+ /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Name" }),
399
+ /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Scopes" }),
400
+ /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Created" }),
401
+ /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Expires" }),
402
+ /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Last used" }),
403
+ /* @__PURE__ */ jsx7("th", { style: styles.th })
404
+ ] }) }),
405
+ /* @__PURE__ */ jsx7("tbody", { children: report.issued.map((t) => /* @__PURE__ */ jsxs7("tr", { children: [
406
+ /* @__PURE__ */ jsxs7("td", { style: styles.td, children: [
407
+ t.name,
408
+ t.revokedAt ? /* @__PURE__ */ jsx7("span", { style: styles.badge, children: " revoked" }) : null
409
+ ] }),
410
+ /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.mono }, children: t.scopes.join(", ") }),
411
+ /* @__PURE__ */ jsxs7("td", { style: { ...styles.td, ...styles.muted }, children: [
412
+ new Date(t.createdAt).toLocaleDateString(),
413
+ " \xB7 ",
414
+ t.createdBy
415
+ ] }),
416
+ /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.muted }, children: t.expiresAt ? new Date(t.expiresAt).toLocaleDateString() : "never" }),
417
+ /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.muted }, children: t.lastUsedAt ? new Date(t.lastUsedAt).toLocaleString() : "never" }),
418
+ /* @__PURE__ */ jsx7("td", { style: styles.td, children: t.revokedAt ? null : /* @__PURE__ */ jsx7(
419
+ "button",
420
+ {
421
+ type: "button",
422
+ style: styles.button,
423
+ onClick: () => {
424
+ if (window.confirm(
425
+ `Revoke "${t.name}"? Anything using it stops working immediately.`
426
+ ))
427
+ void revoke(t.id).catch(() => {
428
+ });
429
+ },
430
+ children: "Revoke"
431
+ }
432
+ ) })
433
+ ] }, t.id)) })
434
+ ] }) : /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "None issued." })
435
+ ] }),
436
+ /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Legacy per-brick tokens" }),
437
+ report && report.legacy.length === 0 ? /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "None \u2014 every brick's admin surface goes through this token." }) : /* @__PURE__ */ jsx7("ul", { style: styles.list, children: report?.legacy.map((l) => /* @__PURE__ */ jsxs7("li", { style: styles.row, children: [
438
+ /* @__PURE__ */ jsx7("span", { style: styles.mono, children: l.module }),
439
+ " ",
440
+ /* @__PURE__ */ jsx7("span", { style: styles.muted, children: "still registers its standalone routes with its own token (deprecated)" })
441
+ ] }, l.module)) })
330
442
  ] });
331
443
  }
332
444
 
333
445
  // src/screens/UsersScreen.tsx
334
446
  import { useAdminLoginHistory, useAdminUser, useAdminUserSessions } from "@fonderie/react-admin";
335
- import { useState } from "react";
447
+ import { useState as useState2 } from "react";
336
448
  import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
337
449
  function UsersScreen({ client }) {
338
- const [input, setInput] = useState("");
339
- const [email, setEmail] = useState(void 0);
450
+ const [input, setInput] = useState2("");
451
+ const [email, setEmail] = useState2(void 0);
340
452
  const { user, isLoading, error, suspend, unsuspend, revokeSessions } = useAdminUser(
341
453
  client,
342
454
  email ? { email } : {}
@@ -546,16 +658,16 @@ function CatalogScreen({ client }) {
546
658
 
547
659
  // src/screens/SubscriberScreen.tsx
548
660
  import { useAdminSubscriber } from "@fonderie/react-admin";
549
- import { useState as useState2 } from "react";
661
+ import { useState as useState3 } from "react";
550
662
  import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
551
663
  function SubscriberScreen({ client }) {
552
- const [type, setType] = useState2("user");
553
- const [idInput, setIdInput] = useState2("");
554
- const [subscriber, setSubscriber] = useState2(null);
664
+ const [type, setType] = useState3("user");
665
+ const [idInput, setIdInput] = useState3("");
666
+ const [subscriber, setSubscriber] = useState3(null);
555
667
  const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(client, subscriber, { limit: 20 });
556
- const [amount, setAmount] = useState2("");
557
- const [note, setNote] = useState2("");
558
- const [granted, setGranted] = useState2(null);
668
+ const [amount, setAmount] = useState3("");
669
+ const [note, setNote] = useState3("");
670
+ const [granted, setGranted] = useState3(null);
559
671
  return /* @__PURE__ */ jsxs10("div", { style: styles.container, children: [
560
672
  /* @__PURE__ */ jsx10("h1", { style: styles.title, children: "Subscriber" }),
561
673
  /* @__PURE__ */ jsxs10(
@@ -720,11 +832,11 @@ function SubscriberScreen({ client }) {
720
832
 
721
833
  // src/screens/AuditScreen.tsx
722
834
  import { useAdminAudit } from "@fonderie/react-admin";
723
- import { useState as useState3 } from "react";
835
+ import { useState as useState4 } from "react";
724
836
  import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
725
837
  function AuditScreen({ client, pageSize = 50 }) {
726
- const [draft, setDraft] = useState3({ workspaceId: "", type: "", actorId: "" });
727
- const [filter, setFilter] = useState3(
838
+ const [draft, setDraft] = useState4({ workspaceId: "", type: "", actorId: "" });
839
+ const [filter, setFilter] = useState4(
728
840
  {}
729
841
  );
730
842
  const { events, hasMore, isLoading, error, refresh, loadMore } = useAdminAudit(client, {
@@ -846,13 +958,13 @@ function AdminShell({
846
958
  page,
847
959
  onNavigate
848
960
  }) {
849
- const [own, setOwn] = useState4("attention");
961
+ const [own, setOwn] = useState5("attention");
850
962
  const current = page ?? own;
851
963
  const go = (p) => {
852
964
  if (onNavigate) onNavigate(p);
853
965
  if (page === void 0) setOwn(p);
854
966
  };
855
- const [editing, setEditing] = useState4(null);
967
+ const [editing, setEditing] = useState5(null);
856
968
  const has = {
857
969
  config: Boolean(configClient),
858
970
  courier: Boolean(courierClient),