This PR cleans up the releasePlans flag. These changes were
automatically generated by AI and should be reviewed carefully.
Fixes#10536
## 🧹 AI Flag Cleanup Summary
The `releasePlans` feature flag has been removed, making the feature
permanently
available for Enterprise customers. All conditional logic and checks
related to
this flag have been removed from the codebase.
This change ensures that Release Plans are an integral part of the
Unleash
Enterprise offering.
### 🚮 Removed
- **Flag Definitions**
- `releasePlans` flag from `experimental.ts` in the backend.
- `releasePlans` flag from `uiConfig.ts` in the frontend.
- `releasePlans` flag from `server-dev.ts` development config.
- **Conditional Logic**
- Removed checks for `releasePlansEnabled` in components and hooks,
including
`ReleaseManagement.tsx`, `FeatureStrategyMenu.tsx`, and
`NewInUnleash.tsx`.
- Removed `useUiFlag('releasePlans')` calls from all frontend files.
- Removed the `flag: 'releasePlans'` property from route definitions in
`routes.ts`.
### 🛠 Kept
- **Feature Functionality**
- All UI and logic related to Release Plans and Release Templates are
now
unconditionally enabled for Enterprise users.
### 📝 Why
The `releasePlans` feature has been successfully rolled out and is now a
stable
part of the product. This cleanup removes the artık feature flag to
simplify the
codebase and reduce complexity.
---------
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Nuno Góis <github@nunogois.com>
This PR cleans up the projectListViewToggle flag. These changes were
automatically generated by AI and should be reviewed carefully.
Fixes#10526
## 🧹 AI Flag Cleanup Summary
This change removes the `projectListViewToggle` feature flag and
hardcodes its
behavior. The feature, which allows toggling between card and list views
for
projects, is now permanently enabled.
### 🚮 Removed
- **Flag Definitions**
- Removed `projectListViewToggle` from `src/server-dev.ts`,
`src/lib/types/experimental.ts`, and
`frontend/src/interfaces/uiConfig.ts`.
- **Hooks & Conditionals**
- Removed `useUiFlag('projectListViewToggle')` calls from
`ProjectGroup.tsx`
and `ProjectList.tsx`.
- Removed conditional rendering logic based on the flag in
`ProjectGroup.tsx`
and `ProjectList.tsx`.
### 🛠 Kept
- **Project List View**
- The project list view functionality is now always available for
non-OSS
versions of Unleash.
- The `ProjectsListViewToggle` component is now always rendered when not
in an
OSS environment.
### 📝 Why
The `projectListViewToggle` feature flag was marked as completed and its
intended outcome was to be kept. The code has been updated to reflect
this by
removing the flag and making the feature a permanent part of the
application.
This simplifies the codebase by removing dead code paths and feature
flag
checks.
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
This PR cleans up the createFlagDialogCache flag. These changes were
automatically generated by AI and should be reviewed carefully.
Fixes#10504
## 🧹 AI Flag Cleanup Summary
This change removes the `createFlagDialogCache` feature flag, making its
functionality permanent. The create-feature-flag dialog will now always
cache
its state in local storage.
### 🚮 Removed
- **TypeScript Definitions**
- Removed `createFlagDialogCache` from `UiFlags` in
`frontend/src/interfaces/uiConfig.ts`.
- Removed `createFlagDialogCache` from `IFlagKey` in
`src/lib/types/experimental.ts`.
- **Flag Configuration**
- Removed the `createFlagDialogCache` flag definition from
`src/lib/types/experimental.ts`.
- **Conditional Logic**
- Removed the `useUiFlag` hook and conditional logic for caching in
`frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFe
atureTogglesHeader/CreateFeatureDialog.tsx`.
### 🛠 Kept
- **Feature Functionality**
- The feature of caching the create-flag dialog's form state in local
storage
is now always enabled.
### 📝 Why
The `createFlagDialogCache` feature has been successfully rolled out and
is now
considered stable. This cleanup removes the obsolete feature flag and
hardcodes
the enabled behavior, simplifying the codebase.
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This PR cleans up the lifecycleMetrics flag. These changes were
automatically generated by AI and should be reviewed carefully.
Fixes#10505
---------
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This PR cleans up the crDiffView flag. These changes were automatically
generated by AI and should be reviewed carefully.
Fixes#10484🧹 AI Flag Cleanup Summary
This PR removes the crDiffView feature flag and its associated legacy
components
for displaying changes in a Change Request. The flag has been enabled
and the
new diff view is now permanent.
This involved removing the feature flag from the configuration and code,
deleting several legacy components, and updating the components that
used them
to only use the new versions.
🚮 Removed
• Feature Flag Logic
• All checks for the crDiffView flag.
• The flag definition in uiConfig.ts, experimental.ts, and
server-dev.ts.
• Legacy Components
• LegacyStrategyChange.tsx
• StrategyTooltipLink.tsx
• LegacyReleasePlanChange.tsx
• SegmentTooltipLink.tsx
• LegacySegmentChangeDetails.tsx
• LegacyArchiveFeatureChange from ArchiveFeatureChange.tsx
• LegacyDependencyChange from DependencyChange.tsx
• LegacyToggleStatusChange from ToggleStatusChange.tsx
🛠 Kept
• New Components
• The new change request diff view components (StrategyChange,
ReleasePlanChange, etc.) are now used directly.
• The UI for displaying changes in a Change Request now consistently
uses
the improved diff view.
📝 Why
The crDiffView feature flag was deemed complete and ready for permanent
implementation. The cleanup follows standard procedure to remove the
flag and
associated dead code, simplifying the codebase and making it easier to
maintain.
This change makes the improved diff view for change requests the only
available
view.
---------
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This PR cleans up the improvedJsonDiff flag. These changes were
automatically generated by AI and should be reviewed carefully.
Fixes#10483
## 🧹 AI Flag Cleanup Summary
This PR removes the `improvedJsonDiff` feature flag, making the enhanced
JSON
diffing component the default and only option. The now-unused legacy
diff
component and all related feature flag logic have been removed to
streamline the
codebase.
### 🚮 Removed
- **Components**
- `OldEventDiff` component was removed, along with its helper types and
constants.
- **Flag Logic**
- All conditional rendering based on the `improvedJsonDiff` flag was
removed.
- The `sort` prop from `EventDiff` was removed as it was only used by
the
legacy component.
- **Configuration**
- `improvedJsonDiff` flag definition was removed from `uiConfig.ts`,
`experimental.ts`, and `server-dev.ts`.
- **Tests**
- Mock configuration for `improvedJsonDiff` in tests was removed.
### 🛠 Kept
- **Components**
- `NewEventDiff` was renamed to `EventDiff` and is now the standard
implementation.
### 📝 Why
The `improvedJsonDiff` feature flag was marked as completed with its
outcome
being "kept". This cleanup finalizes the feature rollout by removing the
flag
and associated legacy code, simplifying the implementation and reducing
code
complexity.
---------
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This PR cleans up the timestampsInChangeRequestTimeline flag. These
changes were automatically generated by AI and should be reviewed
carefully.
Fixes#10491
## 🧹 AI Flag Cleanup Summary
This PR removes the `timestampsInChangeRequestTimeline` feature flag.
The
feature is now permanently enabled.
⚠️ No conditional logic for this flag was found in the provided files.
The
changes are limited to removing flag definitions and configurations. The
actual
logic may reside in other parts of the codebase not included in this
operation.
### 🚮 Removed
- **Flag Definitions & Configuration**
- Removed `timestampsInChangeRequestTimeline` from `IFlagKey` type in
`src/lib/types/experimental.ts`.
- Removed `timestampsInChangeRequestTimeline` flag configuration from
`src/lib/types/experimental.ts`.
- Removed `timestampsInChangeRequestTimeline` from the `UiFlags`
interface in
`frontend/src/interfaces/uiConfig.ts`.
- Removed the flag from the experimental flags in `src/server-dev.ts`.
### 🛠 Kept
- **Feature Functionality**
- The behavior previously enabled by the
`timestampsInChangeRequestTimeline`
flag is now the default and only behavior.
### 📝 Why
The `timestampsInChangeRequestTimeline` feature flag was marked as
completed
with an intended outcome of "kept". This means the feature has been
rolled out
successfully and should be permanent. This cleanup removes the obsolete
flag and
its related configurations, simplifying the code and adhering to best
practices
for feature flag lifecycle management.
Co-authored-by: unleash-bot <194219037+unleash-bot[bot]@users.noreply.github.com>
This change adds the `crDiffView` flag to Unleash, potentially enabling
the new JSON diff tab in change request changes instead of the "view
json diff" hover functionality.
This PR takes two steps towards better constraint handling:
## New type: `IConstraintWithId`
Introduces a new type, `IConstraintWithId`. This is the same as an
`IConstraint`, except the constraint id property is required. The idea
is that the list of editable constraints should move towards using this
instead of just `IConstraint`. That should prevent us (on a type-level)
from seeing more of the same kind of errors we saw with the segment
constraints yesterday.
I don't want to go ahead and update all the upstream uses of this to
IConstraintWithId in this PR, so I'll look at that separately.
## API payload constraint replacer
Introduces an api payload constraint "replacer", which we can use for
[JSON.stringify's `replacer`
parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#the_replacer_parameter).
The current implementation works both for strategies and for segments
and has been added to edit + create forms for both of these resources.
This has a couple benefits:
1. We can clearly state exactly how we want them to be rendered,
including property order. I've decided to go with context -> operator ->
value(s) as the main one (check the screenie), as I believe this is the
most logical reading order.
2. We can exclude value/values (whichever one doesn't work with the
operator)
3. It doesn't matter how we treat constraints internally, we can still
present the payload how we want
4. Importantly: this only affects the stringification for the
user-facing API payload, so it's very low risk. It does not affect
anything that we actually send to the api.
Here's what it can look like with ordered properties:
<img width="392" alt="image"
src="https://github.com/user-attachments/assets/f46f77c8-0b5a-4ded-b13a-bb567df60bd3"
/>
This PR continues the cleanup after removing the addEditStrategy flag
(part 2 of ???). The primary purpose of this PR is to delete and remove
all references to the LegacyConstraintAccordion.
I've gone and updated all references to the legacy files in external
components and verified manually that they still work.
Most of the files in this PR are changing references. I've extracted two
bits into more general constants/utils:
1. Constraint IDs are a symbol. it was exported as a const from the
previous createEmptyConstraint file. I've moved it into constants.
2. formatOperatorDescription was similarly used all over the place, so
I've placed it in the shared utils directory.
In reviewing this, you can ignore any changes in the legacy constraint
accordion folder, because that's all been deleted. Instead, focus on the
changes in the other files. It's primarily just import updates, but
would be good to get a second set of eyes, anyway.
Removes all usages of flag addEditStrategy and refactors code where
necessary.
This is only the first step of the cleanup. After this, there's still
lots of code to be removed. I've got a different PR that removes ~5k
lines of code (https://github.com/Unleash/unleash/pull/10105) that I
want to reach in pieces to make sure that everythnig works on the way
there.
Adds caching via localstorage to the flag creation form, so that if you
(accidentally) close the form before submitting it, you'll retain (most)
of the same data when you reopen it.
Specifically, we'll store:
- name
- description
- type
- tags
- impression data
We can't store the project as it is now, because it gets overridden by
whatever is in the URL. However, this is probably a good thing. It means
that if you navigate to a different project and open the feature
creation form there, it'll retain everything from the last one, but
it'll use the current project.
The stored data is cleared when you successfully create a feature, so
that you don't get dangling data.
The data is also stored in a shared cache for all projects, so that you
don't have different caches per project.
The behavior of seeding the form is hidden behind a flag (that doesn't
exist yet). We'll still read and write to the cache if the flag is off,
but we won't use it to populate the feature form, so it has no
discernible impact on the user.
## Bug detected 🐛 ... and squashed
Working on this, I came to realize that there was a bug in how the
config button and use feature form hooks interacted. We (in this case
probably me) have assumed that it's fine to use a set for any option
checking in the config buttons. Also, we're using a set to store tags in
the feature form. But objects aren't compared by value in JS, so the set
will happily accept multiple instances of the same tag. Likewise, these
tags won't show up as selected in the dropdown because when the dropdown
checks if the set `has` the value, it's using reference equality.
To get around this, I have normalized the values of the Tags set to
strings (`<type>:<value>`), which are easily comparable.
We can iterate on this later if we need to.
## `useLocalStorageState`
In doing this, I have also made a change to the useLocalStorageState
hook:
the exposed "setState" function now writes to the localstorage
immediately. This is because the useEffect method might not have time to
save the data if the component unmounts (this was the case with the flag
dialog).
However, I have kept the useEffect because it gets run on component
mount and then only when it changes. This means that we will get double
saves to localstorage, but it'll be with the same data, so it's benign.
I've tried out two other uses of the hook (event timeline props and
environment columns in the project flags table) and see no discernible
difference in behavior.
## `useFeatureForm`
I have also made a change to the useFeatureForm hook and removed a
`useEffect` that would reset the name to whatever you passed in as the
initial name if you cleared it out. This essentially meant that you
couldn't clear the name completely, because it would just refill with
the initial name.
As far as I can tell, there is no need to have this sticking around
anymore. The hook is only used in two places: the flag creation dialog
and the flag edit page. The flag edit page doesn't allow you to change
the name anyway and it was causing issues in the dialog. It's likely a
holdover from the way something worked 3 years ago. Both the dialog and
the edit screen seem to work just fine with this change.
I have also changed the function parameters from ordered parameters to
an object. There's so many of them that even you don't think it's a good
idea to use objects when you have multiple params with the same type,
it's just nigh-impossible to remember the order by now.
## Minor changes
Additionally, I came across three issues that were causing react errors,
and have fixed them.
1. we'd forgotten to interpolate a variable and just used the variable
name in a string instead
2. an html attribute that doesn't exist (`aria-role` instead of `role`)
3. Providing a disabled button inside a tooltip. I've seen this one
around for ages and it prevented tooltips from working on disabled
buttons. The solution was wrapping it in a span.
- added `sideMenuCleanup` flag
- extracted `SecondaryNavigation`, `SecondaryNavigationList` and
`MobileNavigationSidebar` into separate files
- hidden recent projects and flags
- renamed 'Insights' to 'Analytics'
We're migrating to ESM, which will allow us to import the latest
versions of our dependencies.
Co-Authored-By: Christopher Kolstad <chriswk@getunleash.io>
Initial PR that adds logic for displaying a link to stripe to view
consumption based pricing in the billing overview
---------
Co-authored-by: Nuno Góis <github@nunogois.com>