Fixes the bug where project context fields wouldn't have their legal
values picked up when assigning them. The issue was that this context
call wasn't correctly set to be project specific.
Allows you to use project-scoped context fields in strategy edits and in
project segments.
To do so, introduces a new hook that combines global and project level
segments (using the existing api paths).
Adding project context fields to the project segments works both from
the project settings menu, and from the global segments menu. Step 1 of
the segment creation form allows you to pick a project for the segment.
If this is set, then we use that to fetch the correct context fields.
There isn't anything that'll stop you from moving a project segment to
the global level, though. But that's an edge case we can handle later.
Global segment form:
<img width="1145" height="707" alt="image"
src="https://github.com/user-attachments/assets/a187b5be-522d-4daf-bfb3-7c3c2c6a8cab"
/>
<img width="1145" height="707" alt="image"
src="https://github.com/user-attachments/assets/a23f0643-8f6f-4843-9077-73bbad63d845"
/>
Strategy edit:
<img width="1257" height="364" alt="image"
src="https://github.com/user-attachments/assets/4d747149-656f-4746-881c-1ce876079eff"
/>
## Why update segments?
I realized that the 'editable constraints list' component is used in two
places: the strategy edit form, and the second step of the segment form.
So we got that for free, just had to pass the right project along to get
the segment in the overview.
## Discussion point
With the new hook for combined, I'd have loved to go back and remove the
project Id and url update check in useUnleashContext (because we only
use it with project ids in two places). However, it serves a use case
that isn't covered by the new hook: it returns *only* project or *only*
global context fields. We could probably change the wrapper somehow to
only pass in the correct context fields, though. I'll explore that in a
follow-up.
----
Additionally, there's no way to select project-specific context fields
in the playground yet. I've added a task for it.
## About the changes
The purpose of the changes are to increase consistency and readability in the UI. The changes are mainly related to the styling of typographic elements.
##Details:
- Update theme typography: add fontWeightRegular, set medium weight to 500, update headers to fontWeight 700
- Standardize font sizes: apply body2 variant to navigation links, buttons, tabs, and sidebar
- Enhance visual hierarchy: make selected navigation items, current breadcrumb page, and page headers bold
- Update component styling:
* Navigation: bold selected menu items, medium weight for links
* Buttons: body2 font size, bold font weight
* Tables: medium weight headers (bold when sorted), bold feature flag names
* Tabs: body2 font size, bold environment names
* Projects page: bold titles, project names, and card titles
* UserProfile: reduce avatar size, update spacing, use body2 with medium weight
- Replace deprecated fontSizes with typography.fontSize throughout
- Update Google Fonts Sen import to include weight 500
Adds a new `createFetcher` function that's exposed from `useApiGetter`.
Much like in https://github.com/Unleash/unleash/pull/6541, I'm tired of having to manually redeclare the fetcher in each and every fetching hook, especially when it's always the exact same. As such, I'd like to create a shared standard.
... But that didn't work the last time. Presumably because existing uses weren't updated. I'd suggest that if we do this, then we should update all existing hooks so that the next time someone copies an existing fetch hook, they get the new fetcher instead of the old one.
Additionally, this `createFetcher` function has two improvements on the existing `fetcher` function:
1. It takes the path and errorTarget as part of an object instead of positional parameters. Because both params are of type string, it's possible to mix up the order, so I think it makes sense to enforce the object here.
2. Returns a function that returns the fetcher instead of returning the fetcher directly. All the places in the code where we use the `fetcher` function, we use it as `() => fetcher(args)`. If it's always gonna be a function, why don't we just do that directly?
The token rate-limit logs at info level generate a lot of data that is
not particularly useful during normal operations.
We decided to keep the log level at info, but reduce the amount to 10%
---------
Co-authored-by: Gastón Fournier <gaston@getunleash.io>
Reverts #11156 which was itself a revert of #11153 and then applies a
fix to two breakages
- one in the strategy configuration overview
- one in the context list
## Strategy edit context bug:
Fixed in ef6f6542bc
No context options were available in the strategy edit modal:
<img width="854" height="904" alt="image"
src="https://github.com/user-attachments/assets/6c8be391-294d-4b31-85ce-492db53c1b76"
/>
The fix itself was removing a double call to `formatApiPath`, which
would double up the base path if it's not an empty string, e.g.
`/sandbox/sandbox/api[...]` instead of `/sandbox/api[...]`.
When the base path was doubled up, Unleash would attempt to return the
base app (HTML) which obviously can't be parsed into anything useful.
## Context list bug
Fixed in c410daf183
Edit links would point to `context/edit/undefined` and editing via the
pen also caused some weird issues.
The main cause was that the `name` variable was shadowed and I didn't
realize. So when the edit string was created, it wouldn't be the context
field's name, but instead the name of the context field to delete (for
which there is a weird, stateful solution -- I remember there was a bug
that we fixed with it).
This has been fixed by moving the edit url variable declaration further
down, such that the `name` variable is in scope. additionally, I've
renamed the generic `[name, setName]` variables to
`[contextFieldToDelete, setContextFieldToDelete]` to avoid shadowing and
to make it clearer what the name is being set for.
## Scenarios tested
Against sandbox instance with a base path (using a viewer user with
project update and context field crud permissions):
Flag off:
- [x] Create / edit / delete context field in global menu
- [x] Context fields with projects (as created with the flag on) are
show in global list when flag is off
- [x] Context fields with projects can be edited in the global list (but
are still project-based if the flag goes back on)
- [x] Context fields with projects can be deleted in the global list.
- [x] Select and edit context fields on a strategy
Flag on:
- [x] Create / edit / delete context field in global menu
- [x] Create / edit / delete context field in project menu
- [x] Context fields with projects are not shown in global menu
- [x] Context fields not belonging to "this" project are not shown in
project-scoped menu
- [x] Select and edit (global) context fields on a strategy
## Known limitations:
Using project-scoped context fields for strategies is not yet supported.
Only renders the "ContextFieldUsage" component in the context form when
the form is in edit mode. It doesn't make sense to render it for context
fields that don't exist yet.
Rendering this in the create form caused the Unleash to send a request
to `/api/admin/context/:contextName/strategies` every time the name of
the context field changes (i.e. every key stroke).
Update the context field hooks to accept a project ID and to change
their API endpoints and cache keys based on the project ID.
Updating the URL in this many places (API example, multiple hooks, form
actions) feels kinda brittle and I wish there was a better way to do
this, but I don't have any bright ideas right at this moment. We could,
of course, extract a function that creates it, but that's also brittle
because they're all a little different 🤔
Implements the minimum number of changes in the back end to make the get
operations work separately for project / global context.
Avoids going to the store for now, instead doing filtering in the
service.
---------
Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
Removes the project payload from the context field schema. This optional
property would only have been returned in the get endpoints (and only if
there was a project tied to a context field).
Exposes the optional `project` property on the context field schema,
allowing the new feature to work e2e when the field is set (currently
only possible by manual db manipulation)
<img width="1532" height="558" alt="image"
src="https://github.com/user-attachments/assets/370757a2-01d3-43d1-9178-8b6e4215cee7"
/>
---------
Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
Adds a splash overlay that we can to App.tsx, it will look for active
splash ids defined in splash.tsx and append a query parameter that will
trigger the modal content. Once a splash is triggered it will be marked
as seen in the backend. This PR only adds the functionality, it does not
add it to the application just yet.
Setup the intial splash screen in the current framework. For now we are
only adding the component on a path you can navigate to, there are
currently no triggers set up.
Allows you to create, edit, and delete project context fields from the
project context field page.
Follows the same way of doing dynamic routing on the buttons as we did
for segments (checking if projectId exists, and if so, route there).
The current impl blindly inserts project if the edit/create form is open
under a project path, but we probably want to parameterize this later
(or before merging), so as to make it easier to control.