Adds event creator data to the event creator filter.
It uses a new useEventCreators hook to fetch event creators from the new
API, and uses that to populate the event creators filter.
There's a bug where the UI will fetch all features every time you load a
project screen (including every time you filter the project results).
The reason is that the create flag dialog was rendered (just not open)
every time. To solve it, we instead wrap it in an extra component that
prevents all the fetching and setup from running when the dialog isn't
open.
Additionally, we'll lower the page size for the global fetch limit to 1,
so that we send less data.
`groupId` parameter because of the change in validation wasn't parsed
correctly. Intent was to fill it when it is empty, when the form is loaded.
By mistake the same logic applies when you manually remove all
characters from the text field.
Adds sticky pagination to the event log:
![image](https://github.com/user-attachments/assets/c426f30d-bb64-44a5-b3b4-8c295207b249)
This PR uses the sticky pagination bar that we use on other tables to
navigate the event search results.
## Decisions / discussion points
The trickiest issue here is how we calculate the next and previous page
offsets. This is tricky because we don't expose the page number to the
API, but the raw offset itself. This abstraction makes it possible to
set an offset that isn't a multiple of the page size.
Say the page size is 25. If you manually set an offset of 30 (through
changing the URL), what do you expect should happen when you:
- load the page? Should you see results 31 to 55? 26 to 50?
- go to the next page? Should your next offset be 55 or 50?
- previous page: should your previous page offset be 5? 25? 0?
The current implementation has taken what I thought would be the easiest
way out: If your offset is between two multiples of the page size, we'll
consider it to be the lower of the two.
- The next page's offset is the next multiple of the page size that is
higher than the current offset (50 in the example above).
- The previous page's offset will be not the nearest lower page size,
but the one below. So if you set offset 35 and page size 25, your next
page will take you back to 0 (as if the offset was 25).
We could instead update the API to accept `page` instead of offset, but
that wouldn't align with how other tables do it.
Comparing to the global flags table, if you set an offset that isn't a
multiple of the page size, we force the offset to 0. We can look at
handling it like that in a follow-up, though I'd argue that forcing it
to be the next lower multiple of the page size would make more sense.
One issue that appears when you can set custom offsets is that the
little "showing x-y items out of z" gets out of whack (because it only
operates on multiples of the page size (seemingly))
![image](https://github.com/user-attachments/assets/ec9df89c-2717-45d9-97dd-5c4e8ebc24cc)
## The Event Log as a table
While we haven't used the HTML `table` element to render the event log,
I would argue that it _is_ actually a table. It displays tabular data.
Each card (row) has an id, a project, etc.
The current implementation forces the event log search to act as a table
state manager, but we could transform the event list into an events
table to better align the pagination handling. The best part? We can
keep the exact same design too. A table doesn't have to _look_ like a
table to be a table.
Fixes a bug where the `handleSelection` function would select the
wrong item under certain conditions.
Because we always sent the unfiltered list of options to the function,
but took the index of the filtered items, the index would be off when
you have filtered the list and items before the selected items were
hidden.
This addresses that and also ports in some improvements I made when
setting up the config buttons for the new dialogs:
1. You can now use the space bar to select items that you have
focused (this is consistent with regular form interactions for
checkboxes)
2. When you have added text to the search field, pressing Enter will
select the top-most item (this is consistent with how these fields
work in linear, for instance) as long as your focus is still in the
search field. If you have moved it to the list, enter will still
select an item on that list as expected.
Potential other addition: if you press "Enter" with an empty search
field, we could close the box but keep your selection the same. Again,
this is how Linear does it, but I don't personally know what I'd
expect to happen there, so I'm happy to leave it as is.
Fixes a bug in the navigation when you create a project. It used to be
that we'd replace the current entry in the browser history when we
took you to a separate form for it. However, now that we instead
use a dialog, we don't want to replace the history.
Before: if you created a project and navigated back, you'd be taken to
the page you were at BEFORE you went to the projects page, whether
that was in Unleash or otherwise.
Now you'll be taken back to the projects page.
Hooks up the new Event search and filtering capabilities to the new
Event Log component. In doing so, it also splits the existing EventLog
component into two: `LegacyEventLog` and `NewEventLog`. The naming is
probably temporary, as the old EventLog isn't really legacy yet. But we
can rename them later.
The other half of #7768 .
This is just the state management part of #7768.
Adds a useEventLogSearch hook.
All the filters work except for the date filters. They don't work
because the query parameters in the API don't match what's here, but an
update to the API is coming in a follow-up.
It's a little tricky to handle this because the three different event
logs should have slightly different filters, which makes making the type
checker happy a bit of a pain. However, I'd like to revisit this in a
follow-up PR.
Adding a link "Read more in [release
notes](https://github.com/Unleash/unleash/releases/tag/v6.1.0)" to
orphaned tokens.
This needs to be added on v6.1, with the following changelog entry:
> **SDK tokens for deleted projects**
>
> In previous versions of Unleash, when a project was deleted, the
associated SDK tokens were not removed. This issue has been addressed in
the current version of Unleash.
>
> Unfortunately, if you deleted a project in the past without manually
removing the associated tokens, these "orphaned" tokens were
automatically converted to “wildcard” tokens, granting access to all
feature flags across all projects.
>
> Our assessment indicates this poses a minor security concern due to
the following reasons:
>
> This issue only affects tokens whose entire project scope has been
deleted.
>
> Access requires knowledge of the token.
>
> SDK tokens have limited read access and must be assigned to a single
environment.
>
> In the SDK tokens overview, orphaned tokens are flagged with a
warning. We recommend discontinuing the use of these tokens and creating
new, dedicated tokens instead.
>
> With the latest version, when a project is deleted, all API tokens
scoped to that project will be removed as well. If you need further
assistance, please contact customer support.
Creates a new useEventSearch hook based on the useFeatureSearch hook.
Moves the old useEventSearch hook into useLegacyEventSearch and updates
references to it.
I don't know yet whether this'll work entirely as expected, but I plan
on making any necessary configurations when I implement the state
management in a follow-up PR.
But because this is pretty much a straight copy-paste from
useFeatureSearch (only adjusting types, I think), I also think it might
be possible to turn this into a generic search template. Not sure if now
is the time, but worth thinking about, I think.
This change primarily adds all flags to the flag filter and restructures
the filters component. Instead of splitting into three smaller
components, we now handle more data in the main component.
We might wanna turn them back to smaller components later, but I think
this'll be easier to work with.
Fixes an issue where the collaborator component would be smooshed
together when you have too many collaborators and too many flag tab
items.
The primary things I have done are:
1. Limit the amount of collaborators we show to 6 instead of 8. I
believe the number 8 was arbitrary, so let's go with 6 for now.
2. Instead of using a fixed gap, use a separator element that grows up
to a certain limit. I've added a `Separator` component, which is an
empty div with flex-grow. It feels like you should be able to do that
with gap too, but I can't think of how right now.
3. Don't allow collaborator component text (or avatars) to wrap. We
don't have a lot of space in this header, so let's keep it tight.
Additionally, I've added the `className` prop to the AvatarGroup
component so that it can be styled externally. I also cleaned up some
naming that was left in while I was at it.
Before:
![image](https://github.com/user-attachments/assets/98525a23-c086-433a-8f60-3e281805409f)
After:
![image](https://github.com/user-attachments/assets/559f8975-9cbe-4260-ba5a-409a303375ed)
Fixes a bug introduced with the new tooltips where the system user was
shown as "User ID n" instead of "System". The "n" in this case is
actually the user's index number in the list of project owners
(including duplicates).
There's a few things happening:
1. Change the object for system owners: use `name` instead of
`description`. At the same time, remove the `description` property
completely because it's not used at the moment.
2. Remove the assignnment of `id: objectId(user)` to the user sent to
the User Avatar component. This was a leftover from when we split out
the AvatarGroup component, and is not something we use anymore.
Before:
![image](https://github.com/user-attachments/assets/bd348daf-c81e-4ea9-b8a9-f10af71a0da7)
After:
![image](https://github.com/user-attachments/assets/d147f7c7-d683-43ac-9ee2-6116f155dad6)
This PR makes some small changes to how we handle strategy deletion in
the demo environment, which has become extra important with the recent
soft limits.
The changes are:
- lower the strategy limit from 30 to 25. The standard limit is 30, so
we want to make sure we're below that.
- when checking whether we should delete a strategy, check whether we're
**at or above** the limit. It used to only check if we were above, but
if soft limits would prevent you from adding more, then you'd never be
able to go above the limit.
- Also delete strategies for step3.
Old versions of Unleash allow for creating "Gradual Rollout" strategies
without `groupId` or `stickiness`. UI will now populate those fields,
not getting stuck when editing strategies without said fields.
Fixes an issue where the filter buttons were both too far down and too
far to the right.
The issue was that the wrapper body imposed a pretty substantial bit
of padding. However, the filter buttons already came with their own
bit of padding. The result of this was alignment issues.
To fix it I have:
- opened the `Filters` component up to be styled with styled components
And conditionally (when isEnterprise and the flag is on):
- set the page body to have no padding.
- added a wrapper with padding around the event search results for
This feels a little messy to me, but I also think that because it's
still in heavy development, it might change later. I'd be happy to have
suggestions forbetter implementations.
What makes this extra tricky is that the top padding differs depending
on whether you have the filters there or not, so I couldn't find a way
to just remove that component and be done with it. I may very well have
missed somehing, though.
Before:
![image](https://github.com/user-attachments/assets/1552d1ec-2c14-450f-9ce8-8e74389f11a1)
After:
![image](https://github.com/user-attachments/assets/d58b6fe5-437f-4488-bf01-cabfef669e2e)
Changes the type used by the useEventSearch hook to be `EventSchema`
from OpenAPI instead. This is more accurate with what we're actually
getting. And crucially for the event log search, it contains the
`createdByUserId` property that we need to filter out events.
It's mostly a straightforward find and replace except for one instance
where we need to do some extra fiddling. There's an inline comment
explaining that.
Extracts the Avatar Group component into a `common` component and adds a
standard tooltip to all avatars.
Relates to linear issue 1-2606
This is a suggestion / proof of concept for how we can solve it. While I
think we can merge this as is, I'd also be happy to take any discussions
on other ways to approach it etc.
## Why are these changes made together?
Because extracting the avatar group without adding the new tooltip data
made the existing tooltip misbehave (it'd show up in the top left of the
screen, not synced to the avatar in any way).
I probably could have (and still can if you think it's prudent) split it
out such that the avatar gets a standardized tooltip first (and disable
it for the group card avatars), and split out the avatars in a
follow-up. Happy to do that if you think it's better.
## What does this mean?
It used to be that we had no consistent way of dealing with avatars and
tooltips. Some places had them, some places didn't. This change makes it
so that all avatars that we can show tooltips for will get the same
tooltip.
Previously, we had at least 4 different ways of dealing with tooltips:
- The HTML tooltip (that would be standardized with this PR) in the
project flags table
![image](https://github.com/user-attachments/assets/91098d31-a5e3-4091-9125-332fe5d106fd)
- The "title" that you'd get on your user avatar
![image](https://github.com/user-attachments/assets/39062b61-db8c-4bd5-9fa3-3ecc9bc192ee)
- The group card list tooltip
![image](https://github.com/user-attachments/assets/0d4a696a-e944-446c-8bff-4dcec02d8afb)
- And sometimes you'd get nothing at all
![image](https://github.com/user-attachments/assets/8975afaf-9ca1-4eb6-b443-9ab94b52bbd8)
with this change, we'll always show the same kind of tooltip if we can:
![image](https://github.com/user-attachments/assets/974c592c-c844-4b65-8a55-05e84d3df130)
## What goes in the tooltip?
We use the `UserAvatar` component for a fair few different things and I
didn't want to extract separate components for all the different use
cases. Instead, I wanted to get an overview over what we use it for and
what is relevant info to show.
I found all the places we used it and tried to form an opinion.
This tooltip will work with a user's email, name, username, and id. If
there is no user (such as for empty avatars and avatars displaying only
"+n" for remaining members), we show no tooltip.
Following the example set by the group card avatars, we'll try to use
email or username (in that order) as the main bit of text. If the user
has an email or a username and also a name, the name will be used as
secondary text.
If the user does not have an email or username, but has a name, we'll
use the name as the main text.
If the user does not have an email, a username, or a name, we'll try to
show "User ID: N" if they have an id.
If they do not have a username, a name, an email, or an ID, we bail out
and show nothing.
## Why can you disable the tooltip?
In some cases, you might want to disable the tooltip because you have
more information to feed into it. An example of that is in the project
flags table, where we want to show more information in cases where the
user is 'unknown':
![image](https://github.com/user-attachments/assets/758b4e86-e934-47e3-91ce-ce900f76bc54)
## Additional fixes
This PR also adds a few lines of CSS to fix a minor avatar layout bug.
Before:
![image](https://github.com/user-attachments/assets/0150efbf-c51a-40bb-898f-7ddd3565ce21)
After:
![image](https://github.com/user-attachments/assets/f337cf68-c572-4610-b1de-a27749325da8)
Adds placeholder filter buttons (that don't work at all) yet to the
three event logs.
Flag logs get to choose to and from dates, created by, and event type.
Project logs get all that flag logs get + a filter for flag.
The global log gets all project log filters + a project filter.
There's still work to be done to add data to createdBy, eventType, to
hook it up to the API, and to finalize the layout, but I wanted to get a
rough outline in to iterate on later. The eventType icon will also need
to be decided on.
![image](https://github.com/user-attachments/assets/06a65301-9cc5-45ed-b753-2b9235d64ea6)
This PR fixes a minor visual issue where the "favorite project" button's
hover outline would get cut off due to its container having `overflow:
hidden`.
The overflow value was introduced in
[#7575](https://github.com/Unleash/unleash/pull/7575) as way to handle
long project names. We didn't discover the hover issue back then because
it's not apparent unless you hover the fav star.
I found the solution in the CSS-tricks post [Preventing a Grid
Blowout](https://css-tricks.com/preventing-a-grid-blowout/). To quote
the article, the reason this works is that:
> the minimum width of a grid column is auto. (The same is true for flex
items, by the way.)
>
> And since auto is entirely based on content, we can say it is
“indefinitely” sized, its dimensions flex. If we were to put an explicit
width on the column, like 50% or 400px, then we would say it is
“definitely” sized.
>
> To apply our fix, we need to make sure that there is the column has a
definite minimum width instead of auto.
Before:
![image](https://github.com/user-attachments/assets/d9296afd-326e-4712-a389-f1bc3a1f821e)
After:
![image](https://github.com/user-attachments/assets/2fd88a51-08be-4bc4-8969-cd6ebbaf255c)
Additionally, I've removed a duplicate declaration of font size,
removing the deprecated version.
This change fixes a bug where editors were suddenly unable to create
flags. The issue is that the new project creation dialog used a
permission button, but didn't supply the project ID.
This PR updates the text used to describe the different fields used in
the new creation dialog.
It also removes a redundant aria attribute (that MUI already handles).
This change prevents long project names from blowing the form out of
proportion.
To do so, it:
1. sets `whitespace: no-wrap` on the button labels. Judging by the other
styles, this was the intention all along, but it didn't really come up
until now.
2. It also sets the label width for projects to 30ch,so that you'll get
to see quite a bit of the project name before it gets cut off.
It would be possible to set a dynamic width for this button based on the
longest project name, but I'm not sure it adds much value, so I'm
leaning towards keeping it simple.
Here's what the dynamic width would look like:
``` tsx
const projectButtonLabelWidth = useMemo(() => {
const longestProjectName = projects.reduce(
(prev: number, type: { name: string }) =>
prev >= type.name.length ? prev : type.name.length,
0,
);
return `${Math.min(longestProjectName, 30)}ch`;
}, [projects]);
```
What it looks like:
![image](https://github.com/user-attachments/assets/51bca3f6-aeb3-4a41-b57e-5ebd9baa3ef6)
This PR makes the config dropdown list generic over its values, so that
you can pass stuff that isn't strings.
It also updates the existing impression data button to use booleans
instead.
This change makes it so that we show the name of the project that is
selected on the selection button instead of the ID. There is a chance
that the name is not unique, but I'm willing to take that risk (plus
it's how we do it today).
I've used a useMemo for this, because we have to scan through a list
to find the right project. Sure, it's always a small list (less than
500 items, I should think), but still nice to avoid doing it every
render. Happy to remove it if you think it obfuscates something.
We *could* also use a `useState` hook and initialize it with the right
value, update when it changes, but I actually think this is a better
option (requires less code and less "remember to update this when that
changes").
This change wraps the project selection option in the
CreateFeatureDialog in a conditional that hides it when Unleash is
OSS.
OSS doesn't have access to the project creation API, so there's no
point in showing this.
This fix validates the project name when you blur the field in the new
project form. The only instances where it'll be wrong is if you have
just whitespace or an empty string, but you'll be notified immediately.
Also removes some unused variables and parameters that I found.
This change makes it so that all form input labels start with a
capital letter, regardless of the data we use to generate them.
Also fixes a leftover toggle -> flag renaming.
This PR extracts the dialog form that we created for the new project
form into a shared component in the `common` folder.
Most of the code has been lifted and shifted, but there's been some
minor adjustments along the way. The main file is
`frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.tsx`.
Everything else is just cleanup.
Add ability to format format event as Markdown in generic webhooks,
similar to Datadog integration.
Closes https://github.com/Unleash/unleash/issues/7646
Co-authored-by: Nuno Góis <github@nunogois.com>
https://linear.app/unleash/issue/2-2469/keep-the-latest-event-for-each-integration-configuration
This makes it so we keep the latest event for each integration
configuration, along with the previous logic of keeping the latest 100
events of the last 2 hours.
This should be a cheap nice-to-have, since now we can always know what
the latest integration event looked like for each integration
configuration. This will tie-in nicely with the next task of making the
latest integration event state visible in the integration card.
Also improved the clarity of the auto-deletion explanation in the modal.
This PR adds the UI part of feature flag collaborators. Collaborators are hidden on windows smaller than size XL because we're not sure how to deal with them in those cases yet.
The limit card says to contact cs@getunleash if you're at the limits,
but we probably don't want to show that to OSS customers (it's not
terrible, just not very helpful), so let's hide it for OSS.
Instead, we'll ask them to try the community slack.
Screenie:
![image](https://github.com/user-attachments/assets/5a5dc292-3878-4181-98ac-f1ce4583d8a3)
This PR fixes a minor visual glitch where the initial Unleash load might
display a jumping loading icon. The reason was that the initial
redirect's loader wasn't marked as a fullscreen loader.
This PR updates the tooltips for the health chart to also include
information on how healthy flags there are. The user could make this
calculation themselves before, but it'd require them to subtract the sum
of stale and potentially stale flags from the total. This makes it so
that they don't have to do the calculation.
I've also included a bar for the healthy flags in the overview, so that
it's easier to see how large a portion it is compared to the others.
Also: clean up some uses of the now-deprecated VFC.
![image](https://github.com/user-attachments/assets/fa33b5ec-b5aa-472d-8ee3-329c5ed0d0c6)
Same as the OIDC changes we merged yesterday, this makes the frontend
ready for disabling SAML configuration page, if the SAML_ environment
variables are set.
---------
Co-authored-by: Nuno Góis <github@nunogois.com>
Previously, when the result box was loading, it returned projects and
menu items first. After the feature search response came back, it also
showed the features, but this made the component jump around too much.
Now, everything is shown when the feature result comes back, reducing
the jumping around.
This PR fixes a bug where we wouldn't update the `useFeatureSearch`
hook's cached `total` value if the new total was `0`. The reason this
failed is that we would only update it if `data?.total`. Because `0` is
a falsy value, the check would fail.
This PR adds the first version of the resource limit documentation. It
also corrects the link in the `Limit` component.
In addition to the new limits from the soft limits project, I've also
added the limits from the signals project.
## Discussion points
I've set the Pro resource limits to projects and envs to the same value
as on the [plans & pricing](https://www.getunleash.io/pricing) page
instead of the actual hard soft limit. I think that makes messaging
easier and more consistent.
However, this does present us with a bit of a problem. Because we've
been pretty consistent at saying "no, you can't have more projects" for
Pro. But we're saying it's easy to change (when in actuality the limit
isn't enforced 💁🏼 )
## Screenie
It looks a little bit like this (but check the files or preview for the
actual text content)
![image](https://github.com/Unleash/unleash/assets/17786332/56cadc00-5a8e-4820-8b11-d059112934da)
We'll store hashes for the last 5 passwords, fetch them all for the user
wanting to change their password, and make sure the password does not
verify against any of the 5 stored hashes.
Includes some password-related UI/UX improvements and refactors. Also
some fixes related to reset password rate limiting (instead of an
unhandled exception), and token expiration on error.
---------
Co-authored-by: Nuno Góis <github@nunogois.com>
This PR disables the "create feature flag" button when you've reached
the limits.
This one is a little more complex than the other UI limits, because we
also have to take into account the project feature limit. I've tried to
touch as little as possible, but I _have_ extracted the calculation of
both limits into a single hook.
This change reverts the changes related to the button in particular
that were introduced in #7500. The button is now always enabled, and
the actual resource warning and creation blocking happens in the form,
courtesy of #7548.
Currently, if the location changes, it does not update the active item.
I added useEffect to update the active item.
This is required when the user navigates via the command menu.
This PR activates the limit for API token creation in both the global
API token window and in the project-level API token tab.
Because the same button is used in two places, I encapsulated the
fetching of flags and resource limits within the button. I can be
convinced to pass the current API token count and the limit as
arguments, but I think this is the right solution for this case.
This PR updates the Unleash UI to use the new environment limit.
As it turns out, we already had an environment limit in the UI, but it
was hardcoded (luckily, its value is the same as the new default value
🥳).
In addition to the existing places this limit was used, it also disables
the "new environment" button if you've reached the limit. Because this
limit already exists, I don't think we need a flag for it. The only
change is that you can't click a button (that should be a link!) that
takes you to a page you can't do anything on.
Previously, clearing the SWR cache cleared all entries. Now you can
configure the cache size.
1. This makes the search more fluid. Previously, if you went back and
forth on pages, you were always sent to the loading state.
2. This also solves the issue where the command bar search cleared the
cache for all other searches.
3. Additionally, it addresses the problem where the global search
cleared the cache for project search.
Start tracking plausible events
1. Log the search keywords that returned 0 results
2. Track all clicks, based on source(search/recents/pages), type etc.
Now the search hook is inside another component, so we do not get
searches without search query.
Also we had 2 state variable handing the search query. Removed one of
them.
This PR removes the last two flags related to the project managament
improvements project, making the new project creation form GA.
In doing so, we can also delete the old project creation form (or at
least the page, the form is still in use in the project settings).
Fix project role assignment for users with `ADMIN` permission, even if
they don't have the Admin root role. This happens when e.g. users
inherit the `ADMIN` permission from a group root role, but are not
Admins themselves.
---------
Co-authored-by: Gastón Fournier <gaston@getunleash.io>
This change takes the rendering of the new project form component and
puts in a child component of the project list, thereby
significantly speeding up the time it takes to render the form if you
have lots of projects (about to 10x for 50 projects on my machine).
The reason it was so slow before was that the open state of the form
component was stored in the project list component. This meant that
whenever you wanted to open or close the form, you'd have to rerender
the entire project list.
This change abstracts that process into the new ProjectCreationButton
component. This component takes care of checking the feature flag for
whether to render the dialog or to send the user to the old form, and
takes care of state management for the dialog.
Because this is a child component of the project list, it does not
cause rerenders of the entire project list.
Previously since query params were changing by global search, and
menubar was also altering them, they were conflicting. Menubar does not
need query params as state. So using search hook directly.
Now searching works in command bar
1. Currently piggybacking on the search hook, but I think it is not fast
enough, and also it is using the query params as the global search. This
causes some weird behaviour in UI. This probably means we will create
separate endpoint for this.
![image](https://github.com/Unleash/unleash/assets/964450/a24f41ae-93d7-4ebe-a92b-c20dfe7cb666)
This PR disables the filtering capability in the front end for unknown
users.
Modifying the back end to support filtering for unknown users is not
something we want to do yet. It's possible, but it requires adding a lot
of special cases to the handling code (refer to [PR
#7359](https://github.com/Unleash/unleash/pull/7359)), which we'd like
to avoid if possible. To avoid annoying cases where the filtering
doesn't work as expected and breaks user expectations, we're disabling
the filtering capability for unknown users in the front end.
We can consider whether to enable back-end results for unknown in the future if we get
user feedback that it's important.
This PR works by changing the avatar cell component. When the user has
id 0 (and is therefore unknown), we:
- set aria-disabled to true. This alerts users with assistive tech that
the button is disabled, but it doesn't take it out of the tab order, so
it's not mysteriously missing.
- change the tooltip text, telling users that they can't filter by
unknown users.
- disable the avatar callback function, so clicking on the avatar
doesn't do anything.
The accompanying tests assert this functionality.
I considered also updating the screen reader text, but I think that
would add more confusion or be more information than the user needs.
According to MDN's article on the [aria-disabled
attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-disabled):
> [the aria-disabled] declaration will inform people using assistive
technologies, such as screen readers, that such elements are not meant
to be editable or otherwise operable.
**Upgrade to React v18 for Unleash v6. Here's why I think it's a good
time to do it:**
- Command Bar project: We've begun work on the command bar project, and
there's a fantastic library we want to use. However, it requires React
v18 support.
- Straightforward Upgrade: I took a look at the upgrade guide
https://react.dev/blog/2022/03/08/react-18-upgrade-guide and it seems
fairly straightforward. In fact, I was able to get React v18 running
with minimal changes in just 10 minutes!
- Dropping IE Support: React v18 no longer supports Internet Explorer
(IE), which is no longer supported by Microsoft as of June 15, 2022.
Upgrading to v18 in v6 would be a good way to align with this change.
TS updates:
* FC children has to be explicit:
https://stackoverflow.com/questions/71788254/react-18-typescript-children-fc
* forcing version 18 types in resolutions:
https://sentry.io/answers/type-is-not-assignable-to-type-reactnode/
Test updates:
* fixing SWR issue that we have always had but it manifests more in new
React (https://github.com/vercel/swr/issues/2373)
---------
Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
This PR lets you filter by flag creator by interacting with the user's
avatar.
Additionally, I've switched the custom popover for the standard tooltip
that we use elsewhere in the table. This gives the table a more cohesive
feel. As such, I have also deleted the component created in a previous
PR, because it's no longer in use anywhere.
It now looks like this (when tabbed to; notice the focus ring):
![image](https://github.com/Unleash/unleash/assets/17786332/d321d9df-0b17-49c3-bea7-89331df3f994)
What the title says. There are input values that are whitespace
sensitive, so this will trim clientId and entity field, preventing the
form from sending leading or trailing whitespace. Will make a PR on
enterprise as well to trim on the backend as well.
This PR fixes a bug where if you navigated to the projects page via the
menu, scrolled down, and hovered over a project's avatars, you'd be
scrolled to the top of the page when you moused off the avatar.
Turns out this issue was also in the group cards. It seems to be that
the popover attempts to restore focus back to where you where, which, if
you navigated via the menu, is at the top of the page. Because these
popovers don't have any focusable content, we can disable that
functionality.
Additionally, I've disabled the scroll lock when the popover is open.
The scroll lock made it impossible to scroll when one of the popovers is
open, which is confusing as a user.
This change adds information about the project modes to the new
project creation form, using the tooltip for project creation modes.
In doing so, it updates the config button tooltip to accept extra
elements and adds styling for them.
What it looks like:
![image](https://github.com/Unleash/unleash/assets/17786332/809fb48e-2404-416b-a867-6fa04978ccc1)
## a11y issues
This solution does present one problem: the popover doesn't get focus,
so it's impossible for you to scroll with only a keyboard. However, this
is something that's present in Unleash already, and not something that I
think would be easily solvable, so I don't think this is when we should
solve it.
1. Only suggest to create a tag value if the input is more than two
characters after trimming.
2. Ignore trailing and leading whitespace when considering which
autocomplete options to show
This PR changes the project screen by calling the main tab "flags"
instead of "overview". There isn't really an overview available on that
tab anymore, only a list of flags.
This PR removes the flag for the new project card design, making it GA.
It also removes deprecated components and updates one reference (in the
groups card) to the new components instead.
This PR removes all the feature flags related to the project list split
and updates the snapshot.
Now the project list will always contain "my projects" and "other
projects"
We have an issue that if you open up Insights, the Time to Production
chart was showing nothing because it was taking the median across all
projects. You might have many new or empty projects where the median was
0 (no data).
For example, the median from [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.7, 50.3, 140] was 0.
Now, we will remove the 0 values to have a more reasonable median.
This change fixes a bug where we would show the list of segments as
changed (causing a conflict) if their order wasn't the same in the
change as in the original.
By sorting the segments before comparing them, we can avoid this issue.
To avoid modifying the objects that are passed in (in case that has
knock-on effects anywhere), we copy the objects. And because `toSorted`
"only" has about 89% coverage now, I chose to use `sort` and spread the
arrays instead.
This PR hides horizontal overflow in the dialog.
The pop-up docs that we have on small windows was causing a tiny bit of
overflow, giving us an annoying (and pretty useless) horizontal
scrollbar. We can hide that scrollbar by hiding horizontal overflow.
This PR contains a few fixes for button designs on small screens for the
new project form.
It makes all buttons (config and actions) full-width and addresses some
sizing stuff.
It also caps the width of the stickiness button on non-small screens to
avoid shifting.
![image](https://github.com/Unleash/unleash/assets/17786332/83af0a1c-8eb0-4a6b-aa5c-491bbcfab8e9)
This PR implements some initial cleanup work for the new project
creation dialog.
The primary focus here is to remove unused props and to use the same
logic for the configuration buttons regardless of the content (mode,
stickiness, envs, change requests).
This PR allows you to configure change requests for all environments
when no environments are enabled explicitly. This is the default state
of the form and makes it so that you can configure CRs even if you want
all envs enabled.
Additionally, it preserves the case where you configure CRs for an
environment and then disable all envs.
This is logic only. It's not available in the UI yet.
## About the changes
Summing on Billing page got a little wonky after changing how the
summing worked when the estimation flag is off. This attempts to return
it to previous way of showing numbers when flag is off
If you go directly to the billing page it will not add user calculations
to the total. If you however interact with the UI, like change tabs back
and forth, it will suddenly show the correct sum:
![image](https://github.com/Unleash/unleash/assets/707867/af6eeddf-be3f-42ae-a588-f57c30d739ca)
![image](https://github.com/Unleash/unleash/assets/707867/b4a0b832-a550-4e87-aa69-7b27f96d3beb)
---------
Co-authored-by: Nuno Góis <github@nunogois.com>
Co-authored-by: Gastón Fournier <gaston@getunleash.io>
This change makes it so that the button for change request
environments reads correctly when:
1. You have no envs configured: "Configure change requests"
2. One env configured: "1 environment configured"
3. More than one env configured: "`n` environments configured"
This change makes the CR button wider when you have environments
selected, reducing the difference between "no environments" and "envs
configured" states, thereby reducing the difference in the layout.
This PR contains two small UI improvements for the new project creation
form:
1. Wrap the action buttons when necessary (so that they don't become
unavailable when the window gets narrow enough.)
2. Make the change request table scrollable horizontally, so that it can
still be configured on narrow windows.
---------
Co-authored-by: sjaanus <sellinjaanus@gmail.com>
This PR addresses several related fixes to the new project creation
dialog to prevent unnecessary growing and shifting:
- use a fixed width for the guidance sidebar
- use a fixed height for the guidance code snippet
- use a fixed height for the mobile guidance
- use a fixed width for the mode selector button
- cap description height
This is a little tricky because we don't want the changes for the dialog
to affect other forms. As such, I've added some new options you can use
when you create the guidance components / sidebar.
This PR is part of #4380 - Remove legacy `/api/feature` endpoint.
## About the changes
### Frontend
- Removes the useFeatures hook
- Removes the part of StrategyView that displays features using this
strategy (not been working since v4.4)
- Removes 2 unused features entries from routes
### Backend
- Removes the /api/admin/features endpoint
- Moves a couple of non-feature related tests (auth etc) to use
/admin/projects endpoint instead
- Removes a test that was directly related to the removed endpoint
- Moves a couple of tests to the projects/features endpoint
- Reworks some tests to fetch features from projects features endpoint
and strategies from project strategies
This PR adds accessible descriptions to the dropdown widgets in the new
project creation form. The description is the same as we show in the
background
We have this very specific edge case in the new project form
dropdowns. It only occurs for the single-select lists and only if you
select an item via search.
When the search input is non-empty, you can use enter to select the
first item in the list.
For some reason, this also triggers a click on the underlying button
that opens the dropdown (I'm guessing this is to do with an underlying
focus).
To work around it, we create a variable that prevents you from opening
the dropdown if it is true. We set it to 'true' when you close it (for
single-selects), but also set single-millisecond timeout that sets it
to false thereafter.
This is much to short for the user to notice anything, but it prevents
the browser from noticing the click.
Adds icons to sidebar documentation and removes the link when you can't
interact with it.
I'm a little concerned that this won't be very accessible at the moment,
because we don't announce that anything has changed (i.e. there's no way
to find out that the text has changed if you can't see it), and the text
isn't labeled as describing anything. (this is being addressed in #7110
)
![image](https://github.com/Unleash/unleash/assets/17786332/2f482aa1-b74d-4b0f-97aa-2dbc1d1f82f9)
There's a few caveats to this:
1. we don't set a min height at the moment. I've avoided this because we
use the sidebar a number of other places and I wanted to touch as little
as possible. This means we can still get height adjustments
2. The new project icon doesn't have the same proportions as the mui
icons. This adds some additional jank. We should probably look at this,
though.
I've marked the project creation dialog as "compact", so that it's only
as tall as it needs to be.
However, by default, compact forms don't scroll because they have
overflow set to hidden. This is a problem on very short windows. To get
around this, I've set overflow to unset on compact forms.
I've also removed `min-height: 0` which has some weird side effects on
the centered dialog. Instead, I'm setting `min-height` to `unset` if
it's compact.
![image](https://github.com/Unleash/unleash/assets/17786332/e7d5db52-32d3-47d9-b31f-c73a5bb8e00f)
This task also uncovered some inconsistencies and some borders that only
show up sometimes, so I've removed them too.
I realized that, in an oversight, the form now shows and sends project
CR config, even if the new form isn't active. The API just ignores it if
it doesn't understand it, so it's not very harmful, but it's better if
we don't send it at all. This PR does that.
It does not actually test that change request info isn't included (but
it does test ID inclusion). This is because:
- change request info is only included if we're enterprise. The rendered
version of the hook isn't by default.
- Setting up module mocking and making it work seems like a lot of work
for a small gain, considering we're probably going to be removing the
old form anyway.
- I've tested it locally.
Also adds some testing for the hook related to name validation and
payload creation
At first, I was creating a new component, Project Banner, which was 90%
of the old banner and 10% new code, but it did not feel right. The
current banner is actually smart enough to be used in any container. So
now, I have moved the outdated SDK banner to the project level.
I like the simplicity of the change.
![image](https://github.com/Unleash/unleash/assets/964450/e57c1ace-e8f9-4866-a063-6f9ae561c6c0)
Instead of using the `required` attribute, we manually make it
required. This is indicated visually by red error text if the value is
empty (or whitespace only). To indicate to screen readers that it is
required, we add the `aria-required` attribute.
We didn't previously validate if the name
was whitespace only.
Also: if no envs are selected, indicate that all will be included
This prevents this form value from ever being invalid.
It seems the code that was copied was copied from before we changed
the validation logic, so it wouldn't submit. This fixes that to remove
any ID validation in the new form.
1. Added new schema and tests
2. Controller also accepts the data
3. Also sending fake data from frontend currently
Next steps, implement service/store layer and frontend
This fixes the case when a customer have thousands of strategies causing
the react UI to crash. We still consider it incorrect to use that amount
of strategies and this is more a workaround to help the customer out of
a crashing state.
We put it behind a flag called `manyStrategiesPagination` and plan to
only enable it for the customer in trouble.
This PR adds some tests around how project envs and change request envs
interact in the new project form. It tests that:
1. If you remove an env from the project setup, that env is also removed
from the change request list.
2. If you try to enable CRs for an env that isn't enabled, nothing
happens.