@fonderie/vue-admin-screens 0.3.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 +4 -3
- package/dist/index.cjs +119 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +117 -28
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,10 +14,10 @@ Status: **experimental** (0.x).
|
|
|
14
14
|
| Money | Catalog · Subscriber | what am I selling (configured vs stored) · what is this subscriber on, their wallet, ledger, a manual grant (`billingClient`) |
|
|
15
15
|
| Settings | Config & secrets | the `@fonderie/config` admin screens, as a sub-page |
|
|
16
16
|
| Messaging | Templates | the `@fonderie/courier` admin screens, as a sub-page |
|
|
17
|
-
| 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 |
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import { AdminClient, AuthAdminClient, BillingAdminClient, ConfigAdminClient, CourierAdminClient } from '@fonderie/client';
|
|
20
|
+
import { AdminClient, AuditAdminClient, AuthAdminClient, BillingAdminClient, ConfigAdminClient, CourierAdminClient } from '@fonderie/client';
|
|
21
21
|
import { AdminShell } from '@fonderie/vue-admin-screens';
|
|
22
22
|
|
|
23
23
|
const base = { baseUrl: 'https://api.example.com', adminToken, actor: 'louis' };
|
|
@@ -27,10 +27,11 @@ const configClient = new ConfigAdminClient({ ...base, prefix: '/_admin' });
|
|
|
27
27
|
const courierClient = new CourierAdminClient({ ...base, prefix: '/_admin' });
|
|
28
28
|
const authClient = new AuthAdminClient(base); // @fonderie/auth ≥ 7.8
|
|
29
29
|
const billingClient = new BillingAdminClient(base); // @fonderie/billing ≥ 9.10
|
|
30
|
+
const auditClient = new AuditAdminClient(base); // @fonderie/audit ≥ 5.2
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
```ts
|
|
33
|
-
h(AdminShell, { client, configClient, courierClient, authClient, billingClient })
|
|
34
|
+
h(AdminShell, { client, configClient, courierClient, authClient, billingClient, auditClient })
|
|
34
35
|
```
|
|
35
36
|
|
|
36
37
|
Pass `page` and listen to `navigate` to own the URL (one route per page);
|
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
AdminLogScreen: () => AdminLogScreen,
|
|
24
24
|
AdminShell: () => AdminShell,
|
|
25
25
|
AttentionScreen: () => AttentionScreen,
|
|
26
|
+
AuditScreen: () => AuditScreen,
|
|
26
27
|
CatalogScreen: () => CatalogScreen,
|
|
27
28
|
ConfigScreen: () => ConfigScreen,
|
|
28
29
|
DoctorScreen: () => DoctorScreen,
|
|
@@ -37,7 +38,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
38
|
// src/screens/AdminShell.ts
|
|
38
39
|
var import_vue_config_admin_screens = require("@fonderie/vue-config-admin-screens");
|
|
39
40
|
var import_vue_courier_admin_screens = require("@fonderie/vue-courier-admin-screens");
|
|
40
|
-
var
|
|
41
|
+
var import_vue13 = require("vue");
|
|
41
42
|
|
|
42
43
|
// src/styles.ts
|
|
43
44
|
var styles = {
|
|
@@ -824,6 +825,85 @@ var SubscriberScreen = (0, import_vue11.defineComponent)({
|
|
|
824
825
|
}
|
|
825
826
|
});
|
|
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
|
+
|
|
827
907
|
// src/screens/AdminShell.ts
|
|
828
908
|
var NAV = [
|
|
829
909
|
{ group: "Today", items: [{ page: "attention", label: "Attention" }] },
|
|
@@ -849,12 +929,13 @@ var NAV = [
|
|
|
849
929
|
{
|
|
850
930
|
group: "Activity",
|
|
851
931
|
items: [
|
|
932
|
+
{ page: "audit", label: "Audit", needs: "audit" },
|
|
852
933
|
{ page: "log", label: "Admin log" },
|
|
853
934
|
{ page: "tokens", label: "Access" }
|
|
854
935
|
]
|
|
855
936
|
}
|
|
856
937
|
];
|
|
857
|
-
var AdminShell = (0,
|
|
938
|
+
var AdminShell = (0, import_vue13.defineComponent)({
|
|
858
939
|
name: "FonderieAdminShell",
|
|
859
940
|
props: {
|
|
860
941
|
client: { type: Object, required: true },
|
|
@@ -866,6 +947,8 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
866
947
|
authClient: { type: Object, default: void 0 },
|
|
867
948
|
// Given ⇒ the Money pages (catalog, subscriber) appear; needs @fonderie/billing ≥ 9.10.
|
|
868
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 },
|
|
869
952
|
environment: { type: String, default: void 0 },
|
|
870
953
|
// Controlled navigation: pass `page` and listen to `navigate` to own the
|
|
871
954
|
// URL. Omit `page` and the shell keeps it itself.
|
|
@@ -873,15 +956,15 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
873
956
|
},
|
|
874
957
|
emits: { navigate: (_page) => true },
|
|
875
958
|
setup(props, { emit }) {
|
|
876
|
-
const own = (0,
|
|
877
|
-
const current = (0,
|
|
878
|
-
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);
|
|
879
962
|
const go = (p) => {
|
|
880
963
|
editing.value = null;
|
|
881
964
|
emit("navigate", p);
|
|
882
965
|
if (props.page === void 0) own.value = p;
|
|
883
966
|
};
|
|
884
|
-
const back = () => (0,
|
|
967
|
+
const back = () => (0, import_vue13.h)(
|
|
885
968
|
"button",
|
|
886
969
|
{ type: "button", style: styles.button, onClick: () => editing.value = null },
|
|
887
970
|
"\u2190 Back"
|
|
@@ -890,37 +973,43 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
890
973
|
const c = props.client;
|
|
891
974
|
switch (current.value) {
|
|
892
975
|
case "attention":
|
|
893
|
-
return (0,
|
|
976
|
+
return (0, import_vue13.h)(AttentionScreen, { client: c });
|
|
894
977
|
case "modules":
|
|
895
|
-
return (0,
|
|
978
|
+
return (0, import_vue13.h)(ModulesScreen, { client: c });
|
|
896
979
|
case "doctor":
|
|
897
|
-
return (0,
|
|
980
|
+
return (0, import_vue13.h)(DoctorScreen, { client: c });
|
|
898
981
|
case "config":
|
|
899
|
-
return (0,
|
|
982
|
+
return (0, import_vue13.h)(ConfigScreen, { client: c });
|
|
900
983
|
case "routes":
|
|
901
|
-
return (0,
|
|
984
|
+
return (0, import_vue13.h)(RoutesScreen, { client: c });
|
|
902
985
|
case "tokens":
|
|
903
|
-
return (0,
|
|
986
|
+
return (0, import_vue13.h)(TokensScreen, { client: c });
|
|
904
987
|
case "log":
|
|
905
|
-
return (0,
|
|
988
|
+
return (0, import_vue13.h)(AdminLogScreen, { client: c });
|
|
906
989
|
case "catalog":
|
|
907
|
-
return props.billingClient ? (0,
|
|
990
|
+
return props.billingClient ? (0, import_vue13.h)(CatalogScreen, { client: props.billingClient }) : (0, import_vue13.h)(
|
|
908
991
|
"p",
|
|
909
992
|
{ style: styles.status },
|
|
910
993
|
"Pass a BillingAdminClient to see the catalog here."
|
|
911
994
|
);
|
|
912
995
|
case "subscriber":
|
|
913
|
-
return props.billingClient ? (0,
|
|
996
|
+
return props.billingClient ? (0, import_vue13.h)(SubscriberScreen, { client: props.billingClient }) : (0, import_vue13.h)(
|
|
914
997
|
"p",
|
|
915
998
|
{ style: styles.status },
|
|
916
999
|
"Pass a BillingAdminClient to look up subscribers here."
|
|
917
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
|
+
);
|
|
918
1007
|
case "users":
|
|
919
|
-
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.");
|
|
920
1009
|
case "settings": {
|
|
921
1010
|
const cc = props.configClient;
|
|
922
1011
|
if (!cc)
|
|
923
|
-
return (0,
|
|
1012
|
+
return (0, import_vue13.h)(
|
|
924
1013
|
"p",
|
|
925
1014
|
{ style: styles.status },
|
|
926
1015
|
"Pass a ConfigAdminClient to manage config and secrets here."
|
|
@@ -929,7 +1018,7 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
929
1018
|
if (e && e.kind !== "template")
|
|
930
1019
|
return [
|
|
931
1020
|
back(),
|
|
932
|
-
(0,
|
|
1021
|
+
(0, import_vue13.h)(import_vue_config_admin_screens.ConfigEditorScreen, {
|
|
933
1022
|
client: cc,
|
|
934
1023
|
kind: e.kind,
|
|
935
1024
|
configKey: e.key,
|
|
@@ -937,7 +1026,7 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
937
1026
|
onSaved: () => editing.value = null
|
|
938
1027
|
})
|
|
939
1028
|
];
|
|
940
|
-
return (0,
|
|
1029
|
+
return (0, import_vue13.h)(import_vue_config_admin_screens.ConfigListScreen, {
|
|
941
1030
|
client: cc,
|
|
942
1031
|
...props.environment !== void 0 ? { environment: props.environment } : {},
|
|
943
1032
|
"onSelect-config": (key) => editing.value = { kind: "config", key },
|
|
@@ -947,7 +1036,7 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
947
1036
|
case "templates": {
|
|
948
1037
|
const kc = props.courierClient;
|
|
949
1038
|
if (!kc)
|
|
950
|
-
return (0,
|
|
1039
|
+
return (0, import_vue13.h)(
|
|
951
1040
|
"p",
|
|
952
1041
|
{ style: styles.status },
|
|
953
1042
|
"Pass a CourierAdminClient to manage templates here."
|
|
@@ -956,32 +1045,32 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
956
1045
|
if (e?.kind === "template")
|
|
957
1046
|
return [
|
|
958
1047
|
back(),
|
|
959
|
-
(0,
|
|
1048
|
+
(0, import_vue13.h)(import_vue_courier_admin_screens.TemplateEditorScreen, {
|
|
960
1049
|
client: kc,
|
|
961
1050
|
type: e.type,
|
|
962
1051
|
onSaved: () => editing.value = null
|
|
963
1052
|
})
|
|
964
1053
|
];
|
|
965
|
-
return (0,
|
|
1054
|
+
return (0, import_vue13.h)(import_vue_courier_admin_screens.TemplateListScreen, {
|
|
966
1055
|
client: kc,
|
|
967
1056
|
"onSelect-template": (t) => editing.value = { kind: "template", type: t.type }
|
|
968
1057
|
});
|
|
969
1058
|
}
|
|
970
1059
|
}
|
|
971
1060
|
};
|
|
972
|
-
return () => (0,
|
|
973
|
-
(0,
|
|
1061
|
+
return () => (0, import_vue13.h)("div", { style: styles.shell }, [
|
|
1062
|
+
(0, import_vue13.h)(
|
|
974
1063
|
"nav",
|
|
975
1064
|
{ style: styles.nav, "aria-label": "Admin" },
|
|
976
1065
|
NAV.map((g) => {
|
|
977
1066
|
const items = g.items.filter(
|
|
978
|
-
(i) => !i.needs || (i.needs === "config" ? props.configClient : i.needs === "courier" ? props.courierClient : i.needs === "auth" ? props.authClient : props.billingClient)
|
|
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)
|
|
979
1068
|
);
|
|
980
1069
|
if (items.length === 0) return null;
|
|
981
|
-
return (0,
|
|
982
|
-
(0,
|
|
1070
|
+
return (0, import_vue13.h)("div", { key: g.group }, [
|
|
1071
|
+
(0, import_vue13.h)("div", { style: styles.navGroup }, g.group),
|
|
983
1072
|
...items.map(
|
|
984
|
-
(i) => (0,
|
|
1073
|
+
(i) => (0, import_vue13.h)(
|
|
985
1074
|
"button",
|
|
986
1075
|
{
|
|
987
1076
|
key: i.page,
|
|
@@ -999,7 +1088,7 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
999
1088
|
]);
|
|
1000
1089
|
})
|
|
1001
1090
|
),
|
|
1002
|
-
(0,
|
|
1091
|
+
(0, import_vue13.h)("main", { style: styles.main }, body())
|
|
1003
1092
|
]);
|
|
1004
1093
|
}
|
|
1005
1094
|
});
|
|
@@ -1008,6 +1097,7 @@ var AdminShell = (0, import_vue12.defineComponent)({
|
|
|
1008
1097
|
AdminLogScreen,
|
|
1009
1098
|
AdminShell,
|
|
1010
1099
|
AttentionScreen,
|
|
1100
|
+
AuditScreen,
|
|
1011
1101
|
CatalogScreen,
|
|
1012
1102
|
ConfigScreen,
|
|
1013
1103
|
DoctorScreen,
|