@fonderie/vue-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.ts
2
2
  import { ConfigEditorScreen, ConfigListScreen } from "@fonderie/vue-config-admin-screens";
3
3
  import { TemplateEditorScreen, TemplateListScreen } from "@fonderie/vue-courier-admin-screens";
4
- import { computed as computed2, defineComponent as defineComponent12, h as h13, ref as ref4 } from "vue";
4
+ import { computed as computed2, defineComponent as defineComponent12, h as h13, ref as ref5 } from "vue";
5
5
 
6
6
  // src/styles.ts
7
7
  var styles = {
@@ -381,18 +381,29 @@ var RoutesScreen = defineComponent6({
381
381
 
382
382
  // src/screens/TokensScreen.ts
383
383
  import { useAdminTokens } from "@fonderie/vue-admin";
384
- import { defineComponent as defineComponent7, h as h8 } from "vue";
384
+ import { defineComponent as defineComponent7, h as h8, ref } from "vue";
385
+ var ALL = ["read", "write", "secrets"];
385
386
  var TokensScreen = defineComponent7({
386
387
  name: "FonderieTokensScreen",
387
388
  props: { client: { type: Object, required: true } },
388
389
  setup(props) {
389
- const { report, isLoading, error } = useAdminTokens(props.client);
390
- return () => page("Access", { isLoading, error }, () => {
390
+ const { report, isLoading, error, issue, revoke } = useAdminTokens(props.client);
391
+ const name = ref("");
392
+ const scopes = ref(["read"]);
393
+ const days = ref("");
394
+ const minted = ref(null);
395
+ const toggle = (s) => scopes.value = scopes.value.includes(s) ? scopes.value.filter((x) => x !== s) : [...scopes.value, s];
396
+ return () => {
391
397
  const r = report.value;
392
- if (!r) return null;
393
- return [
394
- h8("h2", { style: styles.subtitle }, "Admin token"),
395
- h8("p", [
398
+ return h8("div", { style: styles.container }, [
399
+ h8("h1", { style: styles.title }, "Access"),
400
+ error.value ? h8(
401
+ "p",
402
+ { style: styles.error, role: "alert" },
403
+ error.value.status === 401 ? "Issuing and revoking need the root token (the one in your deployment config)." : error.value.explanation
404
+ ) : null,
405
+ h8("h2", { style: styles.subtitle }, "Root token"),
406
+ r ? h8("p", [
396
407
  h8(
397
408
  "span",
398
409
  { style: r.admin.ok ? styles.ok : styles.bad },
@@ -401,16 +412,124 @@ var TokensScreen = defineComponent7({
401
412
  ...r.admin.problems.map(
402
413
  (p) => h8("div", { key: p.message, style: styles.bad }, p.message)
403
414
  )
404
- ]),
415
+ ]) : null,
416
+ h8("h2", { style: styles.subtitle }, "Issued tokens"),
417
+ r?.issued === null ? h8(
418
+ "p",
419
+ { style: styles.muted },
420
+ "Issuing is off \u2014 give AdminModule a store and run its migrations."
421
+ ) : [
422
+ minted.value ? h8("p", { style: styles.ok }, [
423
+ "Copy this now \u2014 it is never shown again. ",
424
+ h8("span", { style: styles.mono }, minted.value.token),
425
+ ` (${minted.value.name})`
426
+ ]) : null,
427
+ h8(
428
+ "form",
429
+ {
430
+ style: styles.toolbar,
431
+ onSubmit: (e) => {
432
+ e.preventDefault();
433
+ const d = Number(days.value);
434
+ void issue({
435
+ name: name.value.trim(),
436
+ scopes: scopes.value,
437
+ ...days.value && Number.isInteger(d) && d > 0 ? { expiresInDays: d } : {}
438
+ }).then((t) => {
439
+ minted.value = { name: t.name, token: t.token };
440
+ name.value = "";
441
+ days.value = "";
442
+ }).catch(() => {
443
+ });
444
+ }
445
+ },
446
+ [
447
+ h8("input", {
448
+ value: name.value,
449
+ onInput: (e) => name.value = e.target.value,
450
+ placeholder: "name",
451
+ style: { ...styles.button, cursor: "text" },
452
+ "aria-label": "Name"
453
+ }),
454
+ ...ALL.map(
455
+ (s) => h8("label", { key: s, style: { ...styles.badge, cursor: "pointer" } }, [
456
+ h8("input", {
457
+ type: "checkbox",
458
+ checked: scopes.value.includes(s),
459
+ onChange: () => toggle(s)
460
+ }),
461
+ ` ${s}`
462
+ ])
463
+ ),
464
+ h8("input", {
465
+ value: days.value,
466
+ onInput: (e) => days.value = e.target.value,
467
+ placeholder: "days (optional)",
468
+ style: { ...styles.button, cursor: "text", width: "140px" },
469
+ "aria-label": "Days"
470
+ }),
471
+ h8(
472
+ "button",
473
+ {
474
+ type: "submit",
475
+ style: styles.button,
476
+ disabled: !name.value.trim() || scopes.value.length === 0 || isLoading.value
477
+ },
478
+ "Issue"
479
+ )
480
+ ]
481
+ ),
482
+ r?.issued && r.issued.length > 0 ? table(
483
+ ["Name", "Scopes", "Created", "Expires", "Last used", ""],
484
+ r.issued.map(
485
+ (t) => h8("tr", { key: t.id }, [
486
+ td([
487
+ t.name,
488
+ t.revokedAt ? h8("span", { style: styles.badge }, " revoked") : ""
489
+ ]),
490
+ td(t.scopes.join(", "), styles.mono),
491
+ td(
492
+ `${new Date(t.createdAt).toLocaleDateString()} \xB7 ${t.createdBy}`,
493
+ styles.muted
494
+ ),
495
+ td(
496
+ t.expiresAt ? new Date(t.expiresAt).toLocaleDateString() : "never",
497
+ styles.muted
498
+ ),
499
+ td(
500
+ t.lastUsedAt ? new Date(t.lastUsedAt).toLocaleString() : "never",
501
+ styles.muted
502
+ ),
503
+ td(
504
+ t.revokedAt ? "" : h8(
505
+ "button",
506
+ {
507
+ type: "button",
508
+ style: styles.button,
509
+ onClick: () => {
510
+ if (window.confirm(
511
+ `Revoke "${t.name}"? Anything using it stops working immediately.`
512
+ ))
513
+ void revoke(t.id).catch(() => {
514
+ });
515
+ }
516
+ },
517
+ "Revoke"
518
+ )
519
+ )
520
+ ])
521
+ )
522
+ ) : h8("p", { style: styles.muted }, "None issued.")
523
+ ],
405
524
  h8("h2", { style: styles.subtitle }, "Legacy per-brick tokens"),
406
- r.legacy.length === 0 ? h8(
525
+ r && r.legacy.length === 0 ? h8(
407
526
  "p",
408
527
  { style: styles.muted },
409
528
  "None \u2014 every brick's admin surface goes through this token."
410
529
  ) : h8(
411
530
  "ul",
412
531
  { style: styles.list },
413
- r.legacy.map(
532
+ (r?.legacy ?? []).map(
414
533
  (l) => h8("li", { key: l.module, style: styles.row }, [
415
534
  h8("span", { style: styles.mono }, l.module),
416
535
  " ",
@@ -422,20 +541,20 @@ var TokensScreen = defineComponent7({
422
541
  ])
423
542
  )
424
543
  )
425
- ];
426
- });
544
+ ]);
545
+ };
427
546
  }
428
547
  });
429
548
 
430
549
  // src/screens/UsersScreen.ts
431
550
  import { useAdminLoginHistory, useAdminUser, useAdminUserSessions } from "@fonderie/vue-admin";
432
- import { computed, defineComponent as defineComponent8, h as h9, ref } from "vue";
551
+ import { computed, defineComponent as defineComponent8, h as h9, ref as ref2 } from "vue";
433
552
  var UsersScreen = defineComponent8({
434
553
  name: "FonderieUsersScreen",
435
554
  props: { client: { type: Object, required: true } },
436
555
  setup(props) {
437
- const input = ref("");
438
- const email = ref("");
556
+ const input = ref2("");
557
+ const email = ref2("");
439
558
  const { user, isLoading, error, suspend, unsuspend, revokeSessions } = useAdminUser(
440
559
  props.client,
441
560
  { email }
@@ -633,18 +752,18 @@ var CatalogScreen = defineComponent9({
633
752
 
634
753
  // src/screens/SubscriberScreen.ts
635
754
  import { useAdminSubscriber } from "@fonderie/vue-admin";
636
- import { defineComponent as defineComponent10, h as h11, ref as ref2 } from "vue";
755
+ import { defineComponent as defineComponent10, h as h11, ref as ref3 } from "vue";
637
756
  var SubscriberScreen = defineComponent10({
638
757
  name: "FonderieSubscriberScreen",
639
758
  props: { client: { type: Object, required: true } },
640
759
  setup(props) {
641
- const type = ref2("user");
642
- const idInput = ref2("");
643
- const subscriber = ref2(null);
760
+ const type = ref3("user");
761
+ const idInput = ref3("");
762
+ const subscriber = ref3(null);
644
763
  const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(props.client, subscriber, { limit: 20 });
645
- const amount = ref2("");
646
- const note = ref2("");
647
- const granted = ref2(null);
764
+ const amount = ref3("");
765
+ const note = ref3("");
766
+ const granted = ref3(null);
648
767
  const input = (model, placeholder, extra = {}) => h11("input", {
649
768
  value: model.value,
650
769
  onInput: (e) => model.value = e.target.value,
@@ -790,7 +909,7 @@ var SubscriberScreen = defineComponent10({
790
909
 
791
910
  // src/screens/AuditScreen.ts
792
911
  import { useAdminAudit } from "@fonderie/vue-admin";
793
- import { defineComponent as defineComponent11, h as h12, ref as ref3 } from "vue";
912
+ import { defineComponent as defineComponent11, h as h12, ref as ref4 } from "vue";
794
913
  var AuditScreen = defineComponent11({
795
914
  name: "FonderieAuditScreen",
796
915
  props: {
@@ -798,8 +917,8 @@ var AuditScreen = defineComponent11({
798
917
  pageSize: { type: Number, default: 50 }
799
918
  },
800
919
  setup(props) {
801
- const draft = ref3({ workspaceId: "", type: "", actorId: "" });
802
- const query = ref3({ limit: props.pageSize });
920
+ const draft = ref4({ workspaceId: "", type: "", actorId: "" });
921
+ const query = ref4({ limit: props.pageSize });
803
922
  const { events, hasMore, isLoading, error, refresh, loadMore } = useAdminAudit(
804
923
  props.client,
805
924
  query
@@ -919,9 +1038,9 @@ var AdminShell = defineComponent12({
919
1038
  },
920
1039
  emits: { navigate: (_page) => true },
921
1040
  setup(props, { emit }) {
922
- const own = ref4("attention");
1041
+ const own = ref5("attention");
923
1042
  const current = computed2(() => props.page ?? own.value);
924
- const editing = ref4(null);
1043
+ const editing = ref5(null);
925
1044
  const go = (p) => {
926
1045
  editing.value = null;
927
1046
  emit("navigate", p);