diff --git a/frontend/__snapshots__/scenes-app-experiments--experiments-list.png b/frontend/__snapshots__/scenes-app-experiments--experiments-list.png index 3342ee2a14a57..5d6749345e2a4 100644 Binary files a/frontend/__snapshots__/scenes-app-experiments--experiments-list.png and b/frontend/__snapshots__/scenes-app-experiments--experiments-list.png differ diff --git a/frontend/__snapshots__/scenes-app-feature-flags--feature-flags-list.png b/frontend/__snapshots__/scenes-app-feature-flags--feature-flags-list.png index eaaba388c9c59..a01936611ef6e 100644 Binary files a/frontend/__snapshots__/scenes-app-feature-flags--feature-flags-list.png and b/frontend/__snapshots__/scenes-app-feature-flags--feature-flags-list.png differ diff --git a/frontend/__snapshots__/scenes-app-surveys--surveys-list.png b/frontend/__snapshots__/scenes-app-surveys--surveys-list.png index 60da5cf713cb3..78da6dfa1a967 100644 Binary files a/frontend/__snapshots__/scenes-app-surveys--surveys-list.png and b/frontend/__snapshots__/scenes-app-surveys--surveys-list.png differ diff --git a/frontend/src/lib/components/MemberSelect.tsx b/frontend/src/lib/components/MemberSelect.tsx index cde54586f1fce..a1cb6e1899c92 100644 --- a/frontend/src/lib/components/MemberSelect.tsx +++ b/frontend/src/lib/components/MemberSelect.tsx @@ -107,7 +107,7 @@ export function MemberSelect({ } > - + {typeof selectedMember === 'string' ? ( selectedMember ) : selectedMember ? ( diff --git a/frontend/src/scenes/experiments/Experiments.tsx b/frontend/src/scenes/experiments/Experiments.tsx index 05473a3bc73fc..70ba21a643296 100644 --- a/frontend/src/scenes/experiments/Experiments.tsx +++ b/frontend/src/scenes/experiments/Experiments.tsx @@ -2,6 +2,7 @@ import { LemonInput, LemonSelect } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { router } from 'kea-router' import { ExperimentsHog } from 'lib/components/hedgehogs' +import { MemberSelect } from 'lib/components/MemberSelect' import { PageHeader } from 'lib/components/PageHeader' import { ProductIntroduction } from 'lib/components/ProductIntroduction/ProductIntroduction' import { normalizeColumnTitle } from 'lib/components/Table/utils' @@ -39,8 +40,9 @@ export function Experiments(): JSX.Element { shouldShowEmptyState, shouldShowProductIntroduction, searchStatus, + userFilter, } = useValues(experimentsLogic) - const { setExperimentsTab, deleteExperiment, archiveExperiment, setSearchStatus, setSearchTerm } = + const { setExperimentsTab, deleteExperiment, archiveExperiment, setSearchStatus, setSearchTerm, setUserFilter } = useActions(experimentsLogic) const { hasAvailableFeature } = useValues(userLogic) @@ -230,6 +232,7 @@ export function Experiments(): JSX.Element { Status { if (status) { setSearchStatus(status as ProgressStatus | 'all') @@ -247,6 +250,16 @@ export function Experiments(): JSX.Element { dropdownMatchSelectWidth={false} dropdownMaxContentWidth /> + + Created by + + setUserFilter(user?.uuid ?? null)} + /> ([ setSearchTerm: (searchTerm: string) => ({ searchTerm }), setSearchStatus: (status: ProgressStatus | 'all') => ({ status }), setExperimentsTab: (tabKey: ExperimentsTabs) => ({ tabKey }), + setUserFilter: (userFilter: string | null) => ({ userFilter }), }), reducers({ searchTerm: { @@ -58,6 +59,12 @@ export const experimentsLogic = kea([ searchStatus: { setSearchStatus: (_, { status }) => status, }, + userFilter: [ + null as string | null, + { + setUserFilter: (_, { userFilter }) => userFilter, + }, + ], tab: [ ExperimentsTabs.All as ExperimentsTabs, { @@ -97,8 +104,8 @@ export const experimentsLogic = kea([ })), selectors(({ values }) => ({ filteredExperiments: [ - (selectors) => [selectors.experiments, selectors.searchTerm, selectors.searchStatus, selectors.tab], - (experiments, searchTerm, searchStatus, tab) => { + (s) => [s.experiments, s.searchTerm, s.searchStatus, s.userFilter, s.tab], + (experiments, searchTerm, searchStatus, userFilter, tab) => { let filteredExperiments: Experiment[] = experiments if (tab === ExperimentsTabs.Archived) { @@ -125,6 +132,12 @@ export const experimentsLogic = kea([ (experiment) => getExperimentStatus(experiment) === searchStatus ) } + + if (userFilter) { + filteredExperiments = filteredExperiments.filter( + (experiment) => experiment.created_by?.uuid === userFilter + ) + } return filteredExperiments }, ], @@ -133,14 +146,9 @@ export const experimentsLogic = kea([ (hasAvailableFeature): boolean => hasAvailableFeature(AvailableFeature.EXPERIMENTATION), ], shouldShowEmptyState: [ - (s) => [s.experimentsLoading, s.filteredExperiments], - (experimentsLoading, filteredExperiments): boolean => { - return ( - filteredExperiments.length === 0 && - !experimentsLoading && - !values.searchTerm && - !values.searchStatus - ) + (s) => [s.experimentsLoading, s.experiments], + (experimentsLoading, experiments): boolean => { + return experiments.length === 0 && !experimentsLoading && !values.searchTerm && !values.searchStatus }, ], shouldShowProductIntroduction: [ diff --git a/frontend/src/scenes/feature-flags/FeatureFlags.tsx b/frontend/src/scenes/feature-flags/FeatureFlags.tsx index 5d9733aec817e..5021d0863bdc6 100644 --- a/frontend/src/scenes/feature-flags/FeatureFlags.tsx +++ b/frontend/src/scenes/feature-flags/FeatureFlags.tsx @@ -4,6 +4,7 @@ import { router } from 'kea-router' import { ActivityLog } from 'lib/components/ActivityLog/ActivityLog' import { ActivityScope } from 'lib/components/ActivityLog/humanizeActivity' import { FeatureFlagHog } from 'lib/components/hedgehogs' +import { MemberSelect } from 'lib/components/MemberSelect' import { ObjectTags } from 'lib/components/ObjectTags/ObjectTags' import { PageHeader } from 'lib/components/PageHeader' import { ProductIntroduction } from 'lib/components/ProductIntroduction/ProductIntroduction' @@ -52,7 +53,7 @@ export function OverViewTab({ const { aggregationLabel } = useValues(groupsModel) const flagLogic = featureFlagsLogic({ flagPrefix }) - const { featureFlagsLoading, searchedFeatureFlags, searchTerm, uniqueCreators, filters, shouldShowEmptyState } = + const { featureFlagsLoading, searchedFeatureFlags, searchTerm, filters, shouldShowEmptyState } = useValues(flagLogic) const { updateFeatureFlag, loadFeatureFlags, setSearchTerm, setFeatureFlagsFilters } = useActions(flagLogic) const { user, hasAvailableFeature } = useValues(userLogic) @@ -274,6 +275,7 @@ export function OverViewTab({ { if (type) { if (type === 'all') { @@ -301,6 +303,7 @@ export function OverViewTab({ { if (status) { if (status === 'all') { @@ -323,22 +326,21 @@ export function OverViewTab({ Created by - { - if (user) { - if (user === 'any') { - if (filters) { - const { created_by, ...restFilters } = filters - setFeatureFlagsFilters(restFilters, true) - } - } else { - setFeatureFlagsFilters({ created_by: user }) + if (!user) { + if (filters) { + const { created_by, ...restFilters } = filters + setFeatureFlagsFilters(restFilters, true) } + } else { + setFeatureFlagsFilters({ created_by: user.id }) } }} - options={uniqueCreators} - value={filters.created_by ?? 'any'} /> diff --git a/frontend/src/scenes/feature-flags/featureFlagsLogic.ts b/frontend/src/scenes/feature-flags/featureFlagsLogic.ts index aa5df8a41afc5..6773878fd071b 100644 --- a/frontend/src/scenes/feature-flags/featureFlagsLogic.ts +++ b/frontend/src/scenes/feature-flags/featureFlagsLogic.ts @@ -3,7 +3,6 @@ import { actions, connect, events, kea, listeners, path, props, reducers, select import { loaders } from 'kea-loaders' import { actionToUrl, router, urlToAction } from 'kea-router' import api from 'lib/api' -import { LemonSelectOption } from 'lib/lemon-ui/LemonSelect' import { Scene } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' @@ -25,14 +24,10 @@ export enum FeatureFlagsTab { export interface FeatureFlagsFilters { active: string - created_by: string + created_by: number type: string } -interface FeatureFlagCreators { - [id: string]: string -} - export interface FlagLogicProps { flagPrefix?: string // used to filter flags by prefix e.g. for the user interview flags } @@ -137,7 +132,7 @@ export const featureFlagsLogic = kea([ searchedFlags = searchedFlags.filter((flag) => (active === 'true' ? flag.active : !flag.active)) } if (created_by) { - searchedFlags = searchedFlags.filter((flag) => flag.created_by?.id === parseInt(created_by)) + searchedFlags = searchedFlags.filter((flag) => flag.created_by?.id === created_by) } if (type === 'boolean') { searchedFlags = searchedFlags.filter( @@ -164,24 +159,6 @@ export const featureFlagsLogic = kea([ }, ], ], - uniqueCreators: [ - (selectors) => [selectors.featureFlags], - (featureFlags) => { - const creators: FeatureFlagCreators = {} - for (const flag of featureFlags) { - if (flag.created_by) { - if (!creators[flag.created_by.id]) { - creators[flag.created_by.id] = flag.created_by.first_name - } - } - } - const response: LemonSelectOption[] = [ - { label: 'Any user', value: 'any' }, - ...Object.entries(creators).map(([id, first_name]) => ({ label: first_name, value: id })), - ] - return response - }, - ], shouldShowEmptyState: [ (s) => [s.featureFlagsLoading, s.featureFlags], (featureFlagsLoading, featureFlags): boolean => { diff --git a/frontend/src/scenes/surveys/Surveys.tsx b/frontend/src/scenes/surveys/Surveys.tsx index 52b79940c00b8..e8f0f631cac2f 100644 --- a/frontend/src/scenes/surveys/Surveys.tsx +++ b/frontend/src/scenes/surveys/Surveys.tsx @@ -11,6 +11,7 @@ import { } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { router } from 'kea-router' +import { MemberSelect } from 'lib/components/MemberSelect' import { PageHeader } from 'lib/components/PageHeader' import { ProductIntroduction } from 'lib/components/ProductIntroduction/ProductIntroduction' import { VersionCheckerBanner } from 'lib/components/VersionChecker/VersionCheckerBanner' @@ -53,7 +54,6 @@ export function Surveys(): JSX.Element { surveysResponsesCountLoading, searchTerm, filters, - uniqueCreators, showSurveysDisabledBanner, } = useValues(surveysLogic) @@ -170,6 +170,7 @@ export function Surveys(): JSX.Element { onChange={(status) => { setSurveysFilters({ status }) }} + size="small" options={[ { label: 'Any', value: 'any' }, { label: 'Draft', value: 'draft' }, @@ -181,12 +182,12 @@ export function Surveys(): JSX.Element { Created by - { - setSurveysFilters({ created_by: user }) - }} - options={uniqueCreators} - value={filters.created_by} + setSurveysFilters({ created_by: user?.id })} /> diff --git a/frontend/src/scenes/surveys/surveysLogic.tsx b/frontend/src/scenes/surveys/surveysLogic.tsx index c0a0dc2717dc5..d31ffd5ac7a0d 100644 --- a/frontend/src/scenes/surveys/surveysLogic.tsx +++ b/frontend/src/scenes/surveys/surveysLogic.tsx @@ -5,7 +5,6 @@ import { loaders } from 'kea-loaders' import { router } from 'kea-router' import api from 'lib/api' import { FEATURE_FLAGS } from 'lib/constants' -import { LemonSelectOption } from 'lib/lemon-ui/LemonSelect' import { featureFlagLogic } from 'lib/logic/featureFlagLogic' import { Scene } from 'scenes/sceneTypes' import { teamLogic } from 'scenes/teamLogic' @@ -27,14 +26,10 @@ export function getSurveyStatus(survey: Survey): ProgressStatus { export interface SurveysFilters { status: string - created_by: string + created_by: null | number archived: boolean } -interface SurveysCreators { - [id: string]: string -} - export const surveysLogic = kea([ path(['scenes', 'surveys', 'surveysLogic']), connect(() => ({ @@ -84,7 +79,7 @@ export const surveysLogic = kea([ { archived: false, status: 'any', - created_by: 'any', + created_by: null, } as Partial, { setSurveysFilters: (state, { filters }) => { @@ -133,10 +128,8 @@ export const surveysLogic = kea([ if (status !== 'any') { searchedSurveys = searchedSurveys.filter((survey) => getSurveyStatus(survey) === status) } - if (created_by !== 'any') { - searchedSurveys = searchedSurveys.filter( - (survey) => survey.created_by?.id === (created_by ? parseInt(created_by) : '') - ) + if (created_by) { + searchedSurveys = searchedSurveys.filter((survey) => survey.created_by?.id === created_by) } if (archived) { @@ -158,24 +151,6 @@ export const surveysLogic = kea([ }, ], ], - uniqueCreators: [ - (selectors) => [selectors.surveys], - (surveys) => { - const creators: SurveysCreators = {} - for (const survey of surveys) { - if (survey.created_by) { - if (!creators[survey.created_by.id]) { - creators[survey.created_by.id] = survey.created_by.first_name - } - } - } - const response: LemonSelectOption[] = [ - { label: 'Any user', value: 'any' }, - ...Object.entries(creators).map(([id, first_name]) => ({ label: first_name, value: id })), - ] - return response - }, - ], payGateFlagOn: [(s) => [s.featureFlags], (featureFlags) => featureFlags[FEATURE_FLAGS.SURVEYS_PAYGATES]], whitelabelAvailable: [ (s) => [s.hasAvailableFeature],