Skip to content

Add predefined saved views#2252

Open
ejsmith wants to merge 1 commit into
mainfrom
predefined-saved-views
Open

Add predefined saved views#2252
ejsmith wants to merge 1 commit into
mainfrom
predefined-saved-views

Conversation

@ejsmith
Copy link
Copy Markdown
Member

@ejsmith ejsmith commented May 24, 2026

Adds predefined saved views that can be seeded globally, synced into organizations, and managed from the next UI.

Summary:

  • Add data seeding for global predefined saved views, including hidden filter metadata in the seed JSON.
  • Add saved view API endpoints for syncing organization predefined saved views and managing global predefined saved views.
  • Add next UI actions to update/view predefined saved views and global admin picker actions to save/delete predefined definitions.
  • Update OpenAPI baseline, HTTP samples, and controller coverage for the new API surface.

Validation:

  • npm run check
  • dotnet test --artifacts-path artifacts/copilot-dotnet-test -- --filter-class Exceptionless.Tests.Controllers.SavedViewControllerTests

Assert.Equal("events", logs.ViewType);
Assert.Equal("type:log", logs.Filter);
Assert.NotNull(logs.FilterDefinitions);
Assert.Equal(JsonValueKind.Array, logs.FilterDefinitions.Value.ValueKind);
Assert.Equal("type:log level:warn", logsDefinition.Filter);
Assert.NotNull(logsDefinition.FilterDefinitions);

var filterDefinitions = logsDefinition.FilterDefinitions.Value;

