nuxt-observe 0.0.2
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 +92 -0
- package/dist/module.d.mts +7 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +393 -0
- package/dist/runtime/app/assets/css/main.css +1 -0
- package/dist/runtime/app/components/ObserveActivityFeed.d.vue.ts +13 -0
- package/dist/runtime/app/components/ObserveActivityFeed.vue +77 -0
- package/dist/runtime/app/components/ObserveActivityFeed.vue.d.ts +13 -0
- package/dist/runtime/app/components/ObserveActivityTable.d.vue.ts +30 -0
- package/dist/runtime/app/components/ObserveActivityTable.vue +187 -0
- package/dist/runtime/app/components/ObserveActivityTable.vue.d.ts +30 -0
- package/dist/runtime/app/components/ObserveCan.d.vue.ts +27 -0
- package/dist/runtime/app/components/ObserveCan.vue +16 -0
- package/dist/runtime/app/components/ObserveCan.vue.d.ts +27 -0
- package/dist/runtime/app/components/ObserveErrorsTable.d.vue.ts +19 -0
- package/dist/runtime/app/components/ObserveErrorsTable.vue +105 -0
- package/dist/runtime/app/components/ObserveErrorsTable.vue.d.ts +19 -0
- package/dist/runtime/app/components/ObserveHealthHero.d.vue.ts +16 -0
- package/dist/runtime/app/components/ObserveHealthHero.vue +114 -0
- package/dist/runtime/app/components/ObserveHealthHero.vue.d.ts +16 -0
- package/dist/runtime/app/components/ObserveJourneySearch.d.vue.ts +13 -0
- package/dist/runtime/app/components/ObserveJourneySearch.vue +55 -0
- package/dist/runtime/app/components/ObserveJourneySearch.vue.d.ts +13 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.d.vue.ts +14 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.vue +119 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.vue.d.ts +14 -0
- package/dist/runtime/app/components/ObserveLogDetail.d.vue.ts +12 -0
- package/dist/runtime/app/components/ObserveLogDetail.vue +187 -0
- package/dist/runtime/app/components/ObserveLogDetail.vue.d.ts +12 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.d.vue.ts +10 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.vue +29 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.vue.d.ts +10 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.d.vue.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.vue +134 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.vue.d.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsTable.d.vue.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsTable.vue +92 -0
- package/dist/runtime/app/components/ObserveLogsTable.vue.d.ts +20 -0
- package/dist/runtime/app/components/ObservePeriodSelector.d.vue.ts +3 -0
- package/dist/runtime/app/components/ObservePeriodSelector.vue +22 -0
- package/dist/runtime/app/components/ObservePeriodSelector.vue.d.ts +3 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.d.vue.ts +12 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.vue +27 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.vue.d.ts +12 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.d.vue.ts +3 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.vue +49 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.vue.d.ts +3 -0
- package/dist/runtime/app/components/ObserveServicesTable.d.vue.ts +15 -0
- package/dist/runtime/app/components/ObserveServicesTable.vue +109 -0
- package/dist/runtime/app/components/ObserveServicesTable.vue.d.ts +15 -0
- package/dist/runtime/app/components/ObserveStatCard.d.vue.ts +14 -0
- package/dist/runtime/app/components/ObserveStatCard.vue +34 -0
- package/dist/runtime/app/components/ObserveStatCard.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.d.vue.ts +15 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue +170 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue.d.ts +15 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.d.vue.ts +17 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue +208 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue.d.ts +17 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.d.vue.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue +208 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.d.vue.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue +190 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.d.vue.ts +16 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue +199 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue.d.ts +16 -0
- package/dist/runtime/app/components/charts/chart-core.d.ts +64 -0
- package/dist/runtime/app/components/charts/chart-core.js +136 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.d.vue.ts +8 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue +145 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue.d.ts +8 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.d.vue.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue +106 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue.d.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.d.vue.ts +12 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue +67 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue.d.ts +12 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.d.vue.ts +18 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue +60 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue.d.ts +18 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.d.vue.ts +20 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue +21 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue.d.ts +20 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.d.vue.ts +15 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue +63 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue.d.ts +15 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.d.vue.ts +38 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue +216 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue.d.ts +38 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.d.vue.ts +37 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue +192 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue.d.ts +37 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.d.vue.ts +11 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue +18 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue.d.ts +11 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.d.vue.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue +132 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue.d.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.d.vue.ts +27 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.vue +108 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.vue.d.ts +27 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.d.vue.ts +17 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue +20 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue.d.ts +17 -0
- package/dist/runtime/app/composables/useObserveAbility.d.ts +15 -0
- package/dist/runtime/app/composables/useObserveAbility.js +20 -0
- package/dist/runtime/app/composables/useObserveActivity.d.ts +22 -0
- package/dist/runtime/app/composables/useObserveActivity.js +44 -0
- package/dist/runtime/app/composables/useObserveApiKeys.d.ts +15 -0
- package/dist/runtime/app/composables/useObserveApiKeys.js +19 -0
- package/dist/runtime/app/composables/useObserveAssignments.d.ts +19 -0
- package/dist/runtime/app/composables/useObserveAssignments.js +16 -0
- package/dist/runtime/app/composables/useObserveErrors.d.ts +33 -0
- package/dist/runtime/app/composables/useObserveErrors.js +85 -0
- package/dist/runtime/app/composables/useObserveGroups.d.ts +27 -0
- package/dist/runtime/app/composables/useObserveGroups.js +33 -0
- package/dist/runtime/app/composables/useObserveJourney.d.ts +19 -0
- package/dist/runtime/app/composables/useObserveJourney.js +19 -0
- package/dist/runtime/app/composables/useObserveLogFacets.d.ts +11 -0
- package/dist/runtime/app/composables/useObserveLogFacets.js +21 -0
- package/dist/runtime/app/composables/useObserveLogs.d.ts +28 -0
- package/dist/runtime/app/composables/useObserveLogs.js +100 -0
- package/dist/runtime/app/composables/useObserveMigrations.d.ts +17 -0
- package/dist/runtime/app/composables/useObserveMigrations.js +49 -0
- package/dist/runtime/app/composables/useObserveOverview.d.ts +14 -0
- package/dist/runtime/app/composables/useObserveOverview.js +23 -0
- package/dist/runtime/app/composables/useObservePeriod.d.ts +11 -0
- package/dist/runtime/app/composables/useObservePeriod.js +18 -0
- package/dist/runtime/app/composables/useObserveRollout.d.ts +20 -0
- package/dist/runtime/app/composables/useObserveRollout.js +55 -0
- package/dist/runtime/app/composables/useObserveScope.d.ts +13 -0
- package/dist/runtime/app/composables/useObserveScope.js +17 -0
- package/dist/runtime/app/composables/useObserveServices.d.ts +26 -0
- package/dist/runtime/app/composables/useObserveServices.js +33 -0
- package/dist/runtime/app/composables/useObserveStats.d.ts +14 -0
- package/dist/runtime/app/composables/useObserveStats.js +23 -0
- package/dist/runtime/app/composables/useObserveUsers.d.ts +29 -0
- package/dist/runtime/app/composables/useObserveUsers.js +33 -0
- package/dist/runtime/app/layouts/observe.d.vue.ts +13 -0
- package/dist/runtime/app/layouts/observe.vue +138 -0
- package/dist/runtime/app/layouts/observe.vue.d.ts +13 -0
- package/dist/runtime/app/middleware/observe-auth.global.d.ts +9 -0
- package/dist/runtime/app/middleware/observe-auth.global.js +8 -0
- package/dist/runtime/app/pages/activity.d.vue.ts +3 -0
- package/dist/runtime/app/pages/activity.vue +54 -0
- package/dist/runtime/app/pages/activity.vue.d.ts +3 -0
- package/dist/runtime/app/pages/error-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/error-detail.vue +190 -0
- package/dist/runtime/app/pages/error-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/errors.d.vue.ts +3 -0
- package/dist/runtime/app/pages/errors.vue +47 -0
- package/dist/runtime/app/pages/errors.vue.d.ts +3 -0
- package/dist/runtime/app/pages/journey.d.vue.ts +3 -0
- package/dist/runtime/app/pages/journey.vue +96 -0
- package/dist/runtime/app/pages/journey.vue.d.ts +3 -0
- package/dist/runtime/app/pages/log-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/log-detail.vue +35 -0
- package/dist/runtime/app/pages/log-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/login.d.vue.ts +3 -0
- package/dist/runtime/app/pages/login.vue +69 -0
- package/dist/runtime/app/pages/login.vue.d.ts +3 -0
- package/dist/runtime/app/pages/logs.d.vue.ts +3 -0
- package/dist/runtime/app/pages/logs.vue +36 -0
- package/dist/runtime/app/pages/logs.vue.d.ts +3 -0
- package/dist/runtime/app/pages/metrics.d.vue.ts +3 -0
- package/dist/runtime/app/pages/metrics.vue +68 -0
- package/dist/runtime/app/pages/metrics.vue.d.ts +3 -0
- package/dist/runtime/app/pages/overview.d.vue.ts +3 -0
- package/dist/runtime/app/pages/overview.vue +65 -0
- package/dist/runtime/app/pages/overview.vue.d.ts +3 -0
- package/dist/runtime/app/pages/rollout.d.vue.ts +3 -0
- package/dist/runtime/app/pages/rollout.vue +188 -0
- package/dist/runtime/app/pages/rollout.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/group-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/group-detail.vue +149 -0
- package/dist/runtime/app/pages/settings/group-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/groups.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/groups.vue +107 -0
- package/dist/runtime/app/pages/settings/groups.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/index.vue +47 -0
- package/dist/runtime/app/pages/settings/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/migrations.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/migrations.vue +275 -0
- package/dist/runtime/app/pages/settings/migrations.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/service-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/service-detail.vue +133 -0
- package/dist/runtime/app/pages/settings/service-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/services.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/services.vue +66 -0
- package/dist/runtime/app/pages/settings/services.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/users/[id].d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/users/[id].vue +243 -0
- package/dist/runtime/app/pages/settings/users/[id].vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/users/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/users/index.vue +129 -0
- package/dist/runtime/app/pages/settings/users/index.vue.d.ts +3 -0
- package/dist/runtime/options.d.ts +1 -0
- package/dist/runtime/options.js +1 -0
- package/dist/runtime/server/api/observe/activity.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/activity.get.js +30 -0
- package/dist/runtime/server/api/observe/auth/login.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/auth/login.post.js +13 -0
- package/dist/runtime/server/api/observe/auth/logout.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/auth/logout.post.js +6 -0
- package/dist/runtime/server/api/observe/auth/me.get.d.ts +2 -0
- package/dist/runtime/server/api/observe/auth/me.get.js +3 -0
- package/dist/runtime/server/api/observe/errors/[fingerprint].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/errors/[fingerprint].get.js +56 -0
- package/dist/runtime/server/api/observe/errors/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/errors/index.get.js +41 -0
- package/dist/runtime/server/api/observe/facets.get.d.ts +8 -0
- package/dist/runtime/server/api/observe/facets.get.js +12 -0
- package/dist/runtime/server/api/observe/groups/[id]/assignments.put.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/[id]/assignments.put.js +12 -0
- package/dist/runtime/server/api/observe/groups/[id]/services.put.d.ts +5 -0
- package/dist/runtime/server/api/observe/groups/[id]/services.put.js +13 -0
- package/dist/runtime/server/api/observe/groups/[id].delete.d.ts +5 -0
- package/dist/runtime/server/api/observe/groups/[id].delete.js +11 -0
- package/dist/runtime/server/api/observe/groups/[id].get.d.ts +6 -0
- package/dist/runtime/server/api/observe/groups/[id].get.js +14 -0
- package/dist/runtime/server/api/observe/groups/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/[id].patch.js +12 -0
- package/dist/runtime/server/api/observe/groups/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/index.get.js +7 -0
- package/dist/runtime/server/api/observe/groups/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/index.post.js +11 -0
- package/dist/runtime/server/api/observe/health.get.d.ts +6 -0
- package/dist/runtime/server/api/observe/health.get.js +10 -0
- package/dist/runtime/server/api/observe/ingest/frogger.d.ts +5 -0
- package/dist/runtime/server/api/observe/ingest/frogger.js +42 -0
- package/dist/runtime/server/api/observe/ingest.d.ts +5 -0
- package/dist/runtime/server/api/observe/ingest.js +38 -0
- package/dist/runtime/server/api/observe/journey.get.d.ts +9 -0
- package/dist/runtime/server/api/observe/journey.get.js +31 -0
- package/dist/runtime/server/api/observe/logs/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/logs/[id].get.js +19 -0
- package/dist/runtime/server/api/observe/logs.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/logs.get.js +54 -0
- package/dist/runtime/server/api/observe/migrations/index.get.d.ts +9 -0
- package/dist/runtime/server/api/observe/migrations/index.get.js +14 -0
- package/dist/runtime/server/api/observe/migrations/run.post.d.ts +13 -0
- package/dist/runtime/server/api/observe/migrations/run.post.js +35 -0
- package/dist/runtime/server/api/observe/overview.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/overview.get.js +19 -0
- package/dist/runtime/server/api/observe/rollout/compare.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/compare.get.js +24 -0
- package/dist/runtime/server/api/observe/rollout/regressions.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/regressions.get.js +31 -0
- package/dist/runtime/server/api/observe/rollout/versions.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/versions.get.js +20 -0
- package/dist/runtime/server/api/observe/services/[id]/assignments.put.d.ts +7 -0
- package/dist/runtime/server/api/observe/services/[id]/assignments.put.js +12 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.js +14 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.js +14 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.get.js +10 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.post.js +11 -0
- package/dist/runtime/server/api/observe/services/[id]/restore.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/restore.post.js +11 -0
- package/dist/runtime/server/api/observe/services/[id].delete.d.ts +11 -0
- package/dist/runtime/server/api/observe/services/[id].delete.js +11 -0
- package/dist/runtime/server/api/observe/services/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id].get.js +12 -0
- package/dist/runtime/server/api/observe/services/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id].patch.js +13 -0
- package/dist/runtime/server/api/observe/services/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/index.get.js +7 -0
- package/dist/runtime/server/api/observe/services/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/index.post.js +16 -0
- package/dist/runtime/server/api/observe/stats.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/stats.get.js +28 -0
- package/dist/runtime/server/api/observe/users/[id]/assignments.put.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id]/assignments.put.js +14 -0
- package/dist/runtime/server/api/observe/users/[id].delete.d.ts +4 -0
- package/dist/runtime/server/api/observe/users/[id].delete.js +15 -0
- package/dist/runtime/server/api/observe/users/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id].get.js +11 -0
- package/dist/runtime/server/api/observe/users/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id].patch.js +25 -0
- package/dist/runtime/server/api/observe/users/index.get.d.ts +8 -0
- package/dist/runtime/server/api/observe/users/index.get.js +7 -0
- package/dist/runtime/server/api/observe/users/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/index.post.js +29 -0
- package/dist/runtime/server/auth/authorization.d.ts +7 -0
- package/dist/runtime/server/auth/authorization.js +5 -0
- package/dist/runtime/server/auth/provider.d.ts +17 -0
- package/dist/runtime/server/auth/provider.js +44 -0
- package/dist/runtime/server/auth/providers/config-provider.d.ts +18 -0
- package/dist/runtime/server/auth/providers/config-provider.js +54 -0
- package/dist/runtime/server/auth/providers/db-provider.d.ts +16 -0
- package/dist/runtime/server/auth/providers/db-provider.js +42 -0
- package/dist/runtime/server/auth/providers/jwt-provider.d.ts +24 -0
- package/dist/runtime/server/auth/providers/jwt-provider.js +72 -0
- package/dist/runtime/server/migrations/0001-services-kind.d.ts +8 -0
- package/dist/runtime/server/migrations/0001-services-kind.js +14 -0
- package/dist/runtime/server/migrations/0002-services-type.d.ts +7 -0
- package/dist/runtime/server/migrations/0002-services-type.js +14 -0
- package/dist/runtime/server/migrations/0003-services-deleted-at.d.ts +6 -0
- package/dist/runtime/server/migrations/0003-services-deleted-at.js +14 -0
- package/dist/runtime/server/migrations/0004-logs-error-fingerprint.d.ts +11 -0
- package/dist/runtime/server/migrations/0004-logs-error-fingerprint.js +15 -0
- package/dist/runtime/server/migrations/0005-users-columns.d.ts +9 -0
- package/dist/runtime/server/migrations/0005-users-columns.js +25 -0
- package/dist/runtime/server/migrations/index.d.ts +13 -0
- package/dist/runtime/server/migrations/index.js +13 -0
- package/dist/runtime/server/migrations/types.d.ts +15 -0
- package/dist/runtime/server/migrations/types.js +0 -0
- package/dist/runtime/server/plugins/observe-migrate.server.d.ts +2 -0
- package/dist/runtime/server/plugins/observe-migrate.server.js +18 -0
- package/dist/runtime/server/tasks/backfill-fingerprints.d.ts +11 -0
- package/dist/runtime/server/tasks/backfill-fingerprints.js +41 -0
- package/dist/runtime/server/tasks/purge.d.ts +5 -0
- package/dist/runtime/server/tasks/purge.js +12 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/server/utils/activity-query.d.ts +28 -0
- package/dist/runtime/server/utils/activity-query.js +70 -0
- package/dist/runtime/server/utils/api-keys.d.ts +48 -0
- package/dist/runtime/server/utils/api-keys.js +67 -0
- package/dist/runtime/server/utils/authz.d.ts +50 -0
- package/dist/runtime/server/utils/authz.js +60 -0
- package/dist/runtime/server/utils/db/users.d.ts +91 -0
- package/dist/runtime/server/utils/db/users.js +128 -0
- package/dist/runtime/server/utils/db.d.ts +10 -0
- package/dist/runtime/server/utils/db.js +5 -0
- package/dist/runtime/server/utils/frogger-adapter.d.ts +40 -0
- package/dist/runtime/server/utils/frogger-adapter.js +97 -0
- package/dist/runtime/server/utils/groups.d.ts +35 -0
- package/dist/runtime/server/utils/groups.js +59 -0
- package/dist/runtime/server/utils/ingest-cors.d.ts +23 -0
- package/dist/runtime/server/utils/ingest-cors.js +27 -0
- package/dist/runtime/server/utils/journey.d.ts +20 -0
- package/dist/runtime/server/utils/journey.js +44 -0
- package/dist/runtime/server/utils/logs.d.ts +50 -0
- package/dist/runtime/server/utils/logs.js +154 -0
- package/dist/runtime/server/utils/loop-guard.d.ts +11 -0
- package/dist/runtime/server/utils/loop-guard.js +11 -0
- package/dist/runtime/server/utils/migrate.d.ts +21 -0
- package/dist/runtime/server/utils/migrate.js +144 -0
- package/dist/runtime/server/utils/migration-runner.d.ts +42 -0
- package/dist/runtime/server/utils/migration-runner.js +129 -0
- package/dist/runtime/server/utils/observe-errors.d.ts +58 -0
- package/dist/runtime/server/utils/observe-errors.js +206 -0
- package/dist/runtime/server/utils/overview.d.ts +20 -0
- package/dist/runtime/server/utils/overview.js +119 -0
- package/dist/runtime/server/utils/provisioning.d.ts +62 -0
- package/dist/runtime/server/utils/provisioning.js +299 -0
- package/dist/runtime/server/utils/rate-limit.d.ts +11 -0
- package/dist/runtime/server/utils/rate-limit.js +22 -0
- package/dist/runtime/server/utils/require-observe-session.d.ts +15 -0
- package/dist/runtime/server/utils/require-observe-session.js +25 -0
- package/dist/runtime/server/utils/rollout.d.ts +19 -0
- package/dist/runtime/server/utils/rollout.js +56 -0
- package/dist/runtime/server/utils/scope.d.ts +14 -0
- package/dist/runtime/server/utils/scope.js +28 -0
- package/dist/runtime/server/utils/seed.d.ts +18 -0
- package/dist/runtime/server/utils/seed.js +70 -0
- package/dist/runtime/server/utils/services.d.ts +91 -0
- package/dist/runtime/server/utils/services.js +142 -0
- package/dist/runtime/server/utils/stats-query.d.ts +40 -0
- package/dist/runtime/server/utils/stats-query.js +104 -0
- package/dist/runtime/shared/auth/roles.d.ts +34 -0
- package/dist/runtime/shared/auth/roles.js +6 -0
- package/dist/runtime/shared/auth/schema.d.ts +85 -0
- package/dist/runtime/shared/auth/schema.js +41 -0
- package/dist/runtime/shared/auth/types.d.ts +68 -0
- package/dist/runtime/shared/auth/types.js +0 -0
- package/dist/runtime/shared/rbac/capabilities.d.ts +46 -0
- package/dist/runtime/shared/rbac/capabilities.js +48 -0
- package/dist/runtime/shared/schema/activity.d.ts +77 -0
- package/dist/runtime/shared/schema/activity.js +22 -0
- package/dist/runtime/shared/schema/adapters/frogger.d.ts +52 -0
- package/dist/runtime/shared/schema/adapters/frogger.js +17 -0
- package/dist/runtime/shared/schema/batch.d.ts +33 -0
- package/dist/runtime/shared/schema/batch.js +9 -0
- package/dist/runtime/shared/schema/error-fingerprint.d.ts +53 -0
- package/dist/runtime/shared/schema/error-fingerprint.js +47 -0
- package/dist/runtime/shared/schema/errors-query.d.ts +136 -0
- package/dist/runtime/shared/schema/errors-query.js +47 -0
- package/dist/runtime/shared/schema/event.d.ts +48 -0
- package/dist/runtime/shared/schema/event.js +41 -0
- package/dist/runtime/shared/schema/frogger-map.d.ts +62 -0
- package/dist/runtime/shared/schema/frogger-map.js +30 -0
- package/dist/runtime/shared/schema/index.d.ts +17 -0
- package/dist/runtime/shared/schema/index.js +17 -0
- package/dist/runtime/shared/schema/journey.d.ts +99 -0
- package/dist/runtime/shared/schema/journey.js +96 -0
- package/dist/runtime/shared/schema/levels.d.ts +37 -0
- package/dist/runtime/shared/schema/levels.js +72 -0
- package/dist/runtime/shared/schema/log-row.d.ts +31 -0
- package/dist/runtime/shared/schema/log-row.js +0 -0
- package/dist/runtime/shared/schema/logs-query.d.ts +91 -0
- package/dist/runtime/shared/schema/logs-query.js +72 -0
- package/dist/runtime/shared/schema/migrations.d.ts +34 -0
- package/dist/runtime/shared/schema/migrations.js +0 -0
- package/dist/runtime/shared/schema/overview.d.ts +78 -0
- package/dist/runtime/shared/schema/overview.js +9 -0
- package/dist/runtime/shared/schema/provisioning.d.ts +230 -0
- package/dist/runtime/shared/schema/provisioning.js +52 -0
- package/dist/runtime/shared/schema/registry.d.ts +115 -0
- package/dist/runtime/shared/schema/registry.js +27 -0
- package/dist/runtime/shared/schema/rollout.d.ts +103 -0
- package/dist/runtime/shared/schema/rollout.js +66 -0
- package/dist/runtime/shared/schema/stats.d.ts +64 -0
- package/dist/runtime/shared/schema/stats.js +15 -0
- package/dist/runtime/shared/schema/tiers.d.ts +5 -0
- package/dist/runtime/shared/schema/tiers.js +9 -0
- package/dist/runtime/shared/types/module-options.d.ts +119 -0
- package/dist/runtime/shared/types/module-options.js +13 -0
- package/dist/runtime/shared/types/storage.d.ts +31 -0
- package/dist/runtime/shared/types/storage.js +0 -0
- package/dist/runtime/shared/utils/format-relative.d.ts +7 -0
- package/dist/runtime/shared/utils/format-relative.js +11 -0
- package/dist/runtime/shared/utils/frogger-snippet.d.ts +19 -0
- package/dist/runtime/shared/utils/frogger-snippet.js +33 -0
- package/dist/runtime/shared/utils/observe-config.d.ts +9 -0
- package/dist/runtime/shared/utils/observe-config.js +17 -0
- package/dist/runtime/shared/utils/period.d.ts +13 -0
- package/dist/runtime/shared/utils/period.js +15 -0
- package/dist/runtime/shared/utils/slug.d.ts +1 -0
- package/dist/runtime/shared/utils/slug.js +5 -0
- package/dist/runtime/shared/utils/uuid.d.ts +187 -0
- package/dist/runtime/shared/utils/uuid.js +345 -0
- package/dist/runtime/types/nuxt-auth-utils-imports.d.ts +25 -0
- package/dist/runtime/types/observe-app-imports.d.ts +20 -0
- package/dist/runtime/types/session.d.ts +17 -0
- package/dist/schema.d.mts +1318 -0
- package/dist/schema.mjs +629 -0
- package/dist/types.d.mts +3 -0
- package/package.json +93 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
|
|
3
|
+
import { select, scaleTime, scaleLinear, axisBottom, axisLeft, line, max } from "d3";
|
|
4
|
+
import {
|
|
5
|
+
CHART_MARGIN,
|
|
6
|
+
CHART_HEIGHT,
|
|
7
|
+
formatPct,
|
|
8
|
+
bucketTimeFormatter,
|
|
9
|
+
createTooltip,
|
|
10
|
+
attachBucketInteraction,
|
|
11
|
+
seriesColorMap
|
|
12
|
+
} from "./chart-core";
|
|
13
|
+
const props = defineProps({
|
|
14
|
+
compare: { type: null, required: true },
|
|
15
|
+
pending: { type: Boolean, required: false }
|
|
16
|
+
});
|
|
17
|
+
const host = ref(null);
|
|
18
|
+
const svgRef = ref(null);
|
|
19
|
+
const bucketStarts = computed(() => props.compare?.buckets ?? []);
|
|
20
|
+
const series = computed(() => props.compare?.series ?? []);
|
|
21
|
+
const bucketMs = computed(() => bucketStarts.value.length > 1 ? bucketStarts.value[1] - bucketStarts.value[0] : 1);
|
|
22
|
+
const hasData = computed(() => series.value.some((s) => s.volume.some((v) => v > 0)));
|
|
23
|
+
const windowMs = computed(() => bucketStarts.value.length * bucketMs.value);
|
|
24
|
+
const timeLabel = computed(() => bucketTimeFormatter(bucketMs.value, windowMs.value));
|
|
25
|
+
const colorOf = computed(() => seriesColorMap(series.value.map((s) => ({ id: s.version, slug: s.version }))));
|
|
26
|
+
const hitBuckets = computed(
|
|
27
|
+
() => bucketStarts.value.map((t) => ({ t, count: 0, errorCount: 0, warnCount: 0, byService: {} }))
|
|
28
|
+
);
|
|
29
|
+
const tableIndexes = computed(
|
|
30
|
+
() => bucketStarts.value.map((_, i) => i).filter((i) => series.value.some((s) => (s.volume[i] ?? 0) > 0))
|
|
31
|
+
);
|
|
32
|
+
let tooltip;
|
|
33
|
+
let interaction;
|
|
34
|
+
let resizeObserver;
|
|
35
|
+
let crosshairEl = null;
|
|
36
|
+
const hitState = { buckets: [], bucketMs: 1, xFor: () => 0, plotWidth: 1 };
|
|
37
|
+
function draw() {
|
|
38
|
+
const svgEl = svgRef.value;
|
|
39
|
+
const hostEl = host.value;
|
|
40
|
+
if (!svgEl || !hostEl) return;
|
|
41
|
+
const width = hostEl.clientWidth;
|
|
42
|
+
if (width <= 0) return;
|
|
43
|
+
const plotW = Math.max(1, width - CHART_MARGIN.left - CHART_MARGIN.right);
|
|
44
|
+
const plotH = CHART_HEIGHT - CHART_MARGIN.top - CHART_MARGIN.bottom;
|
|
45
|
+
const svg = select(svgEl).attr("width", width).attr("height", CHART_HEIGHT);
|
|
46
|
+
svg.selectAll("*").remove();
|
|
47
|
+
crosshairEl = null;
|
|
48
|
+
const starts = bucketStarts.value;
|
|
49
|
+
hitState.buckets = hasData.value ? hitBuckets.value : [];
|
|
50
|
+
hitState.bucketMs = bucketMs.value;
|
|
51
|
+
hitState.plotWidth = plotW;
|
|
52
|
+
if (!starts.length || !hasData.value) return;
|
|
53
|
+
const t0 = starts[0];
|
|
54
|
+
const t1 = starts[starts.length - 1] + bucketMs.value;
|
|
55
|
+
const x = scaleTime().domain([new Date(t0), new Date(t1)]).range([0, plotW]);
|
|
56
|
+
const rateAt = (s, i) => (s.errorRate[i] ?? 0) * 100;
|
|
57
|
+
const maxRate = max(series.value, (s) => max(s.errorRate.map((r) => r * 100)) ?? 0) ?? 0;
|
|
58
|
+
const y = scaleLinear().domain([0, Math.min(100, Math.max(5, maxRate * 1.2))]).nice(4).range([plotH, 0]);
|
|
59
|
+
hitState.xFor = (t) => x(new Date(t));
|
|
60
|
+
const g = svg.append("g").attr("transform", `translate(${CHART_MARGIN.left},${CHART_MARGIN.top})`);
|
|
61
|
+
g.append("g").attr("class", "observe-grid").selectAll("line").data(y.ticks(4).filter((t) => t > 0)).join("line").attr("x1", 0).attr("x2", plotW).attr("y1", (d) => y(d)).attr("y2", (d) => y(d));
|
|
62
|
+
g.append("g").attr("transform", `translate(0,${plotH})`).call(axisBottom(x).ticks(Math.max(3, Math.min(8, Math.floor(plotW / 90)))).tickSizeOuter(0));
|
|
63
|
+
g.append("g").call(axisLeft(y).ticks(4).tickSize(0).tickPadding(8).tickFormat((d) => formatPct(+d))).call((sel) => sel.select(".domain").remove());
|
|
64
|
+
const cx = (i) => x(new Date(starts[i] + bucketMs.value / 2));
|
|
65
|
+
for (const s of series.value) {
|
|
66
|
+
const rateLine = line().defined((i) => (s.volume[i] ?? 0) > 0).x((i) => cx(i)).y((i) => y(rateAt(s, i)));
|
|
67
|
+
g.append("path").datum(starts.map((_, i) => i)).attr("d", rateLine).style("fill", "none").style("stroke", colorOf.value.get(s.version)).style("stroke-width", 2).attr("stroke-linejoin", "round").attr("stroke-linecap", "round");
|
|
68
|
+
}
|
|
69
|
+
crosshairEl = g.append("line").attr("class", "observe-crosshair").attr("y1", 0).attr("y2", plotH).style("display", "none").node();
|
|
70
|
+
}
|
|
71
|
+
function handleHit(bucket, index, cx) {
|
|
72
|
+
if (crosshairEl) {
|
|
73
|
+
crosshairEl.style.display = "";
|
|
74
|
+
crosshairEl.setAttribute("x1", String(cx));
|
|
75
|
+
crosshairEl.setAttribute("x2", String(cx));
|
|
76
|
+
}
|
|
77
|
+
const rows = series.value.map((s) => ({ version: s.version, v: s.volume[index] ?? 0, rate: (s.errorRate[index] ?? 0) * 100 })).filter((r) => r.v > 0).sort((a, b) => b.rate - a.rate).map((r) => ({ color: colorOf.value.get(r.version), label: r.version, value: formatPct(r.rate) }));
|
|
78
|
+
tooltip?.show(cx, timeLabel.value(bucket.t), rows.length ? rows : [{ label: "no events", value: "" }]);
|
|
79
|
+
}
|
|
80
|
+
function handleClear() {
|
|
81
|
+
if (crosshairEl) crosshairEl.style.display = "none";
|
|
82
|
+
tooltip?.hide();
|
|
83
|
+
}
|
|
84
|
+
onMounted(async () => {
|
|
85
|
+
await nextTick();
|
|
86
|
+
if (host.value) {
|
|
87
|
+
tooltip = createTooltip(host.value);
|
|
88
|
+
resizeObserver = new ResizeObserver(() => draw());
|
|
89
|
+
resizeObserver.observe(host.value);
|
|
90
|
+
}
|
|
91
|
+
if (svgRef.value) {
|
|
92
|
+
interaction = attachBucketInteraction(svgRef.value, hitState, handleHit, handleClear);
|
|
93
|
+
}
|
|
94
|
+
draw();
|
|
95
|
+
});
|
|
96
|
+
watch(() => props.compare, () => {
|
|
97
|
+
interaction?.clear();
|
|
98
|
+
draw();
|
|
99
|
+
});
|
|
100
|
+
onBeforeUnmount(() => {
|
|
101
|
+
interaction?.destroy();
|
|
102
|
+
tooltip?.destroy();
|
|
103
|
+
resizeObserver?.disconnect();
|
|
104
|
+
if (svgRef.value) select(svgRef.value).selectAll("*").remove();
|
|
105
|
+
});
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<template>
|
|
109
|
+
<section>
|
|
110
|
+
<div class="flex items-baseline justify-between gap-4 mb-2">
|
|
111
|
+
<h2 class="text-xs font-semibold uppercase tracking-wider text-muted">
|
|
112
|
+
Error rate by version
|
|
113
|
+
</h2>
|
|
114
|
+
<div class="flex flex-wrap items-center justify-end gap-x-3 gap-y-1 text-xs text-muted min-w-0">
|
|
115
|
+
<span
|
|
116
|
+
v-for="s in series"
|
|
117
|
+
:key="s.version"
|
|
118
|
+
class="flex items-center gap-1.5"
|
|
119
|
+
>
|
|
120
|
+
<span
|
|
121
|
+
class="size-2 rounded-full shrink-0"
|
|
122
|
+
:style="{ background: colorOf.get(s.version) }"
|
|
123
|
+
/>
|
|
124
|
+
<span class="truncate max-w-32">{{ s.version }}</span>
|
|
125
|
+
</span>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<UCard :ui="{ body: 'p-2 sm:p-3' }">
|
|
130
|
+
<div
|
|
131
|
+
ref="host"
|
|
132
|
+
class="relative"
|
|
133
|
+
>
|
|
134
|
+
<svg
|
|
135
|
+
v-show="hasData"
|
|
136
|
+
ref="svgRef"
|
|
137
|
+
class="observe-chart block w-full transition-opacity"
|
|
138
|
+
:class="{ 'opacity-60': pending }"
|
|
139
|
+
tabindex="0"
|
|
140
|
+
role="img"
|
|
141
|
+
aria-label="Error rate percentage over time, one line per version. Use arrow keys to read values per time bucket."
|
|
142
|
+
/>
|
|
143
|
+
<USkeleton
|
|
144
|
+
v-if="pending && !hasData"
|
|
145
|
+
class="h-60 w-full"
|
|
146
|
+
/>
|
|
147
|
+
<p
|
|
148
|
+
v-else-if="!hasData"
|
|
149
|
+
class="h-60 flex items-center justify-center text-sm text-muted"
|
|
150
|
+
>
|
|
151
|
+
No versioned events in this window.
|
|
152
|
+
</p>
|
|
153
|
+
|
|
154
|
+
<div
|
|
155
|
+
v-if="hasData"
|
|
156
|
+
class="sr-only"
|
|
157
|
+
>
|
|
158
|
+
<table>
|
|
159
|
+
<caption>Error rate by version per time bucket</caption>
|
|
160
|
+
<thead>
|
|
161
|
+
<tr>
|
|
162
|
+
<th>Time</th>
|
|
163
|
+
<th
|
|
164
|
+
v-for="s in series"
|
|
165
|
+
:key="s.version"
|
|
166
|
+
>
|
|
167
|
+
{{ s.version }}
|
|
168
|
+
</th>
|
|
169
|
+
</tr>
|
|
170
|
+
</thead>
|
|
171
|
+
<tbody>
|
|
172
|
+
<tr
|
|
173
|
+
v-for="i in tableIndexes"
|
|
174
|
+
:key="i"
|
|
175
|
+
>
|
|
176
|
+
<td>{{ timeLabel(bucketStarts[i]) }}</td>
|
|
177
|
+
<td
|
|
178
|
+
v-for="s in series"
|
|
179
|
+
:key="s.version"
|
|
180
|
+
>
|
|
181
|
+
{{ (s.volume[i] ?? 0) > 0 ? formatPct((s.errorRate[i] ?? 0) * 100) : "\u2014" }}
|
|
182
|
+
</td>
|
|
183
|
+
</tr>
|
|
184
|
+
</tbody>
|
|
185
|
+
</table>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</UCard>
|
|
189
|
+
</section>
|
|
190
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { VersionCompare } from '../../../shared/schema/rollout.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error rate by version (CP13): one line per version of its per-bucket error rate,
|
|
4
|
+
* drawn only across buckets where that version had events (d3 line.defined gaps), so a
|
|
5
|
+
* version live for part of the window does not read as 0% before it appeared. Mirrors
|
|
6
|
+
* the CP8 error-rate chart's lifecycle; .client.vue because d3 is SSR-unsafe.
|
|
7
|
+
*/
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
compare: VersionCompare | null | undefined;
|
|
10
|
+
pending?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StatsBucket } from '../../../shared/schema/stats.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stacked-bar volume over time, by level: errors (level 0) anchored at the baseline,
|
|
4
|
+
* warnings above, every other level as a muted remainder, so the stack sums to count.
|
|
5
|
+
* Level colors are the dashboard's status tokens (error/warning), never categorical
|
|
6
|
+
* slots. Client-only (d3 touches the DOM); colors ride CSS vars so light/dark needs
|
|
7
|
+
* no redraw.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
buckets: StatsBucket[];
|
|
11
|
+
bucketMs: number;
|
|
12
|
+
pending?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
|
|
3
|
+
import { select, scaleTime, scaleLinear, axisBottom, axisLeft, max } from "d3";
|
|
4
|
+
import {
|
|
5
|
+
CHART_MARGIN,
|
|
6
|
+
CHART_HEIGHT,
|
|
7
|
+
formatCount,
|
|
8
|
+
bucketTimeFormatter,
|
|
9
|
+
roundedTopRect,
|
|
10
|
+
createTooltip,
|
|
11
|
+
attachBucketInteraction
|
|
12
|
+
} from "./chart-core";
|
|
13
|
+
const props = defineProps({
|
|
14
|
+
buckets: { type: Array, required: true },
|
|
15
|
+
bucketMs: { type: Number, required: true },
|
|
16
|
+
pending: { type: Boolean, required: false }
|
|
17
|
+
});
|
|
18
|
+
const host = ref(null);
|
|
19
|
+
const svgRef = ref(null);
|
|
20
|
+
const hasData = computed(() => props.buckets.some((b) => b.count > 0));
|
|
21
|
+
const windowMs = computed(() => props.buckets.length * props.bucketMs);
|
|
22
|
+
const timeLabel = computed(() => bucketTimeFormatter(props.bucketMs, windowMs.value));
|
|
23
|
+
const tableRows = computed(() => props.buckets.filter((b) => b.count > 0));
|
|
24
|
+
const otherOf = (b) => b.count - b.errorCount - b.warnCount;
|
|
25
|
+
let tooltip;
|
|
26
|
+
let interaction;
|
|
27
|
+
let resizeObserver;
|
|
28
|
+
let crosshairEl = null;
|
|
29
|
+
const hitState = { buckets: [], bucketMs: 1, xFor: () => 0, plotWidth: 1 };
|
|
30
|
+
function draw() {
|
|
31
|
+
const svgEl = svgRef.value;
|
|
32
|
+
const hostEl = host.value;
|
|
33
|
+
if (!svgEl || !hostEl) return;
|
|
34
|
+
const width = hostEl.clientWidth;
|
|
35
|
+
if (width <= 0) return;
|
|
36
|
+
const plotW = Math.max(1, width - CHART_MARGIN.left - CHART_MARGIN.right);
|
|
37
|
+
const plotH = CHART_HEIGHT - CHART_MARGIN.top - CHART_MARGIN.bottom;
|
|
38
|
+
const svg = select(svgEl).attr("width", width).attr("height", CHART_HEIGHT);
|
|
39
|
+
svg.selectAll("*").remove();
|
|
40
|
+
crosshairEl = null;
|
|
41
|
+
const buckets = props.buckets;
|
|
42
|
+
hitState.buckets = hasData.value ? buckets : [];
|
|
43
|
+
hitState.bucketMs = props.bucketMs;
|
|
44
|
+
hitState.plotWidth = plotW;
|
|
45
|
+
if (!buckets.length || !hasData.value) return;
|
|
46
|
+
const t0 = buckets[0].t;
|
|
47
|
+
const t1 = buckets[buckets.length - 1].t + props.bucketMs;
|
|
48
|
+
const x = scaleTime().domain([new Date(t0), new Date(t1)]).range([0, plotW]);
|
|
49
|
+
const y = scaleLinear().domain([0, Math.max(1, max(buckets, (b) => b.count) ?? 0)]).nice(4).range([plotH, 0]);
|
|
50
|
+
hitState.xFor = (t) => x(new Date(t));
|
|
51
|
+
const g = svg.append("g").attr("transform", `translate(${CHART_MARGIN.left},${CHART_MARGIN.top})`);
|
|
52
|
+
const yTicks = y.ticks(4).filter(Number.isInteger);
|
|
53
|
+
g.append("g").attr("class", "observe-grid").selectAll("line").data(yTicks.filter((t) => t > 0)).join("line").attr("x1", 0).attr("x2", plotW).attr("y1", (d) => y(d)).attr("y2", (d) => y(d));
|
|
54
|
+
g.append("g").attr("transform", `translate(0,${plotH})`).call(axisBottom(x).ticks(Math.max(3, Math.min(8, Math.floor(plotW / 90)))).tickSizeOuter(0));
|
|
55
|
+
g.append("g").call(axisLeft(y).tickValues(yTicks).tickSize(0).tickPadding(8).tickFormat((d) => formatCount(+d))).call((sel) => sel.select(".domain").remove());
|
|
56
|
+
const bars = g.append("g");
|
|
57
|
+
for (const b of buckets) {
|
|
58
|
+
if (!b.count) continue;
|
|
59
|
+
const x0 = x(new Date(b.t));
|
|
60
|
+
const wFull = x(new Date(b.t + props.bucketMs)) - x0;
|
|
61
|
+
const gap = wFull >= 4 ? 2 : wFull >= 2 ? 1 : 0;
|
|
62
|
+
const w = Math.max(wFull - gap, Math.min(wFull, 1));
|
|
63
|
+
const segments = [
|
|
64
|
+
{ v: b.errorCount, color: "var(--ui-error)" },
|
|
65
|
+
{ v: b.warnCount, color: "var(--ui-warning)" },
|
|
66
|
+
{ v: otherOf(b), color: "var(--observe-viz-muted)" }
|
|
67
|
+
].filter((s) => s.v > 0);
|
|
68
|
+
let cursor = plotH;
|
|
69
|
+
segments.forEach((s, i) => {
|
|
70
|
+
const h = plotH - y(s.v);
|
|
71
|
+
const top = cursor - h;
|
|
72
|
+
if (i === segments.length - 1) {
|
|
73
|
+
bars.append("path").attr("d", roundedTopRect(x0, top, w, h, 3)).style("fill", s.color);
|
|
74
|
+
} else {
|
|
75
|
+
const drawnH = Math.max(h - 1, 0.5);
|
|
76
|
+
bars.append("rect").attr("x", x0).attr("y", cursor - drawnH).attr("width", w).attr("height", drawnH).style("fill", s.color);
|
|
77
|
+
}
|
|
78
|
+
cursor = top;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
crosshairEl = g.append("line").attr("class", "observe-crosshair").attr("y1", 0).attr("y2", plotH).style("display", "none").node();
|
|
82
|
+
}
|
|
83
|
+
function handleHit(bucket, _index, cx) {
|
|
84
|
+
if (crosshairEl) {
|
|
85
|
+
crosshairEl.style.display = "";
|
|
86
|
+
crosshairEl.setAttribute("x1", String(cx));
|
|
87
|
+
crosshairEl.setAttribute("x2", String(cx));
|
|
88
|
+
}
|
|
89
|
+
tooltip?.show(cx, timeLabel.value(bucket.t), [
|
|
90
|
+
{ color: "var(--ui-error)", label: "errors", value: formatCount(bucket.errorCount) },
|
|
91
|
+
{ color: "var(--ui-warning)", label: "warnings", value: formatCount(bucket.warnCount) },
|
|
92
|
+
{ color: "var(--observe-viz-muted)", label: "other", value: formatCount(otherOf(bucket)) },
|
|
93
|
+
{ label: "total", value: formatCount(bucket.count) }
|
|
94
|
+
]);
|
|
95
|
+
}
|
|
96
|
+
function handleClear() {
|
|
97
|
+
if (crosshairEl) crosshairEl.style.display = "none";
|
|
98
|
+
tooltip?.hide();
|
|
99
|
+
}
|
|
100
|
+
onMounted(async () => {
|
|
101
|
+
await nextTick();
|
|
102
|
+
if (host.value) {
|
|
103
|
+
tooltip = createTooltip(host.value);
|
|
104
|
+
resizeObserver = new ResizeObserver(() => draw());
|
|
105
|
+
resizeObserver.observe(host.value);
|
|
106
|
+
}
|
|
107
|
+
if (svgRef.value) {
|
|
108
|
+
interaction = attachBucketInteraction(svgRef.value, hitState, handleHit, handleClear);
|
|
109
|
+
}
|
|
110
|
+
draw();
|
|
111
|
+
});
|
|
112
|
+
watch(() => [props.buckets, props.bucketMs], () => {
|
|
113
|
+
interaction?.clear();
|
|
114
|
+
draw();
|
|
115
|
+
});
|
|
116
|
+
onBeforeUnmount(() => {
|
|
117
|
+
interaction?.destroy();
|
|
118
|
+
tooltip?.destroy();
|
|
119
|
+
resizeObserver?.disconnect();
|
|
120
|
+
if (svgRef.value) select(svgRef.value).selectAll("*").remove();
|
|
121
|
+
});
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<template>
|
|
125
|
+
<section>
|
|
126
|
+
<div class="flex items-baseline justify-between gap-4 mb-2">
|
|
127
|
+
<h2 class="text-xs font-semibold uppercase tracking-wider text-muted">
|
|
128
|
+
Volume
|
|
129
|
+
</h2>
|
|
130
|
+
<div class="flex items-center gap-3 text-xs text-muted">
|
|
131
|
+
<span class="flex items-center gap-1.5">
|
|
132
|
+
<span class="size-2 rounded-full bg-error" />Errors
|
|
133
|
+
</span>
|
|
134
|
+
<span class="flex items-center gap-1.5">
|
|
135
|
+
<span class="size-2 rounded-full bg-warning" />Warnings
|
|
136
|
+
</span>
|
|
137
|
+
<span class="flex items-center gap-1.5">
|
|
138
|
+
<span
|
|
139
|
+
class="size-2 rounded-full"
|
|
140
|
+
style="background: var(--observe-viz-muted)"
|
|
141
|
+
/>Other
|
|
142
|
+
</span>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<UCard :ui="{ body: 'p-2 sm:p-3' }">
|
|
147
|
+
<div
|
|
148
|
+
ref="host"
|
|
149
|
+
class="relative"
|
|
150
|
+
>
|
|
151
|
+
<svg
|
|
152
|
+
v-show="hasData"
|
|
153
|
+
ref="svgRef"
|
|
154
|
+
class="observe-chart block w-full transition-opacity"
|
|
155
|
+
:class="{ 'opacity-60': pending }"
|
|
156
|
+
tabindex="0"
|
|
157
|
+
role="img"
|
|
158
|
+
aria-label="Event volume over time, stacked by level. Use arrow keys to read values per time bucket."
|
|
159
|
+
/>
|
|
160
|
+
<USkeleton
|
|
161
|
+
v-if="pending && !hasData"
|
|
162
|
+
class="h-60 w-full"
|
|
163
|
+
/>
|
|
164
|
+
<p
|
|
165
|
+
v-else-if="!hasData"
|
|
166
|
+
class="h-60 flex items-center justify-center text-sm text-muted"
|
|
167
|
+
>
|
|
168
|
+
No events in this window.
|
|
169
|
+
</p>
|
|
170
|
+
|
|
171
|
+
<!-- sr-only on a wrapper div, never on the table: a <caption> belongs to the
|
|
172
|
+
table wrapper box and escapes the table's own overflow clip in Firefox. -->
|
|
173
|
+
<div
|
|
174
|
+
v-if="hasData"
|
|
175
|
+
class="sr-only"
|
|
176
|
+
>
|
|
177
|
+
<table>
|
|
178
|
+
<caption>Event volume by level per time bucket</caption>
|
|
179
|
+
<thead>
|
|
180
|
+
<tr><th>Time</th><th>Errors</th><th>Warnings</th><th>Other</th><th>Total</th></tr>
|
|
181
|
+
</thead>
|
|
182
|
+
<tbody>
|
|
183
|
+
<tr
|
|
184
|
+
v-for="b in tableRows"
|
|
185
|
+
:key="b.t"
|
|
186
|
+
>
|
|
187
|
+
<td>{{ timeLabel(b.t) }}</td>
|
|
188
|
+
<td>{{ b.errorCount }}</td>
|
|
189
|
+
<td>{{ b.warnCount }}</td>
|
|
190
|
+
<td>{{ otherOf(b) }}</td>
|
|
191
|
+
<td>{{ b.count }}</td>
|
|
192
|
+
</tr>
|
|
193
|
+
</tbody>
|
|
194
|
+
</table>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</UCard>
|
|
198
|
+
</section>
|
|
199
|
+
</template>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StatsBucket } from '../../../shared/schema/stats.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stacked-bar volume over time, by level: errors (level 0) anchored at the baseline,
|
|
4
|
+
* warnings above, every other level as a muted remainder, so the stack sums to count.
|
|
5
|
+
* Level colors are the dashboard's status tokens (error/warning), never categorical
|
|
6
|
+
* slots. Client-only (d3 touches the DOM); colors ride CSS vars so light/dark needs
|
|
7
|
+
* no redraw.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
buckets: StatsBucket[];
|
|
11
|
+
bucketMs: number;
|
|
12
|
+
pending?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { StatsBucket } from '../../../shared/schema/stats.js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared internals for the CP8 d3 charts: geometry, formatters, the tooltip DOM,
|
|
4
|
+
* and the pointer/keyboard bucket-hit wiring. Not a component and not auto-imported;
|
|
5
|
+
* the chart .client.vue files import it relatively. All colors come from CSS custom
|
|
6
|
+
* properties (set in main.css / @nuxt/ui), so light/dark swaps without a redraw.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CHART_MARGIN: {
|
|
9
|
+
top: number;
|
|
10
|
+
right: number;
|
|
11
|
+
bottom: number;
|
|
12
|
+
left: number;
|
|
13
|
+
};
|
|
14
|
+
export declare const CHART_HEIGHT = 240;
|
|
15
|
+
export declare function formatCount(n: number): string;
|
|
16
|
+
export declare function formatPct(n: number): string;
|
|
17
|
+
/** Tooltip/table time label sized to the bucket: seconds for 15s buckets, date + time past a day-long window. */
|
|
18
|
+
export declare function bucketTimeFormatter(bucketMs: number, windowMs: number): (t: number) => string;
|
|
19
|
+
/** SVG path for a bar with rounded top corners and a square baseline. */
|
|
20
|
+
export declare function roundedTopRect(x: number, y: number, w: number, h: number, r: number): string;
|
|
21
|
+
export interface TooltipRow {
|
|
22
|
+
label: string;
|
|
23
|
+
value: string;
|
|
24
|
+
/** CSS color for the series key stroke; omit for un-keyed rows like totals */
|
|
25
|
+
color?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ChartTooltip {
|
|
28
|
+
/** cx is plot-relative px; the tooltip clamps itself inside the host */
|
|
29
|
+
show: (cx: number, title: string, rows: TooltipRow[]) => void;
|
|
30
|
+
hide: () => void;
|
|
31
|
+
destroy: () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One absolutely-positioned tooltip per chart, built with textContent only —
|
|
35
|
+
* series/service names are untrusted data and never go through innerHTML.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTooltip(host: HTMLElement): ChartTooltip;
|
|
38
|
+
export interface BucketHitState {
|
|
39
|
+
buckets: StatsBucket[];
|
|
40
|
+
bucketMs: number;
|
|
41
|
+
/** current x scale, updated by each draw */
|
|
42
|
+
xFor: (t: number) => number;
|
|
43
|
+
plotWidth: number;
|
|
44
|
+
}
|
|
45
|
+
export interface BucketInteraction {
|
|
46
|
+
destroy: () => void;
|
|
47
|
+
clear: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Pointer + keyboard bucket selection over an svg. The whole plot is the hit target
|
|
51
|
+
* (the crosshair finds the X); ArrowLeft/Right walk buckets on keyboard focus so the
|
|
52
|
+
* tooltip is reachable without a pointer. `state` is read live, so redraws only need
|
|
53
|
+
* to update it, never re-wire listeners.
|
|
54
|
+
*/
|
|
55
|
+
export declare function attachBucketInteraction(svg: SVGSVGElement, state: BucketHitState, onHit: (bucket: StatsBucket, index: number, cx: number) => void, onClear: () => void): BucketInteraction;
|
|
56
|
+
/**
|
|
57
|
+
* Stable per-entity categorical slot assignment: slug-alphabetical over the visible
|
|
58
|
+
* set, so a service keeps its hue when the legend's volume order shifts between
|
|
59
|
+
* periods. 'other' always wears the muted fill, never a categorical slot.
|
|
60
|
+
*/
|
|
61
|
+
export declare function seriesColorMap(ids: Array<{
|
|
62
|
+
id: string;
|
|
63
|
+
slug: string;
|
|
64
|
+
}>): Map<string, string>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
export const CHART_MARGIN = { top: 12, right: 16, bottom: 36, left: 44 };
|
|
2
|
+
export const CHART_HEIGHT = 240;
|
|
3
|
+
const compact = new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 1 });
|
|
4
|
+
export function formatCount(n) {
|
|
5
|
+
return compact.format(n);
|
|
6
|
+
}
|
|
7
|
+
export function formatPct(n) {
|
|
8
|
+
return `${n.toFixed(1)}%`;
|
|
9
|
+
}
|
|
10
|
+
export function bucketTimeFormatter(bucketMs, windowMs) {
|
|
11
|
+
const opts = windowMs > 864e5 ? { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" } : bucketMs < 6e4 ? { hour: "2-digit", minute: "2-digit", second: "2-digit" } : { hour: "2-digit", minute: "2-digit" };
|
|
12
|
+
const fmt = new Intl.DateTimeFormat("en", opts);
|
|
13
|
+
return (t) => fmt.format(new Date(t));
|
|
14
|
+
}
|
|
15
|
+
export function roundedTopRect(x, y, w, h, r) {
|
|
16
|
+
const radius = Math.max(0, Math.min(r, w / 2, h));
|
|
17
|
+
return `M${x},${y + h}V${y + radius}Q${x},${y} ${x + radius},${y}H${x + w - radius}Q${x + w},${y} ${x + w},${y + radius}V${y + h}Z`;
|
|
18
|
+
}
|
|
19
|
+
export function createTooltip(host) {
|
|
20
|
+
const el = document.createElement("div");
|
|
21
|
+
el.className = "observe-chart-tooltip";
|
|
22
|
+
el.style.display = "none";
|
|
23
|
+
host.appendChild(el);
|
|
24
|
+
return {
|
|
25
|
+
show(cx, title, rows) {
|
|
26
|
+
el.textContent = "";
|
|
27
|
+
const heading = document.createElement("div");
|
|
28
|
+
heading.className = "observe-chart-tooltip-title";
|
|
29
|
+
heading.textContent = title;
|
|
30
|
+
el.appendChild(heading);
|
|
31
|
+
for (const row of rows) {
|
|
32
|
+
const line = document.createElement("div");
|
|
33
|
+
line.className = "observe-chart-tooltip-row";
|
|
34
|
+
if (row.color) {
|
|
35
|
+
const key = document.createElement("span");
|
|
36
|
+
key.className = "observe-chart-tooltip-key";
|
|
37
|
+
key.style.backgroundColor = row.color;
|
|
38
|
+
line.appendChild(key);
|
|
39
|
+
}
|
|
40
|
+
const value = document.createElement("span");
|
|
41
|
+
value.className = "observe-chart-tooltip-value";
|
|
42
|
+
value.textContent = row.value;
|
|
43
|
+
const label = document.createElement("span");
|
|
44
|
+
label.className = "observe-chart-tooltip-label";
|
|
45
|
+
label.textContent = row.label;
|
|
46
|
+
line.appendChild(value);
|
|
47
|
+
line.appendChild(label);
|
|
48
|
+
el.appendChild(line);
|
|
49
|
+
}
|
|
50
|
+
el.style.display = "block";
|
|
51
|
+
const hostW = host.clientWidth;
|
|
52
|
+
const w = el.offsetWidth;
|
|
53
|
+
const left = Math.max(4, Math.min(cx + CHART_MARGIN.left + 12, hostW - w - 4));
|
|
54
|
+
el.style.left = `${left}px`;
|
|
55
|
+
el.style.top = "8px";
|
|
56
|
+
},
|
|
57
|
+
hide() {
|
|
58
|
+
el.style.display = "none";
|
|
59
|
+
},
|
|
60
|
+
destroy() {
|
|
61
|
+
el.remove();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function attachBucketInteraction(svg, state, onHit, onClear) {
|
|
66
|
+
let index = -1;
|
|
67
|
+
const centerOf = (i) => {
|
|
68
|
+
const bucket = state.buckets[i];
|
|
69
|
+
return state.xFor(bucket.t + state.bucketMs / 2);
|
|
70
|
+
};
|
|
71
|
+
const hitAt = (i) => {
|
|
72
|
+
if (i < 0 || i >= state.buckets.length) return;
|
|
73
|
+
index = i;
|
|
74
|
+
onHit(state.buckets[i], i, centerOf(i));
|
|
75
|
+
};
|
|
76
|
+
const clear = () => {
|
|
77
|
+
index = -1;
|
|
78
|
+
onClear();
|
|
79
|
+
};
|
|
80
|
+
const onPointerMove = (e) => {
|
|
81
|
+
if (!state.buckets.length) return;
|
|
82
|
+
const rect = svg.getBoundingClientRect();
|
|
83
|
+
const px = e.clientX - rect.left - CHART_MARGIN.left;
|
|
84
|
+
const first = state.buckets[0].t;
|
|
85
|
+
const i = Math.round((pxToTime(px) - first - state.bucketMs / 2) / state.bucketMs);
|
|
86
|
+
hitAt(Math.max(0, Math.min(state.buckets.length - 1, i)));
|
|
87
|
+
};
|
|
88
|
+
const pxToTime = (px) => {
|
|
89
|
+
const first = state.buckets[0].t;
|
|
90
|
+
const last = state.buckets[state.buckets.length - 1].t + state.bucketMs;
|
|
91
|
+
return first + px / Math.max(1, state.plotWidth) * (last - first);
|
|
92
|
+
};
|
|
93
|
+
const onKeyDown = (e) => {
|
|
94
|
+
if (!state.buckets.length) return;
|
|
95
|
+
const lastIndex = state.buckets.length - 1;
|
|
96
|
+
let next;
|
|
97
|
+
if (e.key === "ArrowLeft") next = index < 0 ? lastIndex : Math.max(0, index - 1);
|
|
98
|
+
else if (e.key === "ArrowRight") next = index < 0 ? lastIndex : Math.min(lastIndex, index + 1);
|
|
99
|
+
else if (e.key === "Home") next = 0;
|
|
100
|
+
else if (e.key === "End") next = lastIndex;
|
|
101
|
+
else if (e.key === "Escape") {
|
|
102
|
+
clear();
|
|
103
|
+
return;
|
|
104
|
+
} else return;
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
hitAt(next);
|
|
107
|
+
};
|
|
108
|
+
const onFocus = () => {
|
|
109
|
+
if (state.buckets.length && index < 0) hitAt(state.buckets.length - 1);
|
|
110
|
+
};
|
|
111
|
+
svg.addEventListener("pointermove", onPointerMove);
|
|
112
|
+
svg.addEventListener("pointerleave", clear);
|
|
113
|
+
svg.addEventListener("keydown", onKeyDown);
|
|
114
|
+
svg.addEventListener("focus", onFocus);
|
|
115
|
+
svg.addEventListener("blur", clear);
|
|
116
|
+
return {
|
|
117
|
+
clear,
|
|
118
|
+
destroy() {
|
|
119
|
+
svg.removeEventListener("pointermove", onPointerMove);
|
|
120
|
+
svg.removeEventListener("pointerleave", clear);
|
|
121
|
+
svg.removeEventListener("keydown", onKeyDown);
|
|
122
|
+
svg.removeEventListener("focus", onFocus);
|
|
123
|
+
svg.removeEventListener("blur", clear);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export function seriesColorMap(ids) {
|
|
128
|
+
const map = /* @__PURE__ */ new Map();
|
|
129
|
+
const real = ids.filter((s) => s.id !== "other");
|
|
130
|
+
const bySlug = [...real].sort((a, b) => a.slug.localeCompare(b.slug));
|
|
131
|
+
bySlug.forEach((s, i) => {
|
|
132
|
+
map.set(s.id, `var(--observe-viz-${i % 8 + 1})`);
|
|
133
|
+
});
|
|
134
|
+
map.set("other", "var(--observe-viz-muted)");
|
|
135
|
+
return map;
|
|
136
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** List + mint/rotate/revoke for one service's ingest keys. Read-only unless canManage. */
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
serviceId: string;
|
|
4
|
+
canManage: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
7
|
+
declare const _default: typeof __VLS_export;
|
|
8
|
+
export default _default;
|