@fonderie/vue-admin-screens 0.4.0 → 0.6.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/README.md +8 -1
- package/dist/index.cjs +255 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +282 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.js +279 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
-
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
|
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,29 +541,45 @@ 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
|
-
import {
|
|
432
|
-
|
|
550
|
+
import {
|
|
551
|
+
useAdminLoginHistory,
|
|
552
|
+
useAdminUser,
|
|
553
|
+
useAdminUserSessions,
|
|
554
|
+
useAdminUsers
|
|
555
|
+
} from "@fonderie/vue-admin";
|
|
556
|
+
import { computed, defineComponent as defineComponent8, h as h9, ref as ref2 } from "vue";
|
|
433
557
|
var UsersScreen = defineComponent8({
|
|
434
558
|
name: "FonderieUsersScreen",
|
|
435
|
-
props: {
|
|
559
|
+
props: {
|
|
560
|
+
client: { type: Object, required: true },
|
|
561
|
+
pageSize: { type: Number, default: 50 }
|
|
562
|
+
},
|
|
436
563
|
setup(props) {
|
|
437
|
-
const input =
|
|
438
|
-
const email =
|
|
564
|
+
const input = ref2("");
|
|
565
|
+
const email = ref2("");
|
|
566
|
+
const selectedId = ref2("");
|
|
567
|
+
const list = useAdminUsers(props.client, { limit: props.pageSize });
|
|
439
568
|
const { user, isLoading, error, suspend, unsuspend, revokeSessions } = useAdminUser(
|
|
440
569
|
props.client,
|
|
441
|
-
{ email }
|
|
570
|
+
{ email, id: selectedId }
|
|
442
571
|
);
|
|
443
572
|
const userId = computed(() => user.value?.id ?? null);
|
|
444
573
|
const sessions = useAdminUserSessions(props.client, userId);
|
|
445
574
|
const history = useAdminLoginHistory(props.client, userId, { limit: 20 });
|
|
575
|
+
const showList = computed(() => !email.value && !selectedId.value);
|
|
446
576
|
const yesNo = (v) => h9("span", { style: v ? styles.ok : styles.muted }, v ? "yes" : "no");
|
|
447
577
|
const row = (k, v) => h9("tr", [td(k), td(v)]);
|
|
578
|
+
const clear = () => {
|
|
579
|
+
email.value = "";
|
|
580
|
+
selectedId.value = "";
|
|
581
|
+
input.value = "";
|
|
582
|
+
};
|
|
448
583
|
return () => {
|
|
449
584
|
const u = user.value;
|
|
450
585
|
return h9("div", { style: styles.container }, [
|
|
@@ -455,6 +590,7 @@ var UsersScreen = defineComponent8({
|
|
|
455
590
|
style: styles.toolbar,
|
|
456
591
|
onSubmit: (e) => {
|
|
457
592
|
e.preventDefault();
|
|
593
|
+
selectedId.value = "";
|
|
458
594
|
email.value = input.value.trim();
|
|
459
595
|
}
|
|
460
596
|
},
|
|
@@ -471,9 +607,48 @@ var UsersScreen = defineComponent8({
|
|
|
471
607
|
"button",
|
|
472
608
|
{ type: "submit", style: styles.button, disabled: isLoading.value },
|
|
473
609
|
"Look up"
|
|
474
|
-
)
|
|
610
|
+
),
|
|
611
|
+
showList.value ? refreshButton("Refresh", list.isLoading.value, () => void list.refresh()) : refreshButton("\u2190 All users", false, clear)
|
|
475
612
|
]
|
|
476
613
|
),
|
|
614
|
+
showList.value ? h9("div", [
|
|
615
|
+
list.error.value ? h9("p", { style: styles.error, role: "alert" }, list.error.value.explanation) : null,
|
|
616
|
+
list.users.value.length === 0 && !list.isLoading.value ? h9("p", { style: styles.muted }, "No users yet.") : table(
|
|
617
|
+
["Email", "Name", "Created", "Status"],
|
|
618
|
+
list.users.value.map(
|
|
619
|
+
(u2) => h9("tr", { key: u2.id }, [
|
|
620
|
+
td(
|
|
621
|
+
h9(
|
|
622
|
+
"button",
|
|
623
|
+
{
|
|
624
|
+
type: "button",
|
|
625
|
+
style: { ...styles.navItem, padding: 0 },
|
|
626
|
+
onClick: () => selectedId.value = u2.id
|
|
627
|
+
},
|
|
628
|
+
u2.email
|
|
629
|
+
)
|
|
630
|
+
),
|
|
631
|
+
td(
|
|
632
|
+
`${u2.firstName ?? ""} ${u2.lastName ?? ""}`.trim() || h9("span", { style: styles.muted }, "\u2014")
|
|
633
|
+
),
|
|
634
|
+
td(new Date(u2.createdAt).toLocaleDateString()),
|
|
635
|
+
td(
|
|
636
|
+
u2.suspended ? h9("span", { style: styles.badge }, "suspended") : u2.deletedAt ? h9("span", { style: styles.badge }, "deleted") : h9("span", { style: styles.muted }, "active")
|
|
637
|
+
)
|
|
638
|
+
])
|
|
639
|
+
)
|
|
640
|
+
),
|
|
641
|
+
list.isLoading.value ? h9("p", { style: styles.status }, "Loading\u2026") : null,
|
|
642
|
+
list.hasMore.value && !list.isLoading.value ? h9(
|
|
643
|
+
"button",
|
|
644
|
+
{
|
|
645
|
+
type: "button",
|
|
646
|
+
style: { ...styles.button, marginTop: "8px" },
|
|
647
|
+
onClick: () => void list.loadMore()
|
|
648
|
+
},
|
|
649
|
+
"Load more"
|
|
650
|
+
) : null
|
|
651
|
+
]) : null,
|
|
477
652
|
error.value ? h9(
|
|
478
653
|
"p",
|
|
479
654
|
{ style: styles.error, role: "alert" },
|
|
@@ -632,19 +807,29 @@ var CatalogScreen = defineComponent9({
|
|
|
632
807
|
});
|
|
633
808
|
|
|
634
809
|
// src/screens/SubscriberScreen.ts
|
|
635
|
-
import { useAdminSubscriber } from "@fonderie/vue-admin";
|
|
636
|
-
import { defineComponent as defineComponent10, h as h11, ref as
|
|
810
|
+
import { useAdminSubscriber, useAdminSubscribers } from "@fonderie/vue-admin";
|
|
811
|
+
import { defineComponent as defineComponent10, h as h11, ref as ref3 } from "vue";
|
|
637
812
|
var SubscriberScreen = defineComponent10({
|
|
638
813
|
name: "FonderieSubscriberScreen",
|
|
639
|
-
props: {
|
|
814
|
+
props: {
|
|
815
|
+
client: { type: Object, required: true },
|
|
816
|
+
pageSize: { type: Number, default: 50 }
|
|
817
|
+
},
|
|
640
818
|
setup(props) {
|
|
641
|
-
const type =
|
|
642
|
-
const idInput =
|
|
643
|
-
const subscriber =
|
|
819
|
+
const type = ref3("user");
|
|
820
|
+
const idInput = ref3("");
|
|
821
|
+
const subscriber = ref3(null);
|
|
822
|
+
const list = useAdminSubscribers(props.client, { limit: props.pageSize });
|
|
644
823
|
const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(props.client, subscriber, { limit: 20 });
|
|
645
|
-
const
|
|
646
|
-
|
|
647
|
-
|
|
824
|
+
const open = (t, id) => {
|
|
825
|
+
granted.value = null;
|
|
826
|
+
type.value = t;
|
|
827
|
+
idInput.value = id;
|
|
828
|
+
subscriber.value = { type: t, id };
|
|
829
|
+
};
|
|
830
|
+
const amount = ref3("");
|
|
831
|
+
const note = ref3("");
|
|
832
|
+
const granted = ref3(null);
|
|
648
833
|
const input = (model, placeholder, extra = {}) => h11("input", {
|
|
649
834
|
value: model.value,
|
|
650
835
|
onInput: (e) => model.value = e.target.value,
|
|
@@ -686,9 +871,69 @@ var SubscriberScreen = defineComponent10({
|
|
|
686
871
|
"button",
|
|
687
872
|
{ type: "submit", style: styles.button, disabled: isLoading.value },
|
|
688
873
|
"Look up"
|
|
874
|
+
),
|
|
875
|
+
subscriber.value ? h11(
|
|
876
|
+
"button",
|
|
877
|
+
{
|
|
878
|
+
type: "button",
|
|
879
|
+
style: styles.button,
|
|
880
|
+
onClick: () => {
|
|
881
|
+
subscriber.value = null;
|
|
882
|
+
idInput.value = "";
|
|
883
|
+
granted.value = null;
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
"\u2190 All subscribers"
|
|
887
|
+
) : h11(
|
|
888
|
+
"button",
|
|
889
|
+
{
|
|
890
|
+
type: "button",
|
|
891
|
+
style: styles.button,
|
|
892
|
+
disabled: list.isLoading.value,
|
|
893
|
+
onClick: () => void list.refresh()
|
|
894
|
+
},
|
|
895
|
+
"Refresh"
|
|
689
896
|
)
|
|
690
897
|
]
|
|
691
898
|
),
|
|
899
|
+
!subscriber.value ? h11("div", [
|
|
900
|
+
list.error.value ? h11("p", { style: styles.error, role: "alert" }, list.error.value.explanation) : null,
|
|
901
|
+
list.subscriptions.value.length === 0 && !list.isLoading.value ? h11("p", { style: styles.muted }, "No subscribers yet.") : table(
|
|
902
|
+
["Subscriber", "Plan", "Status", "Renews"],
|
|
903
|
+
list.subscriptions.value.map(
|
|
904
|
+
(sub) => h11("tr", { key: sub.id }, [
|
|
905
|
+
td(
|
|
906
|
+
h11(
|
|
907
|
+
"button",
|
|
908
|
+
{
|
|
909
|
+
type: "button",
|
|
910
|
+
style: { ...styles.navItem, padding: 0, ...styles.mono },
|
|
911
|
+
onClick: () => open(sub.subscriberType, sub.subscriberId)
|
|
912
|
+
},
|
|
913
|
+
`${sub.subscriberType}/${sub.subscriberId}`
|
|
914
|
+
)
|
|
915
|
+
),
|
|
916
|
+
td(`${sub.plan} \xB7 ${sub.interval}`),
|
|
917
|
+
td(
|
|
918
|
+
sub.cancelAtPeriodEnd ? [sub.status, " ", h11("span", { style: styles.badge }, "cancels")] : sub.status
|
|
919
|
+
),
|
|
920
|
+
td(
|
|
921
|
+
sub.currentPeriodEnd ? new Date(sub.currentPeriodEnd).toLocaleDateString() : h11("span", { style: styles.muted }, "\u2014")
|
|
922
|
+
)
|
|
923
|
+
])
|
|
924
|
+
)
|
|
925
|
+
),
|
|
926
|
+
list.isLoading.value ? h11("p", { style: styles.status }, "Loading\u2026") : null,
|
|
927
|
+
list.hasMore.value && !list.isLoading.value ? h11(
|
|
928
|
+
"button",
|
|
929
|
+
{
|
|
930
|
+
type: "button",
|
|
931
|
+
style: { ...styles.button, marginTop: "8px" },
|
|
932
|
+
onClick: () => void list.loadMore()
|
|
933
|
+
},
|
|
934
|
+
"Load more"
|
|
935
|
+
) : null
|
|
936
|
+
]) : null,
|
|
692
937
|
error.value ? h11("p", { style: styles.error, role: "alert" }, error.value.explanation) : null,
|
|
693
938
|
subscriber.value && !isLoading.value ? [
|
|
694
939
|
h11("h2", { style: styles.subtitle }, "Subscription"),
|
|
@@ -790,7 +1035,7 @@ var SubscriberScreen = defineComponent10({
|
|
|
790
1035
|
|
|
791
1036
|
// src/screens/AuditScreen.ts
|
|
792
1037
|
import { useAdminAudit } from "@fonderie/vue-admin";
|
|
793
|
-
import { defineComponent as defineComponent11, h as h12, ref as
|
|
1038
|
+
import { defineComponent as defineComponent11, h as h12, ref as ref4 } from "vue";
|
|
794
1039
|
var AuditScreen = defineComponent11({
|
|
795
1040
|
name: "FonderieAuditScreen",
|
|
796
1041
|
props: {
|
|
@@ -798,8 +1043,8 @@ var AuditScreen = defineComponent11({
|
|
|
798
1043
|
pageSize: { type: Number, default: 50 }
|
|
799
1044
|
},
|
|
800
1045
|
setup(props) {
|
|
801
|
-
const draft =
|
|
802
|
-
const query =
|
|
1046
|
+
const draft = ref4({ workspaceId: "", type: "", actorId: "" });
|
|
1047
|
+
const query = ref4({ limit: props.pageSize });
|
|
803
1048
|
const { events, hasMore, isLoading, error, refresh, loadMore } = useAdminAudit(
|
|
804
1049
|
props.client,
|
|
805
1050
|
query
|
|
@@ -919,9 +1164,9 @@ var AdminShell = defineComponent12({
|
|
|
919
1164
|
},
|
|
920
1165
|
emits: { navigate: (_page) => true },
|
|
921
1166
|
setup(props, { emit }) {
|
|
922
|
-
const own =
|
|
1167
|
+
const own = ref5("attention");
|
|
923
1168
|
const current = computed2(() => props.page ?? own.value);
|
|
924
|
-
const editing =
|
|
1169
|
+
const editing = ref5(null);
|
|
925
1170
|
const go = (p) => {
|
|
926
1171
|
editing.value = null;
|
|
927
1172
|
emit("navigate", p);
|