fix: deleted cohort navigation experience (#38753)

Co-authored-by: yazan-amer <yazan.amer@progressoft.com>
This commit is contained in:
Yazan Amer Abu Obaideh
2025-10-15 01:16:32 +03:00
committed by GitHub
parent 8ca251c157
commit 06102dae27
3 changed files with 53 additions and 1 deletions

View File

@@ -14,7 +14,7 @@ import { LemonButton } from 'lib/lemon-ui/LemonButton'
import { LemonField } from 'lib/lemon-ui/LemonField'
import { LemonSelect } from 'lib/lemon-ui/LemonSelect'
import { Spinner } from 'lib/lemon-ui/Spinner/Spinner'
import { IconErrorOutline, IconUploadFile } from 'lib/lemon-ui/icons'
import { IconErrorOutline, IconRefresh, IconUploadFile } from 'lib/lemon-ui/icons'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { useAttachedLogic } from 'lib/logic/scenes/useAttachedLogic'
import { ButtonPrimitive } from 'lib/ui/Button/ButtonPrimitives'
@@ -71,6 +71,7 @@ export function CohortEdit({ id, attachTo, tabId }: CohortEditProps): JSX.Elemen
useAttachedLogic(logic, attachTo)
const {
deleteCohort,
restoreCohort,
setOuterGroupsType,
setQuery,
duplicateCohort,
@@ -131,6 +132,25 @@ export function CohortEdit({ id, attachTo, tabId }: CohortEditProps): JSX.Elemen
return <NotFound object="cohort" />
}
if (cohort.deleted) {
return (
<div>
<LemonBanner type="error">The cohort '{cohort.name}' has been soft deleted.</LemonBanner>
<ScenePanel>
<ButtonPrimitive
disabled={cohortLoading}
onClick={() => {
restoreCohort()
}}
menuItem
>
<IconRefresh /> Restore
</ButtonPrimitive>
</ScenePanel>
</div>
)
}
return (
<BindLogic logic={cohortEditLogic} props={logicProps}>
<div className="cohort">

View File

@@ -105,6 +105,24 @@ describe('cohortEditLogic', () => {
expect(api.update).toHaveBeenCalledTimes(1)
})
it('restore cohort', async () => {
await initCohortLogic({ id: 1 })
await expectLogic(logic, async () => {
logic.actions.setCohort({ ...mockCohort, deleted: true })
logic.actions.restoreCohort()
})
.toFinishAllListeners()
.toDispatchActions(['setCohort', 'restoreCohort'])
expect(api.update).toHaveBeenCalledTimes(1)
expect(api.update).toHaveBeenCalledWith(
expect.anything(),
{
deleted: false,
},
expect.anything()
)
})
describe('form validation', () => {
it('save with valid cohort', async () => {
await initCohortLogic({ id: 1 })

View File

@@ -69,6 +69,7 @@ export const cohortEditLogic = kea<cohortEditLogicType>([
saveCohort: (cohortParams = {}) => ({ cohortParams }),
setCohort: (cohort: CohortType) => ({ cohort }),
deleteCohort: true,
restoreCohort: true,
fetchCohort: (id: CohortType['id']) => ({ id }),
setCohortMissing: true,
onCriteriaChange: (newGroup: Partial<CohortGroupType>, id: string) => ({ newGroup, id }),
@@ -319,6 +320,19 @@ export const cohortEditLogic = kea<cohortEditLogicType>([
return values.cohort
}
},
restoreCohort: async () => {
try {
const restoredCohort = await api.cohorts.update(values.cohort.id, {
deleted: false,
})
actions.setCohort(restoredCohort)
lemonToast.success('Cohort restored successfully.')
return restoredCohort
} catch (error) {
lemonToast.error(`Failed to restore cohort: '${error}'`)
return values.cohort
}
},
saveCohort: async ({ cohortParams }, breakpoint) => {
const existingCohort = values.cohort
let cohort = { ...existingCohort, ...cohortParams }