private static string GetSeedFilePath()
{
return Path.Combine(AppContext.BaseDirectory, "Seed", SeedFileName);
@github-actions
Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Web 72% 61% 3899
Exceptionless.AppHost 18% 9% 82
Exceptionless.Insulation 25% 23% 203
Exceptionless.Core 69% 62% 7766
Summary 68% (13345 / 19738) 61% (7020 / 11494) 11950

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for predefined saved views that can be seeded globally, synced into organizations, and administered via new API endpoints and next UI affordances. This fits into the Saved Views feature area by introducing a “global definition → organization instances” synchronization flow, plus admin tooling to export/manage definitions.

Changes:

  • Add data seeding infrastructure and a bundled predefined-saved-views.json seed file for global predefined saved views.
  • Add SavedView API endpoints to (a) sync predefined views into an organization and (b) export/promote/delete global predefined definitions.
  • Update the next UI to trigger/surface predefined-view flows (system admin actions, org features page, saved view picker admin actions) and refresh behavior around first-event onboarding.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/http/saved-views.http Adds HTTP samples for new predefined saved view endpoints.
tests/Exceptionless.Tests/Controllers/SavedViewControllerTests.cs Adds integration test coverage for seeding, global export, org sync, promote/delete predefined.
tests/Exceptionless.Tests/Controllers/Data/openapi.json Updates OpenAPI baseline for the new predefined saved view API surface and schema.
src/Exceptionless.Web/Controllers/SavedViewController.cs Implements org sync endpoint, global predefined endpoints, and “ensure created” behavior on reads.
src/Exceptionless.Web/ClientApp/src/routes/(auth)/signup/+page.svelte Adjusts signup redirect behavior based on invite token; refactors markup wrapper.
src/Exceptionless.Web/ClientApp/src/routes/(app)/system/actions/[[category]]/+page.svelte Adds a system action to view/export predefined saved views JSON with a dialog + copy.
src/Exceptionless.Web/ClientApp/src/routes/(app)/project/add/+page.svelte Improves org selection initialization and adjusts copy/CTA; syncs organization_id via effect.
src/Exceptionless.Web/ClientApp/src/routes/(app)/project/[projectId]/routes.svelte.ts Tweaks project nav items/titles and removes “Configure Client” from settings nav.
src/Exceptionless.Web/ClientApp/src/routes/(app)/project/[projectId]/manage/+page.svelte Adds “Configure Project” and “Generate Sample Data” actions; refactors destructive actions UI.
src/Exceptionless.Web/ClientApp/src/routes/(app)/project/[projectId]/configure/+page.svelte Improves first-event onboarding by redirecting to events when a relevant event arrives; adds “View Events”.
src/Exceptionless.Web/ClientApp/src/routes/(app)/project/[projectId]/+layout.svelte Hides project settings nav when on configure flow; adjusts header label.
src/Exceptionless.Web/ClientApp/src/routes/(app)/organization/add/+page.svelte Reworks setup flow to create organization + project and then redirect to client configuration.
src/Exceptionless.Web/ClientApp/src/routes/(app)/organization/[organizationId]/features/+page.svelte Adds “Update Predefined Saved Views” action and reorganizes feature management UI.
src/Exceptionless.Web/ClientApp/src/routes/(app)/events/+page.svelte Debounced refresh behavior for websocket event updates + an empty-grid refresh guard tied to stats.
src/Exceptionless.Web/ClientApp/src/routes/(app)/+layout.svelte Adds a setup-specific shell layout for the organization/project setup page.
src/Exceptionless.Web/ClientApp/src/lib/features/saved-views/components/saved-view-picker.svelte Adds global-admin actions to promote/demote predefined saved views from the picker.
src/Exceptionless.Web/ClientApp/src/lib/features/saved-views/api.svelte.ts Adds mutations for syncing org predefined views and promoting/deleting global predefined definitions.
src/Exceptionless.Web/ClientApp/src/lib/features/organizations/components/organization-notifications.svelte Refetches org/project configuration state after first-event websocket notifications.
src/Exceptionless.Web/ClientApp/src/lib/features/admin/models.ts Adds types and a maintenance action kind/entry for predefined saved view export.
src/Exceptionless.Web/ClientApp/src/lib/features/admin/api.svelte.ts Adds mutation to fetch and JSON-stringify predefined saved view definitions.
src/Exceptionless.Core/Seed/PredefinedSavedViewsDataSeed.cs Implements global predefined saved views seed using bundled JSON file + distributed lock.
src/Exceptionless.Core/Seed/predefined-saved-views.json Adds the default predefined saved view definitions (filters + hidden filter metadata).
src/Exceptionless.Core/Seed/IDataSeed.cs Introduces a seed contract for startup data seeding.
src/Exceptionless.Core/Seed/DataSeedService.cs Adds a startup action to run all registered IDataSeed implementations.
src/Exceptionless.Core/Models/SavedView.cs Adds PredefinedKey for stable cross-organization predefined view identity.
src/Exceptionless.Core/Exceptionless.Core.csproj Ensures the predefined saved view seed JSON is copied to output/publish.
src/Exceptionless.Core/Bootstrapper.cs Registers data seed services and hooks seeding into startup actions.
src/Exceptionless.AppHost/Exceptionless.AppHost.csproj Bumps Aspire hosting package versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +701 to +706
if ((left?.Count ?? 0) != (right?.Count ?? 0))
return false;

if (left is null || right is null)
return true;

Comment on lines +432 to +452
private async Task<IReadOnlyCollection<SavedView>> UpsertPredefinedSavedViewsAsync(string organizationId, bool onlyIfNeverCreated = false)
{
List<SavedView> savedViews = [];

await _lockProvider.TryUsingAsync($"predefined-saved-views:{organizationId}", async () =>
{
var organization = await _organizationRepository.GetByIdAsync(organizationId);
if (organization is null)
return;

if (onlyIfNeverCreated && HasCreatedPredefinedSavedViews(organization))
return;

savedViews = await UpsertPredefinedSavedViewsForOrganizationAsync(organizationId);
organization.Data ??= new DataDictionary();
organization.Data[PredefinedSavedViewsDataKey] = PredefinedSavedViewsVersion.ToString();
await _organizationRepository.SaveAsync(organization, o => o.Cache().ImmediateConsistency());
}, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(15));

return savedViews;
}

private static bool HasCreatedPredefinedSavedViews(Organization organization)
{
return organization.Data is not null && organization.Data.ContainsKey(PredefinedSavedViewsDataKey);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants