@fonderie/vue-admin-screens 0.2.0 → 0.4.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 +6 -3
- package/dist/index.cjs +369 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +365 -26
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -11,12 +11,13 @@ Status: **experimental** (0.x).
|
|
|
11
11
|
| Today | Attention | what needs me today — empty is green |
|
|
12
12
|
| System | Modules · Configuration · Doctor · Routes | what did I deploy · is it configured · is it working · what is exposed |
|
|
13
13
|
| People | Users | why can't this person log in — lookup, sessions, sign-ins, suspend, sign out everywhere (`authClient`) |
|
|
14
|
+
| Money | Catalog · Subscriber | what am I selling (configured vs stored) · what is this subscriber on, their wallet, ledger, a manual grant (`billingClient`) |
|
|
14
15
|
| Settings | Config & secrets | the `@fonderie/config` admin screens, as a sub-page |
|
|
15
16
|
| Messaging | Templates | the `@fonderie/courier` admin screens, as a sub-page |
|
|
16
|
-
| Activity | Admin log · Access | who did what · who can be here |
|
|
17
|
+
| Activity | Audit · Admin log · Access | what happened, every workspace (`auditClient`) · who did what through here · who can be here |
|
|
17
18
|
|
|
18
19
|
```ts
|
|
19
|
-
import { AdminClient, AuthAdminClient, ConfigAdminClient, CourierAdminClient } from '@fonderie/client';
|
|
20
|
+
import { AdminClient, AuditAdminClient, AuthAdminClient, BillingAdminClient, ConfigAdminClient, CourierAdminClient } from '@fonderie/client';
|
|
20
21
|
import { AdminShell } from '@fonderie/vue-admin-screens';
|
|
21
22
|
|
|
22
23
|
const base = { baseUrl: 'https://api.example.com', adminToken, actor: 'louis' };
|
|
@@ -25,10 +26,12 @@ const client = new AdminClient(base);
|
|
|
25
26
|
const configClient = new ConfigAdminClient({ ...base, prefix: '/_admin' });
|
|
26
27
|
const courierClient = new CourierAdminClient({ ...base, prefix: '/_admin' });
|
|
27
28
|
const authClient = new AuthAdminClient(base); // @fonderie/auth ≥ 7.8
|
|
29
|
+
const billingClient = new BillingAdminClient(base); // @fonderie/billing ≥ 9.10
|
|
30
|
+
const auditClient = new AuditAdminClient(base); // @fonderie/audit ≥ 5.2
|
|
28
31
|
```
|
|
29
32
|
|
|
30
33
|
```ts
|
|
31
|
-
h(AdminShell, { client, configClient, courierClient, authClient })
|
|
34
|
+
h(AdminShell, { client, configClient, courierClient, authClient, billingClient, auditClient })
|
|
32
35
|
```
|
|
33
36
|
|
|
34
37
|
Pass `page` and listen to `navigate` to own the URL (one route per page);
|
package/dist/index.cjs
CHANGED
|
@@ -23,10 +23,13 @@ __export(index_exports, {
|
|
|
23
23
|
AdminLogScreen: () => AdminLogScreen,
|
|
24
24
|
AdminShell: () => AdminShell,
|
|
25
25
|
AttentionScreen: () => AttentionScreen,
|
|
26
|
+
AuditScreen: () => AuditScreen,
|
|
27
|
+
CatalogScreen: () => CatalogScreen,
|
|
26
28
|
ConfigScreen: () => ConfigScreen,
|
|
27
29
|
DoctorScreen: () => DoctorScreen,
|
|
28
30
|
ModulesScreen: () => ModulesScreen,
|
|
29
31
|
RoutesScreen: () => RoutesScreen,
|
|
32
|
+
SubscriberScreen: () => SubscriberScreen,
|
|
30
33
|
TokensScreen: () => TokensScreen,
|
|
31
34
|
UsersScreen: () => UsersScreen
|
|
32
35
|
});
|
|
@@ -35,7 +38,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
35
38
|
// src/screens/AdminShell.ts
|
|
36
39
|
var import_vue_config_admin_screens = require("@fonderie/vue-config-admin-screens");
|
|
37
40
|
var import_vue_courier_admin_screens = require("@fonderie/vue-courier-admin-screens");
|
|
38
|
-
var
|
|
41
|
+
var import_vue13 = require("vue");
|
|
39
42
|
|
|
40
43
|
// src/styles.ts
|
|
41
44
|
var styles = {
|
|
@@ -595,6 +598,312 @@ var UsersScreen = (0, import_vue9.defineComponent)({
|
|
|
595
598
|
}
|
|
596
599
|
});
|
|
597
600
|
|
|
601
|
+
// src/screens/CatalogScreen.ts
|
|
602
|
+
var import_vue_admin9 = require("@fonderie/vue-admin");
|
|
603
|
+
var import_vue10 = require("vue");
|
|
604
|
+
var CatalogScreen = (0, import_vue10.defineComponent)({
|
|
605
|
+
name: "FonderieCatalogScreen",
|
|
606
|
+
props: { client: { type: Object, required: true } },
|
|
607
|
+
setup(props) {
|
|
608
|
+
const { catalog, isLoading, error, refresh, deletePlan } = (0, import_vue_admin9.useAdminCatalog)(props.client);
|
|
609
|
+
const money = (v) => v == null ? "\u2014" : (v / 100).toFixed(2);
|
|
610
|
+
return () => {
|
|
611
|
+
const c = catalog.value;
|
|
612
|
+
return (0, import_vue10.h)("div", { style: styles.container }, [
|
|
613
|
+
(0, import_vue10.h)("div", { style: styles.toolbar }, [
|
|
614
|
+
(0, import_vue10.h)("h1", { style: { ...styles.title, marginBottom: 0 } }, "Catalog"),
|
|
615
|
+
refreshButton("Refresh", isLoading.value, () => void refresh())
|
|
616
|
+
]),
|
|
617
|
+
error.value ? (0, import_vue10.h)("p", { style: styles.error, role: "alert" }, error.value.explanation) : null,
|
|
618
|
+
isLoading.value && !c ? (0, import_vue10.h)("p", { style: styles.status }, "Loading\u2026") : null,
|
|
619
|
+
c ? [
|
|
620
|
+
(0, import_vue10.h)("h2", { style: styles.subtitle }, "Configured (code)"),
|
|
621
|
+
(0, import_vue10.h)(
|
|
622
|
+
"pre",
|
|
623
|
+
{
|
|
624
|
+
style: {
|
|
625
|
+
...styles.mono,
|
|
626
|
+
background: "#f9fafb",
|
|
627
|
+
padding: "12px",
|
|
628
|
+
overflowX: "auto"
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
JSON.stringify(c.configured, null, 2)
|
|
632
|
+
),
|
|
633
|
+
(0, import_vue10.h)("h2", { style: styles.subtitle }, "Stored (database)"),
|
|
634
|
+
c.stored.length === 0 ? (0, import_vue10.h)("p", { style: styles.muted }, "No stored plans.") : table(
|
|
635
|
+
["Plan", "Tier", "Seats", "Monthly", "Yearly", "Trial", ""],
|
|
636
|
+
c.stored.map(
|
|
637
|
+
(p) => (0, import_vue10.h)("tr", { key: p.id }, [
|
|
638
|
+
td([
|
|
639
|
+
(0, import_vue10.h)("strong", p.name),
|
|
640
|
+
p.description ? (0, import_vue10.h)("div", { style: styles.muted }, p.description) : ""
|
|
641
|
+
]),
|
|
642
|
+
td(String(p.tier)),
|
|
643
|
+
td(p.seats == null ? "\u221E" : String(p.seats)),
|
|
644
|
+
td(`${money(p.pricing?.monthly)} ${p.pricing?.currency ?? ""}`),
|
|
645
|
+
td(money(p.pricing?.yearly)),
|
|
646
|
+
td(p.trialDays ? `${p.trialDays} d` : "\u2014"),
|
|
647
|
+
td(
|
|
648
|
+
(0, import_vue10.h)(
|
|
649
|
+
"button",
|
|
650
|
+
{
|
|
651
|
+
type: "button",
|
|
652
|
+
style: styles.button,
|
|
653
|
+
onClick: () => {
|
|
654
|
+
if (window.confirm(`Delete stored plan "${p.name}"?`))
|
|
655
|
+
void deletePlan(p.id).catch(() => {
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
},
|
|
659
|
+
"Delete"
|
|
660
|
+
)
|
|
661
|
+
)
|
|
662
|
+
])
|
|
663
|
+
)
|
|
664
|
+
)
|
|
665
|
+
] : null
|
|
666
|
+
]);
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
// src/screens/SubscriberScreen.ts
|
|
672
|
+
var import_vue_admin10 = require("@fonderie/vue-admin");
|
|
673
|
+
var import_vue11 = require("vue");
|
|
674
|
+
var SubscriberScreen = (0, import_vue11.defineComponent)({
|
|
675
|
+
name: "FonderieSubscriberScreen",
|
|
676
|
+
props: { client: { type: Object, required: true } },
|
|
677
|
+
setup(props) {
|
|
678
|
+
const type = (0, import_vue11.ref)("user");
|
|
679
|
+
const idInput = (0, import_vue11.ref)("");
|
|
680
|
+
const subscriber = (0, import_vue11.ref)(null);
|
|
681
|
+
const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = (0, import_vue_admin10.useAdminSubscriber)(props.client, subscriber, { limit: 20 });
|
|
682
|
+
const amount = (0, import_vue11.ref)("");
|
|
683
|
+
const note = (0, import_vue11.ref)("");
|
|
684
|
+
const granted = (0, import_vue11.ref)(null);
|
|
685
|
+
const input = (model, placeholder, extra = {}) => (0, import_vue11.h)("input", {
|
|
686
|
+
value: model.value,
|
|
687
|
+
onInput: (e) => model.value = e.target.value,
|
|
688
|
+
placeholder,
|
|
689
|
+
style: { ...styles.button, cursor: "text", ...extra },
|
|
690
|
+
"aria-label": placeholder
|
|
691
|
+
});
|
|
692
|
+
return () => {
|
|
693
|
+
const s = subscription.value;
|
|
694
|
+
const w = wallet.value;
|
|
695
|
+
return (0, import_vue11.h)("div", { style: styles.container }, [
|
|
696
|
+
(0, import_vue11.h)("h1", { style: styles.title }, "Subscriber"),
|
|
697
|
+
(0, import_vue11.h)(
|
|
698
|
+
"form",
|
|
699
|
+
{
|
|
700
|
+
style: styles.toolbar,
|
|
701
|
+
onSubmit: (e) => {
|
|
702
|
+
e.preventDefault();
|
|
703
|
+
granted.value = null;
|
|
704
|
+
subscriber.value = idInput.value.trim() ? { type: type.value, id: idInput.value.trim() } : null;
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
[
|
|
708
|
+
(0, import_vue11.h)(
|
|
709
|
+
"select",
|
|
710
|
+
{
|
|
711
|
+
value: type.value,
|
|
712
|
+
onChange: (e) => type.value = e.target.value,
|
|
713
|
+
style: styles.button,
|
|
714
|
+
"aria-label": "Type"
|
|
715
|
+
},
|
|
716
|
+
[
|
|
717
|
+
(0, import_vue11.h)("option", { value: "user" }, "user"),
|
|
718
|
+
(0, import_vue11.h)("option", { value: "workspace" }, "workspace")
|
|
719
|
+
]
|
|
720
|
+
),
|
|
721
|
+
input(idInput, "subscriber id", { minWidth: "280px" }),
|
|
722
|
+
(0, import_vue11.h)(
|
|
723
|
+
"button",
|
|
724
|
+
{ type: "submit", style: styles.button, disabled: isLoading.value },
|
|
725
|
+
"Look up"
|
|
726
|
+
)
|
|
727
|
+
]
|
|
728
|
+
),
|
|
729
|
+
error.value ? (0, import_vue11.h)("p", { style: styles.error, role: "alert" }, error.value.explanation) : null,
|
|
730
|
+
subscriber.value && !isLoading.value ? [
|
|
731
|
+
(0, import_vue11.h)("h2", { style: styles.subtitle }, "Subscription"),
|
|
732
|
+
s ? (0, import_vue11.h)("table", { style: styles.table }, [
|
|
733
|
+
(0, import_vue11.h)("tbody", [
|
|
734
|
+
(0, import_vue11.h)("tr", [td("plan"), td([(0, import_vue11.h)("strong", s.plan), ` \xB7 ${s.interval}`])]),
|
|
735
|
+
(0, import_vue11.h)("tr", [
|
|
736
|
+
td("status"),
|
|
737
|
+
td(`${s.status}${s.cancelAtPeriodEnd ? " \xB7 cancels at period end" : ""}`)
|
|
738
|
+
]),
|
|
739
|
+
(0, import_vue11.h)("tr", [
|
|
740
|
+
td("period"),
|
|
741
|
+
td(
|
|
742
|
+
`${s.currentPeriodStart ? new Date(s.currentPeriodStart).toLocaleDateString() : "\u2014"} \u2192 ${s.currentPeriodEnd ? new Date(s.currentPeriodEnd).toLocaleDateString() : "\u2014"}`
|
|
743
|
+
)
|
|
744
|
+
]),
|
|
745
|
+
(0, import_vue11.h)("tr", [td("provider"), td(s.providerSubscriptionId ?? "\u2014", styles.mono)])
|
|
746
|
+
])
|
|
747
|
+
]) : (0, import_vue11.h)("p", { style: styles.muted }, "No subscription."),
|
|
748
|
+
(0, import_vue11.h)("h2", { style: styles.subtitle }, "Wallet"),
|
|
749
|
+
w ? [
|
|
750
|
+
(0, import_vue11.h)("p", [
|
|
751
|
+
(0, import_vue11.h)("strong", w.balance),
|
|
752
|
+
` ${w.currency} `,
|
|
753
|
+
(0, import_vue11.h)(
|
|
754
|
+
"span",
|
|
755
|
+
{ style: styles.muted },
|
|
756
|
+
`(granted ${w.granted ?? "0"} \xB7 purchased ${w.purchased ?? "0"}) \xB7 minor units, precision ${w.precision}`
|
|
757
|
+
)
|
|
758
|
+
]),
|
|
759
|
+
(0, import_vue11.h)(
|
|
760
|
+
"form",
|
|
761
|
+
{
|
|
762
|
+
style: styles.toolbar,
|
|
763
|
+
onSubmit: (e) => {
|
|
764
|
+
e.preventDefault();
|
|
765
|
+
const sub = subscriber.value;
|
|
766
|
+
if (!sub) return;
|
|
767
|
+
const key = `admin-grant-${sub.type}-${sub.id}-${Date.now()}`;
|
|
768
|
+
const amt = amount.value.trim();
|
|
769
|
+
void grant({
|
|
770
|
+
amount: amt,
|
|
771
|
+
...note.value ? { description: note.value } : {},
|
|
772
|
+
idempotencyKey: key
|
|
773
|
+
}).then(() => {
|
|
774
|
+
granted.value = `Granted ${amt} ${w.currency}.`;
|
|
775
|
+
amount.value = "";
|
|
776
|
+
note.value = "";
|
|
777
|
+
}).catch(() => {
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
[
|
|
782
|
+
input(amount, "amount (minor units)"),
|
|
783
|
+
input(note, "reason (optional)", { minWidth: "220px" }),
|
|
784
|
+
(0, import_vue11.h)(
|
|
785
|
+
"button",
|
|
786
|
+
{
|
|
787
|
+
type: "submit",
|
|
788
|
+
style: styles.button,
|
|
789
|
+
disabled: !/^\d+$/.test(amount.value.trim())
|
|
790
|
+
},
|
|
791
|
+
"Grant"
|
|
792
|
+
),
|
|
793
|
+
granted.value ? (0, import_vue11.h)("span", { style: styles.ok }, granted.value) : null
|
|
794
|
+
]
|
|
795
|
+
),
|
|
796
|
+
(0, import_vue11.h)("h2", { style: styles.subtitle }, "Ledger"),
|
|
797
|
+
ledger.value.length === 0 ? (0, import_vue11.h)("p", { style: styles.muted }, "Nothing moved yet.") : table(
|
|
798
|
+
["When", "Kind", "Amount", "Note"],
|
|
799
|
+
ledger.value.map(
|
|
800
|
+
(t) => (0, import_vue11.h)("tr", { key: t.id }, [
|
|
801
|
+
td(new Date(t.createdAt).toLocaleString(), styles.muted),
|
|
802
|
+
td(t.type),
|
|
803
|
+
td(t.amount, styles.mono),
|
|
804
|
+
td(t.description ?? "", styles.muted)
|
|
805
|
+
])
|
|
806
|
+
)
|
|
807
|
+
),
|
|
808
|
+
hasMoreLedger.value ? (0, import_vue11.h)(
|
|
809
|
+
"button",
|
|
810
|
+
{
|
|
811
|
+
type: "button",
|
|
812
|
+
style: { ...styles.button, marginTop: "8px" },
|
|
813
|
+
onClick: () => void loadMoreLedger()
|
|
814
|
+
},
|
|
815
|
+
"Load more"
|
|
816
|
+
) : null
|
|
817
|
+
] : (0, import_vue11.h)(
|
|
818
|
+
"p",
|
|
819
|
+
{ style: styles.muted },
|
|
820
|
+
"No wallet \u2014 billing has no wallet configuration."
|
|
821
|
+
)
|
|
822
|
+
] : null
|
|
823
|
+
]);
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
// src/screens/AuditScreen.ts
|
|
829
|
+
var import_vue_admin11 = require("@fonderie/vue-admin");
|
|
830
|
+
var import_vue12 = require("vue");
|
|
831
|
+
var AuditScreen = (0, import_vue12.defineComponent)({
|
|
832
|
+
name: "FonderieAuditScreen",
|
|
833
|
+
props: {
|
|
834
|
+
client: { type: Object, required: true },
|
|
835
|
+
pageSize: { type: Number, default: 50 }
|
|
836
|
+
},
|
|
837
|
+
setup(props) {
|
|
838
|
+
const draft = (0, import_vue12.ref)({ workspaceId: "", type: "", actorId: "" });
|
|
839
|
+
const query = (0, import_vue12.ref)({ limit: props.pageSize });
|
|
840
|
+
const { events, hasMore, isLoading, error, refresh, loadMore } = (0, import_vue_admin11.useAdminAudit)(
|
|
841
|
+
props.client,
|
|
842
|
+
query
|
|
843
|
+
);
|
|
844
|
+
const field = (key, placeholder) => (0, import_vue12.h)("input", {
|
|
845
|
+
value: draft.value[key],
|
|
846
|
+
onInput: (e) => draft.value = { ...draft.value, [key]: e.target.value },
|
|
847
|
+
placeholder,
|
|
848
|
+
style: { ...styles.button, cursor: "text" },
|
|
849
|
+
"aria-label": placeholder
|
|
850
|
+
});
|
|
851
|
+
return () => (0, import_vue12.h)("div", { style: styles.container }, [
|
|
852
|
+
(0, import_vue12.h)("h1", { style: styles.title }, "Audit"),
|
|
853
|
+
(0, import_vue12.h)(
|
|
854
|
+
"form",
|
|
855
|
+
{
|
|
856
|
+
style: styles.toolbar,
|
|
857
|
+
onSubmit: (e) => {
|
|
858
|
+
e.preventDefault();
|
|
859
|
+
const d = draft.value;
|
|
860
|
+
query.value = {
|
|
861
|
+
limit: props.pageSize,
|
|
862
|
+
...d.workspaceId.trim() ? { workspaceId: d.workspaceId.trim() } : {},
|
|
863
|
+
...d.type.trim() ? { type: d.type.trim() } : {},
|
|
864
|
+
...d.actorId.trim() ? { actorId: d.actorId.trim() } : {}
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
[
|
|
869
|
+
field("workspaceId", "workspace id (all if empty)"),
|
|
870
|
+
field("type", "event type"),
|
|
871
|
+
field("actorId", "actor id"),
|
|
872
|
+
(0, import_vue12.h)(
|
|
873
|
+
"button",
|
|
874
|
+
{ type: "submit", style: styles.button, disabled: isLoading.value },
|
|
875
|
+
"Filter"
|
|
876
|
+
),
|
|
877
|
+
refreshButton("Refresh", isLoading.value, () => void refresh())
|
|
878
|
+
]
|
|
879
|
+
),
|
|
880
|
+
error.value ? (0, import_vue12.h)("p", { style: styles.error, role: "alert" }, error.value.explanation) : null,
|
|
881
|
+
events.value.length === 0 && !isLoading.value ? (0, import_vue12.h)("p", { style: styles.muted }, "Nothing recorded for this filter.") : table(
|
|
882
|
+
["When", "Type", "Workspace", "Actor", "Request"],
|
|
883
|
+
events.value.map(
|
|
884
|
+
(e) => (0, import_vue12.h)("tr", { key: e.id }, [
|
|
885
|
+
td(new Date(e.createdAt).toLocaleString(), styles.muted),
|
|
886
|
+
td(e.type, styles.mono),
|
|
887
|
+
td(String(e.payload["workspaceId"] ?? "\u2014"), styles.mono),
|
|
888
|
+
td(e.actorId ?? "\u2014", styles.mono),
|
|
889
|
+
td(e.requestId ?? "", styles.muted)
|
|
890
|
+
])
|
|
891
|
+
)
|
|
892
|
+
),
|
|
893
|
+
isLoading.value ? (0, import_vue12.h)("p", { style: styles.status }, "Loading\u2026") : null,
|
|
894
|
+
hasMore.value && !isLoading.value ? (0, import_vue12.h)(
|
|
895
|
+
"button",
|
|
896
|
+
{
|
|
897
|
+
type: "button",
|
|
898
|
+
style: { ...styles.button, marginTop: "8px" },
|
|
899
|
+
onClick: () => void loadMore()
|
|
900
|
+
},
|
|
901
|
+
"Load more"
|
|
902
|
+
) : null
|
|
903
|
+
]);
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
|
|
598
907
|
// src/screens/AdminShell.ts
|
|
599
908
|
var NAV = [
|
|
600
909
|
{ group: "Today", items: [{ page: "attention", label: "Attention" }] },
|
|
@@ -608,17 +917,25 @@ var NAV = [
|
|
|
608
917
|
]
|
|
609
918
|
},
|
|
610
919
|
{ group: "People", items: [{ page: "users", label: "Users", needs: "auth" }] },
|
|
920
|
+
{
|
|
921
|
+
group: "Money",
|
|
922
|
+
items: [
|
|
923
|
+
{ page: "catalog", label: "Catalog", needs: "billing" },
|
|
924
|
+
{ page: "subscriber", label: "Subscriber", needs: "billing" }
|
|
925
|
+
]
|
|
926
|
+
},
|
|
611
927
|
{ group: "Settings", items: [{ page: "settings", label: "Config & secrets", needs: "config" }] },
|
|
612
928
|
{ group: "Messaging", items: [{ page: "templates", label: "Templates", needs: "courier" }] },
|
|
613
929
|
{
|
|
614
930
|
group: "Activity",
|
|
615
931
|
items: [
|
|
932
|
+
{ page: "audit", label: "Audit", needs: "audit" },
|
|
616
933
|
{ page: "log", label: "Admin log" },
|
|
617
934
|
{ page: "tokens", label: "Access" }
|
|
618
935
|
]
|
|
619
936
|
}
|
|
620
937
|
];
|
|
621
|
-
var AdminShell = (0,
|
|
938
|
+
var AdminShell = (0, import_vue13.defineComponent)({
|
|
622
939
|
name: "FonderieAdminShell",
|
|
623
940
|
props: {
|
|
624
941
|
client: { type: Object, required: true },
|
|
@@ -628,6 +945,10 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
628
945
|
courierClient: { type: Object, default: void 0 },
|
|
629
946
|
// Given ⇒ the People page (users) appears; needs @fonderie/auth ≥ 7.8.
|
|
630
947
|
authClient: { type: Object, default: void 0 },
|
|
948
|
+
// Given ⇒ the Money pages (catalog, subscriber) appear; needs @fonderie/billing ≥ 9.10.
|
|
949
|
+
billingClient: { type: Object, default: void 0 },
|
|
950
|
+
// Given ⇒ the Audit page appears; needs @fonderie/audit ≥ 5.2.
|
|
951
|
+
auditClient: { type: Object, default: void 0 },
|
|
631
952
|
environment: { type: String, default: void 0 },
|
|
632
953
|
// Controlled navigation: pass `page` and listen to `navigate` to own the
|
|
633
954
|
// URL. Omit `page` and the shell keeps it itself.
|
|
@@ -635,15 +956,15 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
635
956
|
},
|
|
636
957
|
emits: { navigate: (_page) => true },
|
|
637
958
|
setup(props, { emit }) {
|
|
638
|
-
const own = (0,
|
|
639
|
-
const current = (0,
|
|
640
|
-
const editing = (0,
|
|
959
|
+
const own = (0, import_vue13.ref)("attention");
|
|
960
|
+
const current = (0, import_vue13.computed)(() => props.page ?? own.value);
|
|
961
|
+
const editing = (0, import_vue13.ref)(null);
|
|
641
962
|
const go = (p) => {
|
|
642
963
|
editing.value = null;
|
|
643
964
|
emit("navigate", p);
|
|
644
965
|
if (props.page === void 0) own.value = p;
|
|
645
966
|
};
|
|
646
|
-
const back = () => (0,
|
|
967
|
+
const back = () => (0, import_vue13.h)(
|
|
647
968
|
"button",
|
|
648
969
|
{ type: "button", style: styles.button, onClick: () => editing.value = null },
|
|
649
970
|
"\u2190 Back"
|
|
@@ -652,25 +973,43 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
652
973
|
const c = props.client;
|
|
653
974
|
switch (current.value) {
|
|
654
975
|
case "attention":
|
|
655
|
-
return (0,
|
|
976
|
+
return (0, import_vue13.h)(AttentionScreen, { client: c });
|
|
656
977
|
case "modules":
|
|
657
|
-
return (0,
|
|
978
|
+
return (0, import_vue13.h)(ModulesScreen, { client: c });
|
|
658
979
|
case "doctor":
|
|
659
|
-
return (0,
|
|
980
|
+
return (0, import_vue13.h)(DoctorScreen, { client: c });
|
|
660
981
|
case "config":
|
|
661
|
-
return (0,
|
|
982
|
+
return (0, import_vue13.h)(ConfigScreen, { client: c });
|
|
662
983
|
case "routes":
|
|
663
|
-
return (0,
|
|
984
|
+
return (0, import_vue13.h)(RoutesScreen, { client: c });
|
|
664
985
|
case "tokens":
|
|
665
|
-
return (0,
|
|
986
|
+
return (0, import_vue13.h)(TokensScreen, { client: c });
|
|
666
987
|
case "log":
|
|
667
|
-
return (0,
|
|
988
|
+
return (0, import_vue13.h)(AdminLogScreen, { client: c });
|
|
989
|
+
case "catalog":
|
|
990
|
+
return props.billingClient ? (0, import_vue13.h)(CatalogScreen, { client: props.billingClient }) : (0, import_vue13.h)(
|
|
991
|
+
"p",
|
|
992
|
+
{ style: styles.status },
|
|
993
|
+
"Pass a BillingAdminClient to see the catalog here."
|
|
994
|
+
);
|
|
995
|
+
case "subscriber":
|
|
996
|
+
return props.billingClient ? (0, import_vue13.h)(SubscriberScreen, { client: props.billingClient }) : (0, import_vue13.h)(
|
|
997
|
+
"p",
|
|
998
|
+
{ style: styles.status },
|
|
999
|
+
"Pass a BillingAdminClient to look up subscribers here."
|
|
1000
|
+
);
|
|
1001
|
+
case "audit":
|
|
1002
|
+
return props.auditClient ? (0, import_vue13.h)(AuditScreen, { client: props.auditClient }) : (0, import_vue13.h)(
|
|
1003
|
+
"p",
|
|
1004
|
+
{ style: styles.status },
|
|
1005
|
+
"Pass an AuditAdminClient to see the audit trail here."
|
|
1006
|
+
);
|
|
668
1007
|
case "users":
|
|
669
|
-
return props.authClient ? (0,
|
|
1008
|
+
return props.authClient ? (0, import_vue13.h)(UsersScreen, { client: props.authClient }) : (0, import_vue13.h)("p", { style: styles.status }, "Pass an AuthAdminClient to look up users here.");
|
|
670
1009
|
case "settings": {
|
|
671
1010
|
const cc = props.configClient;
|
|
672
1011
|
if (!cc)
|
|
673
|
-
return (0,
|
|
1012
|
+
return (0, import_vue13.h)(
|
|
674
1013
|
"p",
|
|
675
1014
|
{ style: styles.status },
|
|
676
1015
|
"Pass a ConfigAdminClient to manage config and secrets here."
|
|
@@ -679,7 +1018,7 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
679
1018
|
if (e && e.kind !== "template")
|
|
680
1019
|
return [
|
|
681
1020
|
back(),
|
|
682
|
-
(0,
|
|
1021
|
+
(0, import_vue13.h)(import_vue_config_admin_screens.ConfigEditorScreen, {
|
|
683
1022
|
client: cc,
|
|
684
1023
|
kind: e.kind,
|
|
685
1024
|
configKey: e.key,
|
|
@@ -687,7 +1026,7 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
687
1026
|
onSaved: () => editing.value = null
|
|
688
1027
|
})
|
|
689
1028
|
];
|
|
690
|
-
return (0,
|
|
1029
|
+
return (0, import_vue13.h)(import_vue_config_admin_screens.ConfigListScreen, {
|
|
691
1030
|
client: cc,
|
|
692
1031
|
...props.environment !== void 0 ? { environment: props.environment } : {},
|
|
693
1032
|
"onSelect-config": (key) => editing.value = { kind: "config", key },
|
|
@@ -697,7 +1036,7 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
697
1036
|
case "templates": {
|
|
698
1037
|
const kc = props.courierClient;
|
|
699
1038
|
if (!kc)
|
|
700
|
-
return (0,
|
|
1039
|
+
return (0, import_vue13.h)(
|
|
701
1040
|
"p",
|
|
702
1041
|
{ style: styles.status },
|
|
703
1042
|
"Pass a CourierAdminClient to manage templates here."
|
|
@@ -706,32 +1045,32 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
706
1045
|
if (e?.kind === "template")
|
|
707
1046
|
return [
|
|
708
1047
|
back(),
|
|
709
|
-
(0,
|
|
1048
|
+
(0, import_vue13.h)(import_vue_courier_admin_screens.TemplateEditorScreen, {
|
|
710
1049
|
client: kc,
|
|
711
1050
|
type: e.type,
|
|
712
1051
|
onSaved: () => editing.value = null
|
|
713
1052
|
})
|
|
714
1053
|
];
|
|
715
|
-
return (0,
|
|
1054
|
+
return (0, import_vue13.h)(import_vue_courier_admin_screens.TemplateListScreen, {
|
|
716
1055
|
client: kc,
|
|
717
1056
|
"onSelect-template": (t) => editing.value = { kind: "template", type: t.type }
|
|
718
1057
|
});
|
|
719
1058
|
}
|
|
720
1059
|
}
|
|
721
1060
|
};
|
|
722
|
-
return () => (0,
|
|
723
|
-
(0,
|
|
1061
|
+
return () => (0, import_vue13.h)("div", { style: styles.shell }, [
|
|
1062
|
+
(0, import_vue13.h)(
|
|
724
1063
|
"nav",
|
|
725
1064
|
{ style: styles.nav, "aria-label": "Admin" },
|
|
726
1065
|
NAV.map((g) => {
|
|
727
1066
|
const items = g.items.filter(
|
|
728
|
-
(i) => !i.needs || (i.needs === "config" ? props.configClient : i.needs === "courier" ? props.courierClient : props.authClient)
|
|
1067
|
+
(i) => !i.needs || (i.needs === "config" ? props.configClient : i.needs === "courier" ? props.courierClient : i.needs === "auth" ? props.authClient : i.needs === "billing" ? props.billingClient : props.auditClient)
|
|
729
1068
|
);
|
|
730
1069
|
if (items.length === 0) return null;
|
|
731
|
-
return (0,
|
|
732
|
-
(0,
|
|
1070
|
+
return (0, import_vue13.h)("div", { key: g.group }, [
|
|
1071
|
+
(0, import_vue13.h)("div", { style: styles.navGroup }, g.group),
|
|
733
1072
|
...items.map(
|
|
734
|
-
(i) => (0,
|
|
1073
|
+
(i) => (0, import_vue13.h)(
|
|
735
1074
|
"button",
|
|
736
1075
|
{
|
|
737
1076
|
key: i.page,
|
|
@@ -749,7 +1088,7 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
749
1088
|
]);
|
|
750
1089
|
})
|
|
751
1090
|
),
|
|
752
|
-
(0,
|
|
1091
|
+
(0, import_vue13.h)("main", { style: styles.main }, body())
|
|
753
1092
|
]);
|
|
754
1093
|
}
|
|
755
1094
|
});
|
|
@@ -758,10 +1097,13 @@ var AdminShell = (0, import_vue10.defineComponent)({
|
|
|
758
1097
|
AdminLogScreen,
|
|
759
1098
|
AdminShell,
|
|
760
1099
|
AttentionScreen,
|
|
1100
|
+
AuditScreen,
|
|
1101
|
+
CatalogScreen,
|
|
761
1102
|
ConfigScreen,
|
|
762
1103
|
DoctorScreen,
|
|
763
1104
|
ModulesScreen,
|
|
764
1105
|
RoutesScreen,
|
|
1106
|
+
SubscriberScreen,
|
|
765
1107
|
TokensScreen,
|
|
766
1108
|
UsersScreen
|
|
767
1109
|
});
|