Add new methods to the store behind data usage metrics that accept date
ranges instead of a single month. The old data collection methods
re-route to the new ones instead, so the new methods are tested
implicitly.
Also deprecates the new endpoint that's not in use anywhere except in an
unused service method in Enterprise yet.
## Discussion point:
Accepts from and to params as dates for type safety. You can send unparseable strings, but if you send a date object, you know it'll work.
Leaves the use of the old method in `src/lib/features/instance-stats/instance-stats-service.ts` to keep changes small.
We are changing how the Delta API works, as discussed:
1. We have removed the `updated` and `removed` arrays and now keep
everything in the `events` array.
2. We decided to keep the hydration cache separate from the events array
internally. Since the hydration cache has a special structure and may
contain not just one feature but potentially 1,000 features, it behaved
differently, requiring a lot of special logic to handle it.
3. Implemented `nameprefix` filtering, which we were missing before.
Things still to implement:
1. Segment hydration and updates to it.
Add support for querying the traffic data usage store for the aggregated data for an arbitrary number of months back.
Adds a new `getTrafficDataForMonthRange(monthsBack: number)` method to the store that aggregates data on a monthly basis by status code and traffic group. Returns a new type with month data instead of day data.
This PR implements a first version of the new month/range picker for the
data usage graphs. It's minimally hooked up to the existing
functionality to not take anything away.
This primary purpose of this PR is to get the design and interaction out
on sandbox so that UX can have a look and we can make adjustments.
As such, there are a few things in the code that we'll want to clean up
before removing the flag later:
- for faster iteration, I've used a lot of CSS nesting and element
selectors. this isn't usually how we do it here, so we'll probably want
to extract into styled components later
- there is a temporary override of the value in the period selector so
that you can select ranges. It won't affect the chart state, but it
affects the selector state. Again, this lets you see how it acts and
works.
- I've added a `NewHeader` component because the existing setup smushed
the selector (it's a MUI grid setup, which isn't very flexible). I don't
know what we want to do with this in the end, but the existing chart
*does* have some problems when you resize your window, at least
(although this is likely due to the chart, and can be solved in the same
way that we did for the personal dashboards).
![image](https://github.com/user-attachments/assets/f3ce3ff9-bab3-4d00-afbe-56f5624fbe16)
Currently, every time you archived feature, it created
feature-dependencies-removed event.
This PR adds a check to only create events for those features that have
dependency.
We got an event for a scheduled application success today that looked a
little something like this:
> Successfully applied the scheduled change request #1168 in the
production environment in project eg by gaston in project eg.
Notice that we're stating the project twice (once with a link (removed
here) and once without).
This PR removes the redundancy in CR events:
The project is already included in the `changeRequest` variable, which
is populated in `src/lib/addons/feature-event-formatter-md.ts` by
the `generateChangeRequestLink` function.
The (current) definition is:
```typescript
generateChangeRequestLink(event: IEvent): string | undefined {
const { preData, data, project, environment } = event;
const changeRequestId =
data?.changeRequestId || preData?.changeRequestId;
if (project && changeRequestId) {
const url = `${this.unleashUrl}/projects/${project}/change-requests/${changeRequestId}`;
const text = `#${changeRequestId}`;
const featureLink = this.generateFeatureLink(event);
const featureText = featureLink
? ` for feature flag ${this.bold(featureLink)}`
: '';
const environmentText = environment
? ` in the ${this.bold(environment)} environment`
: '';
const projectLink = this.generateProjectLink(event);
const projectText = project
? ` in project ${this.bold(projectLink)}`
: '';
if (this.linkStyle === LinkStyle.SLACK) {
return `${this.bold(`<${url}|${text}>`)}${featureText}${environmentText}${projectText}`;
} else {
return `${this.bold(`[${text}](${url})`)}${featureText}${environmentText}${projectText}`;
}
}
}
```
Which includes links, env, and project info already.
Weird thing is that I could not reproduce it locally, but I have a
theory to fix our delta mismatch.
Revisions are added to the delta every second.
This means that in a single revision, you can disable an event, remove a
dependency, and archive it simultaneously. These actions are usually
performed together since archiving an event will inherently disable it,
remove its dependencies, and so on.
Currently, we observe these events happening within the same revision.
However, since we were checking `.updated` last, the event was always
removed from the `removedMap`.
Now, by checking `.removed` last, the archive action will properly
propagate to the revision.
Our delta API was returning archived feature as updated. Now making sure
we do not put `archived-feature `event into `updated` event array.
Also stop returning removed as complex object.