portal-mojo 0.1.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/LICENSE +201 -0
- package/README.md +55 -0
- package/docs/DetailView.md +173 -0
- package/docs/ModelTable.md +128 -0
- package/docs/README.md +98 -0
- package/docs/admin-assistant.md +72 -0
- package/docs/admin-bouncer.md +120 -0
- package/docs/admin-cloudwatch.md +38 -0
- package/docs/admin-credentials.md +116 -0
- package/docs/admin-dashboard.md +15 -0
- package/docs/admin-devices-geoip.md +284 -0
- package/docs/admin-dns-certificates.md +122 -0
- package/docs/admin-dns-records.md +65 -0
- package/docs/admin-dns-registrar.md +33 -0
- package/docs/admin-dns.md +80 -0
- package/docs/admin-identity-users.md +103 -0
- package/docs/admin-incidents.md +71 -0
- package/docs/admin-jobs.md +426 -0
- package/docs/admin-members.md +112 -0
- package/docs/admin-messaging.md +56 -0
- package/docs/admin-metrics-explorer.md +63 -0
- package/docs/admin-monitoring.md +99 -0
- package/docs/admin-network-security.md +393 -0
- package/docs/admin-phonehub.md +27 -0
- package/docs/admin-push.md +36 -0
- package/docs/admin-rules.md +87 -0
- package/docs/admin-security-tickets.md +40 -0
- package/docs/admin-settings.md +78 -0
- package/docs/admin-shortlinks.md +32 -0
- package/docs/admin-storage.md +141 -0
- package/docs/auth-pages.md +212 -0
- package/docs/auth.md +58 -0
- package/docs/calendar.md +122 -0
- package/docs/charts.md +303 -0
- package/docs/client.md +206 -0
- package/docs/collection-multiselect.md +117 -0
- package/docs/collection-select.md +132 -0
- package/docs/combobox.md +105 -0
- package/docs/dataview.md +226 -0
- package/docs/datepicker.md +151 -0
- package/docs/daterange.md +170 -0
- package/docs/datetimepicker.md +249 -0
- package/docs/defineModel.md +72 -0
- package/docs/detail-primitives.md +174 -0
- package/docs/feedback.md +85 -0
- package/docs/file-upload-ux.md +146 -0
- package/docs/forms.md +435 -0
- package/docs/grouping-and-fmt.md +98 -0
- package/docs/idioms.md +112 -0
- package/docs/image-editor.md +101 -0
- package/docs/loading.md +242 -0
- package/docs/location-address.md +76 -0
- package/docs/markdown.md +203 -0
- package/docs/menus-and-access.md +89 -0
- package/docs/multiselect-dropdown.md +153 -0
- package/docs/params.md +73 -0
- package/docs/popover.md +130 -0
- package/docs/realtime.md +61 -0
- package/docs/record-feed.md +238 -0
- package/docs/right-panel.md +42 -0
- package/docs/tabs-and-form-wizard.md +60 -0
- package/docs/taginput.md +120 -0
- package/docs/timepicker.md +173 -0
- package/docs/timezone-select.md +147 -0
- package/docs/worldmap.md +302 -0
- package/package.json +55 -0
- package/src/admin/assistant/AssistantFeed.tsx +29 -0
- package/src/admin/assistant/AssistantPanel.tsx +65 -0
- package/src/admin/assistant/api.ts +17 -0
- package/src/admin/assistant/data.ts +63 -0
- package/src/admin/assistant/index.ts +21 -0
- package/src/admin/assistant/launchers.tsx +33 -0
- package/src/admin/assistant/pages.tsx +78 -0
- package/src/admin/assistant/streaming.ts +238 -0
- package/src/admin/assistant/types.ts +30 -0
- package/src/admin/bouncer/devices.tsx +230 -0
- package/src/admin/bouncer/index.ts +34 -0
- package/src/admin/bouncer/models.ts +199 -0
- package/src/admin/bouncer/signals.tsx +182 -0
- package/src/admin/bouncer/signatures.tsx +220 -0
- package/src/admin/cloudwatch/CloudWatchChart.tsx +61 -0
- package/src/admin/cloudwatch/CloudWatchDashboardPage.tsx +52 -0
- package/src/admin/cloudwatch/CloudWatchResourceDetail.tsx +33 -0
- package/src/admin/cloudwatch/data.ts +163 -0
- package/src/admin/cloudwatch/index.ts +16 -0
- package/src/admin/credentials/group-api-keys.tsx +433 -0
- package/src/admin/credentials/index.ts +4 -0
- package/src/admin/credentials/models.ts +244 -0
- package/src/admin/credentials/secret-dialog.tsx +77 -0
- package/src/admin/credentials/webhook-subscriptions.tsx +423 -0
- package/src/admin/dashboard/AdminDashboardPage.tsx +101 -0
- package/src/admin/dashboard/data.ts +60 -0
- package/src/admin/dashboard/index.ts +2 -0
- package/src/admin/dns/CertificateDetail.tsx +115 -0
- package/src/admin/dns/CertificateLifecyclePoller.tsx +141 -0
- package/src/admin/dns/CertificateRequestDialog.tsx +103 -0
- package/src/admin/dns/CertificatesPage.tsx +85 -0
- package/src/admin/dns/DnsRecordEditor.tsx +110 -0
- package/src/admin/dns/DnsRecordsPage.tsx +36 -0
- package/src/admin/dns/DnsRecordsPanel.tsx +71 -0
- package/src/admin/dns/DomainCertificatesSection.tsx +40 -0
- package/src/admin/dns/DomainDetail.tsx +41 -0
- package/src/admin/dns/DomainOnboardingDialog.tsx +27 -0
- package/src/admin/dns/DomainPurchaseDetail.tsx +11 -0
- package/src/admin/dns/DomainPurchaseWizard.tsx +112 -0
- package/src/admin/dns/DomainPurchasesPage.tsx +16 -0
- package/src/admin/dns/DomainsPage.tsx +27 -0
- package/src/admin/dns/ProviderCredentialsPage.tsx +304 -0
- package/src/admin/dns/RegistrantContactPage.tsx +42 -0
- package/src/admin/dns/api.ts +515 -0
- package/src/admin/dns/certificate-data.ts +221 -0
- package/src/admin/dns/data.ts +32 -0
- package/src/admin/dns/dns-data.ts +266 -0
- package/src/admin/dns/dns-integration.ts +24 -0
- package/src/admin/dns/domain-links.ts +37 -0
- package/src/admin/dns/index.ts +86 -0
- package/src/admin/dns/models.ts +418 -0
- package/src/admin/dns/purchase-data.ts +67 -0
- package/src/admin/dns/registrant-data.ts +52 -0
- package/src/admin/identity/index.ts +5 -0
- package/src/admin/identity/members/GroupMembersPanel.tsx +146 -0
- package/src/admin/identity/members/MemberDetail.tsx +226 -0
- package/src/admin/identity/members/MembersPage.tsx +144 -0
- package/src/admin/identity/members/index.ts +24 -0
- package/src/admin/identity/members/member-flows.tsx +132 -0
- package/src/admin/identity/members/models.ts +204 -0
- package/src/admin/identity/users/UserDetail.tsx +257 -0
- package/src/admin/identity/users/UsersPage.tsx +163 -0
- package/src/admin/identity/users/index.ts +27 -0
- package/src/admin/identity/users/models.ts +232 -0
- package/src/admin/identity/users/sections/ApiKeysSection.tsx +119 -0
- package/src/admin/identity/users/sections/AuditSection.tsx +190 -0
- package/src/admin/identity/users/sections/DevicesSection.tsx +140 -0
- package/src/admin/identity/users/sections/GroupsSection.tsx +64 -0
- package/src/admin/identity/users/sections/LoginsSection.tsx +106 -0
- package/src/admin/identity/users/sections/MetadataPanel.tsx +36 -0
- package/src/admin/identity/users/sections/NotificationsSection.tsx +117 -0
- package/src/admin/identity/users/sections/OAuthSection.tsx +72 -0
- package/src/admin/identity/users/sections/OverviewSection.tsx +109 -0
- package/src/admin/identity/users/sections/PermissionsSection.tsx +35 -0
- package/src/admin/identity/users/sections/PersonalSection.tsx +73 -0
- package/src/admin/identity/users/sections/ProfileSection.tsx +175 -0
- package/src/admin/identity/users/sections/SecuritySection.tsx +123 -0
- package/src/admin/identity/users/sections/actions.tsx +752 -0
- package/src/admin/identity/users/sections/permission-catalog.ts +138 -0
- package/src/admin/identity/users/sections/queries.ts +74 -0
- package/src/admin/identity/users/sections/shared.tsx +299 -0
- package/src/admin/incidents/EventDetail.tsx +43 -0
- package/src/admin/incidents/EventsPage.tsx +52 -0
- package/src/admin/incidents/IncidentDetail.tsx +68 -0
- package/src/admin/incidents/IncidentsPage.tsx +102 -0
- package/src/admin/incidents/forensics.tsx +73 -0
- package/src/admin/incidents/index.ts +16 -0
- package/src/admin/incidents/models.ts +113 -0
- package/src/admin/incidents/sanitize.ts +71 -0
- package/src/admin/index.ts +383 -0
- package/src/admin/jobs/JobDashboardPage.tsx +111 -0
- package/src/admin/jobs/JobDetail.tsx +721 -0
- package/src/admin/jobs/JobRunnersPage.tsx +216 -0
- package/src/admin/jobs/JobsTablePage.tsx +122 -0
- package/src/admin/jobs/RunnerDetail.tsx +576 -0
- package/src/admin/jobs/ScheduledTaskDetail.tsx +421 -0
- package/src/admin/jobs/ScheduledTasksPage.tsx +167 -0
- package/src/admin/jobs/columns.tsx +297 -0
- package/src/admin/jobs/control.ts +488 -0
- package/src/admin/jobs/index.ts +85 -0
- package/src/admin/jobs/models.ts +599 -0
- package/src/admin/jobs/queries.ts +272 -0
- package/src/admin/jobs/scheduled-task-form.tsx +493 -0
- package/src/admin/jobs/sections/JobChannelsPanel.tsx +142 -0
- package/src/admin/jobs/sections/JobOperationsSection.tsx +423 -0
- package/src/admin/jobs/sections/JobRunnersStrip.tsx +82 -0
- package/src/admin/jobs/sections/JobThroughputSection.tsx +118 -0
- package/src/admin/messaging/EmailDomainWizard.tsx +24 -0
- package/src/admin/messaging/EmailDomainsPage.tsx +17 -0
- package/src/admin/messaging/EmailTemplatesPage.tsx +13 -0
- package/src/admin/messaging/MailboxesPage.tsx +15 -0
- package/src/admin/messaging/PublicMessagesPage.tsx +13 -0
- package/src/admin/messaging/SandboxedEmailPreview.tsx +23 -0
- package/src/admin/messaging/SentMessagesPage.tsx +11 -0
- package/src/admin/messaging/api.ts +17 -0
- package/src/admin/messaging/data.ts +10 -0
- package/src/admin/messaging/index.ts +23 -0
- package/src/admin/messaging/models.ts +76 -0
- package/src/admin/messaging/push/PushPage.tsx +44 -0
- package/src/admin/messaging/push/api.ts +17 -0
- package/src/admin/messaging/push/index.ts +9 -0
- package/src/admin/messaging/push/models.ts +43 -0
- package/src/admin/messaging/sanitize.ts +44 -0
- package/src/admin/monitoring/LogInspector.tsx +160 -0
- package/src/admin/monitoring/LogsPage.tsx +135 -0
- package/src/admin/monitoring/MetricsExplorerPage.tsx +360 -0
- package/src/admin/monitoring/MetricsPermissionsPage.tsx +166 -0
- package/src/admin/monitoring/MetricsSourcePicker.tsx +136 -0
- package/src/admin/monitoring/index.ts +55 -0
- package/src/admin/monitoring/metrics-explorer-client.ts +229 -0
- package/src/admin/monitoring/metrics-explorer-data.ts +158 -0
- package/src/admin/monitoring/models.ts +155 -0
- package/src/admin/network/BlockedIPsPage.tsx +194 -0
- package/src/admin/network/BlockedIpDetail.tsx +262 -0
- package/src/admin/network/FirewallLogPage.tsx +115 -0
- package/src/admin/network/IPSetDetail.tsx +280 -0
- package/src/admin/network/IPSetEditor.tsx +191 -0
- package/src/admin/network/IPSetsPage.tsx +177 -0
- package/src/admin/network/geofence/BlocksTab.tsx +289 -0
- package/src/admin/network/geofence/ExemptionsTab.tsx +349 -0
- package/src/admin/network/geofence/GeofencingPage.tsx +119 -0
- package/src/admin/network/geofence/PostureHeader.tsx +184 -0
- package/src/admin/network/geofence/RuleEditor.tsx +176 -0
- package/src/admin/network/geofence/RulesTab.tsx +254 -0
- package/src/admin/network/geofence/SimulatorTab.tsx +281 -0
- package/src/admin/network/geofence/geofence-data.ts +674 -0
- package/src/admin/network/index.ts +68 -0
- package/src/admin/network/models.ts +607 -0
- package/src/admin/phonehub/PhoneHubPage.tsx +57 -0
- package/src/admin/phonehub/api.ts +47 -0
- package/src/admin/phonehub/data.ts +6 -0
- package/src/admin/phonehub/index.ts +10 -0
- package/src/admin/phonehub/models.ts +68 -0
- package/src/admin/rules/HandlerChainBuilder.tsx +51 -0
- package/src/admin/rules/RuleSetDetailPage.tsx +33 -0
- package/src/admin/rules/RuleSetsPage.tsx +33 -0
- package/src/admin/rules/editors.tsx +54 -0
- package/src/admin/rules/handler-dsl.ts +213 -0
- package/src/admin/rules/index.ts +13 -0
- package/src/admin/rules/models.ts +112 -0
- package/src/admin/security/devices/LoginEventDetail.tsx +123 -0
- package/src/admin/security/devices/LoginLocationMap.tsx +321 -0
- package/src/admin/security/devices/LoginLocationsPage.tsx +162 -0
- package/src/admin/security/devices/UserDeviceDetail.tsx +546 -0
- package/src/admin/security/devices/UserDeviceLocationDetail.tsx +272 -0
- package/src/admin/security/devices/UserDevicesPage.tsx +84 -0
- package/src/admin/security/devices/index.ts +40 -0
- package/src/admin/security/devices/models.ts +470 -0
- package/src/admin/security/geoip/GeoIpCachePage.tsx +135 -0
- package/src/admin/security/geoip/GeoIpDossier.tsx +804 -0
- package/src/admin/security/geoip/geoip-forms.ts +102 -0
- package/src/admin/security/geoip/index.ts +27 -0
- package/src/admin/security/geoip/models.ts +397 -0
- package/src/admin/security/index.ts +31 -0
- package/src/admin/security/models.ts +137 -0
- package/src/admin/security/tickets.tsx +562 -0
- package/src/admin/security-permissions.ts +5 -0
- package/src/admin/settings/SettingDetail.tsx +57 -0
- package/src/admin/settings/SettingEditor.tsx +157 -0
- package/src/admin/settings/SettingsPage.tsx +72 -0
- package/src/admin/settings/index.ts +19 -0
- package/src/admin/settings/model.ts +143 -0
- package/src/admin/shortlinks/ShortlinkDetail.tsx +55 -0
- package/src/admin/shortlinks/ShortlinkHistoryPage.tsx +18 -0
- package/src/admin/shortlinks/ShortlinksPage.tsx +59 -0
- package/src/admin/shortlinks/index.ts +18 -0
- package/src/admin/shortlinks/models.ts +246 -0
- package/src/admin/storage/BackendsPage.tsx +43 -0
- package/src/admin/storage/BucketDetail.tsx +77 -0
- package/src/admin/storage/BucketsPage.tsx +64 -0
- package/src/admin/storage/FileManagerDetail.tsx +36 -0
- package/src/admin/storage/FilePreview.tsx +54 -0
- package/src/admin/storage/FileUploadSurface.tsx +250 -0
- package/src/admin/storage/FileView.tsx +109 -0
- package/src/admin/storage/FilesPage.tsx +53 -0
- package/src/admin/storage/file-renditions.ts +99 -0
- package/src/admin/storage/index.ts +31 -0
- package/src/admin/storage/models.ts +585 -0
- package/src/admin/storage/storage-dialogs.tsx +80 -0
- package/src/charts/CircularProgress.tsx +281 -0
- package/src/charts/KPIStrip.tsx +162 -0
- package/src/charts/KPITile.tsx +125 -0
- package/src/charts/MetricsChart.tsx +459 -0
- package/src/charts/MetricsMiniWidget.tsx +588 -0
- package/src/charts/MiniChart.tsx +283 -0
- package/src/charts/PieChart.tsx +354 -0
- package/src/charts/SeriesChart.tsx +378 -0
- package/src/charts/chart-dialogs.tsx +149 -0
- package/src/charts/exportChart.ts +144 -0
- package/src/charts/index.ts +28 -0
- package/src/charts/pie-math.ts +127 -0
- package/src/charts/stats.ts +265 -0
- package/src/charts/worldmap/WorldMap.tsx +649 -0
- package/src/charts/worldmap/countryCentroids.ts +304 -0
- package/src/charts/worldmap/geo.ts +293 -0
- package/src/charts/worldmap/use-world-land.ts +47 -0
- package/src/charts/worldmap/world-land.ts +18 -0
- package/src/charts/worldmap/worldmap-data.ts +285 -0
- package/src/client/auth.ts +737 -0
- package/src/client/client.ts +268 -0
- package/src/client/duid.ts +31 -0
- package/src/client/errors.ts +33 -0
- package/src/client/group-context.ts +28 -0
- package/src/client/group.tsx +126 -0
- package/src/client/hooks.ts +50 -0
- package/src/client/index.ts +37 -0
- package/src/client/jwt.ts +75 -0
- package/src/client/location.ts +285 -0
- package/src/client/lookups.ts +41 -0
- package/src/client/markdown-fallback.tsx +115 -0
- package/src/client/markdown-parse.ts +386 -0
- package/src/client/markdown-sanitize.ts +217 -0
- package/src/client/markdown.ts +122 -0
- package/src/client/me.ts +188 -0
- package/src/client/mock.ts +9984 -0
- package/src/client/model.ts +227 -0
- package/src/client/params.ts +292 -0
- package/src/client/realtime-mock.ts +221 -0
- package/src/client/realtime.ts +561 -0
- package/src/client/record-feed.ts +329 -0
- package/src/client/safe-export.ts +71 -0
- package/src/client/types.ts +278 -0
- package/src/client/upload.ts +421 -0
- package/src/ui/AddressField.tsx +273 -0
- package/src/ui/AttachmentQueue.tsx +92 -0
- package/src/ui/CollectionMultiSelect.tsx +622 -0
- package/src/ui/CollectionSelect.tsx +517 -0
- package/src/ui/ComboBox.tsx +336 -0
- package/src/ui/DetailView.tsx +438 -0
- package/src/ui/FileDrop.tsx +194 -0
- package/src/ui/FileField.tsx +369 -0
- package/src/ui/FilterBar.tsx +269 -0
- package/src/ui/FormFields.tsx +77 -0
- package/src/ui/FormView.tsx +360 -0
- package/src/ui/FormWizard.tsx +336 -0
- package/src/ui/GroupSwitcher.tsx +202 -0
- package/src/ui/Guarded.tsx +16 -0
- package/src/ui/MarkdownView.tsx +89 -0
- package/src/ui/ModelTable.tsx +848 -0
- package/src/ui/MultiSelectDropdown.tsx +390 -0
- package/src/ui/Popover.tsx +204 -0
- package/src/ui/RecordFeed.tsx +627 -0
- package/src/ui/RequiresGroup.tsx +32 -0
- package/src/ui/RightPanel.tsx +107 -0
- package/src/ui/SidebarNav.tsx +330 -0
- package/src/ui/Tabs.tsx +161 -0
- package/src/ui/TagInput.tsx +381 -0
- package/src/ui/ThemeProvider.tsx +52 -0
- package/src/ui/UploadQueue.tsx +603 -0
- package/src/ui/armed-button.tsx +91 -0
- package/src/ui/date/Calendar.tsx +498 -0
- package/src/ui/date/DatePicker.tsx +289 -0
- package/src/ui/date/DateRangePicker.tsx +280 -0
- package/src/ui/date/DateTimePicker.tsx +587 -0
- package/src/ui/date/PresetRail.tsx +165 -0
- package/src/ui/date/TimePicker.tsx +624 -0
- package/src/ui/date/TimezoneSelect.tsx +267 -0
- package/src/ui/date/fns.ts +679 -0
- package/src/ui/detail/DataView.tsx +692 -0
- package/src/ui/detail/FlowStrip.tsx +80 -0
- package/src/ui/detail/KnownFieldsCard.tsx +121 -0
- package/src/ui/detail/MetadataSection.tsx +219 -0
- package/src/ui/detail/StackTraceView.tsx +150 -0
- package/src/ui/detail/StatusPanel.tsx +73 -0
- package/src/ui/detail/Timeline.tsx +52 -0
- package/src/ui/detail/index.ts +12 -0
- package/src/ui/field-registry.tsx +428 -0
- package/src/ui/field-wire.ts +322 -0
- package/src/ui/form-autosave.ts +583 -0
- package/src/ui/format.ts +444 -0
- package/src/ui/grouping.ts +150 -0
- package/src/ui/image-editor/ImageEditor.tsx +484 -0
- package/src/ui/image-editor/canvas.ts +254 -0
- package/src/ui/image-editor/index.ts +3 -0
- package/src/ui/image-editor/math.ts +416 -0
- package/src/ui/index.ts +58 -0
- package/src/ui/loading.tsx +604 -0
- package/src/ui/menu-registry.ts +213 -0
- package/src/ui/modal.tsx +297 -0
- package/src/ui/password.tsx +302 -0
- package/src/ui/schema-form-core.tsx +315 -0
- package/src/ui/toast.tsx +219 -0
- package/src/ui/ui.tsx +45 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Admin Members
|
|
2
|
+
|
|
3
|
+
Reusable global membership administration for django-mojo. Import from
|
|
4
|
+
`portal-mojo/admin`:
|
|
5
|
+
|
|
6
|
+
```tsx
|
|
7
|
+
import {
|
|
8
|
+
MembersPage,
|
|
9
|
+
MemberDetail,
|
|
10
|
+
GroupMembersPanel,
|
|
11
|
+
MemberModel,
|
|
12
|
+
MEMBERS_ADMIN_SECTION,
|
|
13
|
+
openMemberAdmissionDialog,
|
|
14
|
+
registerMemberPermissions,
|
|
15
|
+
} from 'portal-mojo/admin';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Wire contract
|
|
19
|
+
|
|
20
|
+
`MemberModel` speaks `/api/group/member`. Its default row is:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
{
|
|
24
|
+
id, created, modified, is_active,
|
|
25
|
+
permissions: Record<string, unknown>,
|
|
26
|
+
metadata: { role?: string, ... },
|
|
27
|
+
user: User | null,
|
|
28
|
+
group: Group | null,
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
There is no top-level `role` or `status`: the presentation label is
|
|
33
|
+
`metadata.role`, and state is `is_active`. Relation columns are rendered but
|
|
34
|
+
not sortable. The model normalizes list state to verified parameters only:
|
|
35
|
+
search, paging, `id|created|modified|is_active` ordering, exact group/user and
|
|
36
|
+
active filters, `__icontains` lookups for user email/display name, group name
|
|
37
|
+
and role metadata, plus created/modified date ranges.
|
|
38
|
+
|
|
39
|
+
Supported mutations are collection create `{group,user}`, detail update, and
|
|
40
|
+
the `resend_invite` POST_SAVE_ACTION. Resend returns a payload (`{status:true}`),
|
|
41
|
+
not a refreshed member row. GroupMember declares neither delete nor generic
|
|
42
|
+
batch support, and has no move action. Remove and Move are intentionally absent:
|
|
43
|
+
a generic `{group:newId}` update is not a target-authorized move contract.
|
|
44
|
+
|
|
45
|
+
Audit rows filter `/api/logs` with `model_name=account.GroupMember` and the
|
|
46
|
+
membership `model_id`. `account.Member` is the obsolete web-mojo value.
|
|
47
|
+
|
|
48
|
+
## Admission and the no-oracle boundary
|
|
49
|
+
|
|
50
|
+
`openMemberAdmissionDialog` makes Invite and Add-existing separate choices.
|
|
51
|
+
Global Members selects a group first; `GroupMembersPanel` already has a fixed
|
|
52
|
+
group. Invite posts the supplied email directly to
|
|
53
|
+
`/api/group/member/invite`—it never probes `/api/user`. The confirmation is
|
|
54
|
+
the same whether the address is new, existing, or already associated.
|
|
55
|
+
|
|
56
|
+
Add-existing is deliberately directory-backed. It appears only when the
|
|
57
|
+
operator has both the Member create gate and the global user-directory gate;
|
|
58
|
+
only then does the `/api/user` picker run before collection POST.
|
|
59
|
+
|
|
60
|
+
## Permission tiers
|
|
61
|
+
|
|
62
|
+
Every global Admin clause is system-pinned:
|
|
63
|
+
|
|
64
|
+
- read: `sys.view_members | sys.view_groups | sys.manage_groups |
|
|
65
|
+
sys.manage_group | sys.groups`
|
|
66
|
+
- save/create: `sys.manage_groups | sys.manage_group | sys.groups`
|
|
67
|
+
- invite: `sys.manage_users | sys.manage_members | sys.manage_group |
|
|
68
|
+
sys.manage_groups`
|
|
69
|
+
- directory: `sys.view_users | sys.manage_users | sys.users`
|
|
70
|
+
|
|
71
|
+
Literal member `sys.*` keys always fail `memberHasPermission`, including a
|
|
72
|
+
malformed dictionary containing the exact requested key. User-level system
|
|
73
|
+
grants and superuser behavior in `hasPermission` are unchanged.
|
|
74
|
+
|
|
75
|
+
Three permission views must remain distinct:
|
|
76
|
+
|
|
77
|
+
1. Raw stored grants are the truthy keys in the JSON dictionary.
|
|
78
|
+
2. Effective member grants omit literal `sys.*`, stored `full_member`, and
|
|
79
|
+
legacy `admin`; `member` is intrinsic and `full_member` is derived when
|
|
80
|
+
`guest` is false.
|
|
81
|
+
3. User-level `sys.*` grants come only from the User permission dictionary.
|
|
82
|
+
|
|
83
|
+
The client retains the historical non-system member `admin` wildcard for
|
|
84
|
+
product portals, but django-mojo GroupMember does not honor it server-side.
|
|
85
|
+
Admin is labeled as client compatibility only and is never an editable grant.
|
|
86
|
+
`metadata.role` is also display-only and confers no authority.
|
|
87
|
+
|
|
88
|
+
## Extensible editable grants
|
|
89
|
+
|
|
90
|
+
The safe baseline includes ordinary group grants and the `guest` marker.
|
|
91
|
+
Products register additional controls:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
registerMemberPermissions([
|
|
95
|
+
{ name: 'view_orders', label: 'View orders' },
|
|
96
|
+
{ name: 'manage_orders', label: 'Manage orders' },
|
|
97
|
+
]);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`sys.*`, `admin`, `member`, and `full_member` registrations are rejected.
|
|
101
|
+
Stored deployment-specific grants without a registered editor stay visible
|
|
102
|
+
and read-only rather than disappearing. Permission switches autosave through
|
|
103
|
+
`FormView`; a deployment's `MEMBER_PERMS_PROTECTION` remains authoritative,
|
|
104
|
+
and rejected changes revert with the server error shown.
|
|
105
|
+
|
|
106
|
+
## Composition
|
|
107
|
+
|
|
108
|
+
`MEMBERS_ADMIN_SECTION` is root-relative and dual-mounts as `/members` in the
|
|
109
|
+
standalone Admin and `/system/members` when embedded. It never consumes active
|
|
110
|
+
group context. `GroupMembersPanel` is the reusable Group-detail composition;
|
|
111
|
+
pass optional `onNavigateUser` and `onNavigateGroup` callbacks to connect
|
|
112
|
+
sibling identity details without coupling the package to an app.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Communications Admin
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import {
|
|
5
|
+
EMAIL_ADMIN_SECTION, PUBLIC_MESSAGES_ADMIN_SECTION,
|
|
6
|
+
EmailDomainModel, MailboxModel, SentMessageModel,
|
|
7
|
+
EmailTemplateModel, PublicMessageModel,
|
|
8
|
+
} from 'portal-mojo/admin';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The global, no-group Communications workspace mounts at `email/domains`,
|
|
12
|
+
`email/mailboxes`, `email/sent`, `email/templates`, and
|
|
13
|
+
`messaging/public-messages` (or under `/system` in an embedded portal). Every
|
|
14
|
+
record opens in a native KISS detail modal; there are no record-detail routes
|
|
15
|
+
or drawers.
|
|
16
|
+
|
|
17
|
+
Email uses global `sys.manage_aws | sys.comms` for both view and mutation,
|
|
18
|
+
matching django-mojo's current single tier. Contact-message view uses
|
|
19
|
+
`sys.view_support | sys.security | sys.support`, status mutation uses
|
|
20
|
+
`sys.manage_support | sys.security | sys.support`, and delete uses only
|
|
21
|
+
`sys.manage_support`. A granular manager must also hold a view grant to open
|
|
22
|
+
the page. Active-group membership never satisfies a global Admin gate.
|
|
23
|
+
|
|
24
|
+
Domain credentials are write-only. Secret-bearing saves, onboarding, audit,
|
|
25
|
+
reconcile, and send are imperative and never use MutationCache. Audit is POST,
|
|
26
|
+
has no automatic retry, and always refreshes because it persists readiness.
|
|
27
|
+
Create reports only that the row was created: django-mojo's best-effort
|
|
28
|
+
create-time audit/reconcile can fail after the row exists. Delete warns that
|
|
29
|
+
local mailboxes and sent audit history disappear while SES/SNS/S3/DNS
|
|
30
|
+
resources may remain.
|
|
31
|
+
|
|
32
|
+
Onboarding composes the shared `FormWizard`. Managed mode is available only
|
|
33
|
+
when the optional DNS Admin integration resolves the normalized domain and
|
|
34
|
+
uses its one record store; no provider key is submitted. Manual mode always
|
|
35
|
+
shows the complete returned verification, DKIM, and MAIL-FROM records. Managed
|
|
36
|
+
failure never silently retries manually because SES-side work may already
|
|
37
|
+
have occurred.
|
|
38
|
+
|
|
39
|
+
Sent-message and template HTML is untrusted. `SandboxedEmailPreview` uses a
|
|
40
|
+
bare iframe sandbox, `referrerPolicy="no-referrer"`, an offline CSP, removed
|
|
41
|
+
meta refresh, and neutralized links. Safe exports are explicit projections:
|
|
42
|
+
template bodies, message bodies, BCC, template context, provider metadata,
|
|
43
|
+
contact-message body/IP/user-agent/metadata, and credential masks never leave.
|
|
44
|
+
|
|
45
|
+
Stable mock identities (password `mojo`):
|
|
46
|
+
|
|
47
|
+
- `email.operator@nativemojo.com` — email only (`comms`).
|
|
48
|
+
- `support.viewer@nativemojo.com` — contact read only.
|
|
49
|
+
- `support.manager@nativemojo.com` — contact read/update/delete.
|
|
50
|
+
- `support.manage-only@nativemojo.com` — delete authority but intentionally no page view.
|
|
51
|
+
- `showcase.operator@nativemojo.com` — executable showcase coverage.
|
|
52
|
+
|
|
53
|
+
Live verification is read-only by default. Never create/edit/delete a domain,
|
|
54
|
+
replace credentials, audit, onboard, reconcile, or send without explicit
|
|
55
|
+
authorization for that exact live action. SES quota is intentionally absent;
|
|
56
|
+
django-mojo #1310 tracks the missing backend endpoint.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Admin Metrics Explorer
|
|
2
|
+
|
|
3
|
+
`MetricsExplorerPage` is the read-only, global Admin workspace for django-mojo's recorded time-series metrics. Import it, its route contribution, or its exact adapters from `portal-mojo/admin`; import the reusable chart seam from `portal-mojo/charts`.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { MONITORING_ADMIN_SECTION, MetricsExplorerPage } from 'portal-mojo/admin';
|
|
7
|
+
|
|
8
|
+
<MetricsExplorerPage />
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The registered route is `/metrics/explorer` standalone and `/system/metrics/explorer` when `adminSectionRoutes()` is mounted below `/system`. Its exact any-of gate is `sys.view_metrics | sys.metrics`. That clause stays separate from the existing metrics-permission editor gate; `sys.manage_metrics` alone does not imply read access.
|
|
12
|
+
|
|
13
|
+
## Discovery wire
|
|
14
|
+
|
|
15
|
+
The page consumes only django-mojo #1438:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
GET /api/metrics/discover?resource=accounts|categories|slugs
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`discoverMetrics()` uses `mojoCall`, because the stable response fields `resource`, `filters`, `count`, `page_count`, and `next_start` are top-level envelope metadata that `mojoList` would discard. It validates the exact resource/filter echo and internally consistent paging before returning a `MetricsDiscoveryPage`. Permission failures reject; they never become an empty authorized catalog.
|
|
22
|
+
|
|
23
|
+
Account entry accepts exact `public`, `global`, `group-<positive-id>`, `user-<positive-id>`, or a bounded opaque custom account. Invalid reserved forms do not fall back to custom interpretation. Registry selection is URL-backed, with one repeated `slug` parameter per full slug. Comma-bearing slugs are reported as unaddressable because history endpoints use a comma-delimited request grammar.
|
|
24
|
+
|
|
25
|
+
Group and User `CollectionSelect` conveniences are separate capabilities. They mount only under `sys.view_groups|sys.manage_groups|sys.groups` and `sys.view_users|sys.manage_users|sys.users`, respectively. Without those clauses the exact account input remains available and no directory picker request can start.
|
|
26
|
+
|
|
27
|
+
## Full-slug identity
|
|
28
|
+
|
|
29
|
+
Full colon-bearing strings are the client identity. The backend responses are deliberately asymmetric:
|
|
30
|
+
|
|
31
|
+
- `/api/metrics/fetch` and fan-out sum key each dataset by the last colon segment;
|
|
32
|
+
- `/api/metrics/series?with_delta=true` preserves full keys;
|
|
33
|
+
- `/api/metrics/value/get` again truncates to the last segment.
|
|
34
|
+
|
|
35
|
+
`loadExactMetricSeries()` repairs history at the boundary. It batches globally unique tails, splits every member of a duplicate-tail group into its own request, validates exact response keys and compatible labels, and reassembles datasets in original request order. It rejects missing, extra, or ambiguous results. Fan-out breakdown requires one slug and preserves the returned child labels plus required `groups` map. `fetchMetricPoints()` validates full-key current/previous/delta maps, including the valid previous-zero case where `delta_pct` is absent. `readMetricValue()` reads one exact full slug per request.
|
|
36
|
+
|
|
37
|
+
History uses `dt_start` and `dt_end` epoch seconds. `dr_*` belongs to model-list aggregation and is never emitted here. The explorer has no record, value-set, permission mutation, or arbitrary `_mode` surface.
|
|
38
|
+
|
|
39
|
+
## Chart seam and cache
|
|
40
|
+
|
|
41
|
+
`MetricsChart` adds these optional props without changing existing callers:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
loadSeries?: MetricsSeriesLoader;
|
|
45
|
+
seriesCacheKey?: string;
|
|
46
|
+
childKind?: string;
|
|
47
|
+
breakdown?: boolean;
|
|
48
|
+
preserveSeriesLabels?: boolean;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The default loader remains `mojoMetrics` and repairs a tail-only response key when the configured full-slug set makes that mapping unique; ambiguous duplicate tails still require the exact loader. A custom loader must supply a stable namespace through `seriesCacheKey`; the namespace is part of the TanStack key so exact explorer data cannot reuse a cached lossy default response. The explorer namespace and every discovery/KPI/scalar key use the synchronous auth-token uid. Protected reads stay disabled until the async `me` identity agrees with that uid, preventing boot or direct identity switches from caching authenticated data under a shared placeholder.
|
|
52
|
+
|
|
53
|
+
## Fan-out, KPI, scalar, and export
|
|
54
|
+
|
|
55
|
+
Fan-out appears only for a parsed group account. Sum supports multiple selected slugs through the collision-safe adapter. Breakdown limits selection to one slug and requires an explicit child kind. KPI tiles issue one `/series?with_delta=true` request at an explicit `when` and granularity.
|
|
56
|
+
|
|
57
|
+
The scalar card reads a known exact slug and opens the standard KISS native-dialog detail. Its optional scale changes presentation only; raw values remain visible. There is no gauge catalog or fabricated health classification.
|
|
58
|
+
|
|
59
|
+
Chart CSV export flows through shared `csvEscape()`. String cells beginning with `=`, `+`, `-`, `@`, tab, or carriage return gain a leading apostrophe before normal RFC quoting. Numeric negatives remain numeric.
|
|
60
|
+
|
|
61
|
+
## Styling
|
|
62
|
+
|
|
63
|
+
The explorer extends the semantic `admin-monitoring.css` token stylesheet used by the Portal and showcase. It adds no UI or chart dependency. Consumers already including the Monitoring section stylesheet need no additional CSS entry.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Admin monitoring
|
|
2
|
+
|
|
3
|
+
`portal-mojo/admin` packages the immutable Logs feed, one-record log inspector,
|
|
4
|
+
read-only Metrics Explorer, and metrics-permission administration for standalone
|
|
5
|
+
or embedded admin portals. See [admin-metrics-explorer.md](admin-metrics-explorer.md)
|
|
6
|
+
for the discovery, identity, KPI, fan-out, scalar, and cache contracts.
|
|
7
|
+
|
|
8
|
+
## Admin registration and gates
|
|
9
|
+
|
|
10
|
+
`MONITORING_ADMIN_SECTION` contributes three root-relative routes:
|
|
11
|
+
|
|
12
|
+
| Route | Component | Any-of gate |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `/logs` | `LogsPage` | `sys.manage_logs`, `sys.view_logs`, `sys.security` |
|
|
15
|
+
| `/metrics/explorer` | `MetricsExplorerPage` | `sys.view_metrics`, `sys.metrics` |
|
|
16
|
+
| `/metrics/permissions` | `MetricsPermissionsPage` | `sys.manage_incidents`, `sys.metrics`, `sys.manage_metrics` |
|
|
17
|
+
|
|
18
|
+
The section clause is the union of these route audiences, while each route
|
|
19
|
+
retains its exact clause. In particular, `sys.view_metrics` reveals only the
|
|
20
|
+
explorer, `sys.metrics` reveals explorer and editor, and `sys.manage_metrics`
|
|
21
|
+
reveals only the editor. The `sys.` prefix is intentional: these are global operator surfaces and must
|
|
22
|
+
not inherit a similarly named active-group permission. `adminSectionRoutes()`
|
|
23
|
+
wraps each component before it mounts, so a denied direct route cannot fetch.
|
|
24
|
+
The backend remains authoritative.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import {
|
|
28
|
+
MONITORING_ADMIN_SECTION,
|
|
29
|
+
adminSectionRoutes,
|
|
30
|
+
adminSectionsMenu,
|
|
31
|
+
} from 'portal-mojo/admin';
|
|
32
|
+
|
|
33
|
+
const sections = [MONITORING_ADMIN_SECTION];
|
|
34
|
+
const routes = adminSectionRoutes(sections, { mount: '/system' });
|
|
35
|
+
const menu = adminSectionsMenu(sections, { mount: '/system' });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Logs and inspector
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { LogsPage, LogInspector, LogModel, type LogRow } from 'portal-mojo/admin';
|
|
42
|
+
|
|
43
|
+
<LogInspector log={row} />
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`LogsPage` is the canonical `/api/logs` table: server search/filter/sort,
|
|
47
|
+
day grouping, column persistence, export, quick-look chevron, and a full-size
|
|
48
|
+
row-click inspector. The table is read-only because log rows are immutable
|
|
49
|
+
records. The chevron cell stops propagation in `ModelTable`, so expanding a
|
|
50
|
+
quick look does not also open the inspector.
|
|
51
|
+
|
|
52
|
+
`LogModel` therefore publishes only its exact view gate. Although the backend
|
|
53
|
+
has separate `security|admin` save and `admin` delete gates, this immutable
|
|
54
|
+
package surface advertises no `manage` contract or mutation control. The
|
|
55
|
+
client's normal admin/superuser wildcard remains separate from `sys.security`.
|
|
56
|
+
|
|
57
|
+
The inspector recognizes explicit request and response `kind` tokens. All
|
|
58
|
+
other kinds are messages. The `log` field is the primary stored content and is
|
|
59
|
+
labelled “Stored request content,” “Stored response content,” or “Message” from
|
|
60
|
+
that kind. `payload` is always labelled “Auxiliary payload”; it is never
|
|
61
|
+
presented as the response body. The inspector also renders request context,
|
|
62
|
+
user, device, IP, related model, and user agent. Valid JSON goes through
|
|
63
|
+
`JsonBlock`; everything else is a React text child in a `<pre>`. HTML-looking
|
|
64
|
+
stored data is never an HTML rendering boundary. Clipboard absence and rejected
|
|
65
|
+
writes surface an error toast instead of reporting false success.
|
|
66
|
+
|
|
67
|
+
A response row is only a stored response row. `/api/logs` exposes no request
|
|
68
|
+
correlation key, so the inspector never searches for or claims a paired request.
|
|
69
|
+
|
|
70
|
+
## Metrics permission wire
|
|
71
|
+
|
|
72
|
+
The endpoint is Redis-backed and intentionally not modeled as a paged
|
|
73
|
+
`ModelTable`:
|
|
74
|
+
|
|
75
|
+
- `GET /api/metrics/permissions` returns a normal `{data, count}` envelope.
|
|
76
|
+
The complete set is normalized and sorted by account in the client because
|
|
77
|
+
Redis ordering is nondeterministic.
|
|
78
|
+
- A permission value may be a single string, an array, or `null`; all normalize
|
|
79
|
+
to `string[]` for the controlled `TagInput` fields.
|
|
80
|
+
- `POST /api/metrics/permissions/<encoded-account>` sends
|
|
81
|
+
`view_permissions` and `write_permissions` as CSV strings.
|
|
82
|
+
- The POST result is asymmetric: `account`, `view_permissions`, and
|
|
83
|
+
`write_permissions` are top-level envelope fields, not nested under `data`.
|
|
84
|
+
- `DELETE /api/metrics/permissions/<encoded-account>` clears both permission
|
|
85
|
+
keys. It does not delete the metrics account registry entry, so the table
|
|
86
|
+
refetches authoritatively and retains the row with empty tags.
|
|
87
|
+
|
|
88
|
+
Accounts are immutable in this surface. There is no fake add, search, paging,
|
|
89
|
+
or client table framework. Every save and clear refetches the authoritative
|
|
90
|
+
list. Empty tags are submitted as empty CSV strings, matching the backend's
|
|
91
|
+
current contract.
|
|
92
|
+
|
|
93
|
+
## Styling and showcase
|
|
94
|
+
|
|
95
|
+
Monitoring components use semantic `monitoring-*` classes and application
|
|
96
|
+
tokens only. A consuming app must include `admin-monitoring.css`. This repo's
|
|
97
|
+
portal and showcase theme entries do so. The showcase's Admin Monitoring demo
|
|
98
|
+
contains static request, response, JSON, and HTML-looking plain-text cases for
|
|
99
|
+
both-theme verification without mutating a backend.
|