mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: count number of combinations from playground (#4077)
This PR adds plausible tracking of the number of feature combinations that we get from the advanced playground API. The event type has been added to plausible Relates to #3545
This commit is contained in:
parent
89cf16f915
commit
12c00733d9
@ -62,6 +62,7 @@
|
||||
"@uiw/codemirror-theme-duotone": "4.21.3",
|
||||
"@uiw/react-codemirror": "4.21.1",
|
||||
"@vitejs/plugin-react": "3.1.0",
|
||||
"cartesian": "^1.0.1",
|
||||
"chart.js": "3.9.1",
|
||||
"chartjs-adapter-date-fns": "3.0.0",
|
||||
"classnames": "2.3.2",
|
||||
|
@ -36,6 +36,8 @@ import {
|
||||
} from 'openapi';
|
||||
import { capitalizeFirst } from 'utils/capitalizeFirst';
|
||||
import { AdvancedPlaygroundEnvironmentDiffCell } from './AdvancedPlaygroundEnvironmentCell/AdvancedPlaygroundEnvironmentDiffCell';
|
||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||
import { countCombinations } from './combinationCounter';
|
||||
|
||||
const defaultSort: SortingRule<string> = { id: 'name' };
|
||||
const { value, setValue } = createLocalStorage(
|
||||
@ -61,6 +63,16 @@ export const AdvancedPlaygroundResultsTable = ({
|
||||
input,
|
||||
loading,
|
||||
}: IAdvancedPlaygroundResultsTableProps) => {
|
||||
const { trackEvent } = usePlausibleTracker();
|
||||
if (features) {
|
||||
trackEvent('playground', {
|
||||
props: {
|
||||
eventType: 'number-of-combinations',
|
||||
count: countCombinations(features),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const ref = useLoading(loading);
|
||||
const [searchValue, setSearchValue] = useState(
|
||||
|
@ -0,0 +1,97 @@
|
||||
import { countCombinations } from './combinationCounter';
|
||||
import {
|
||||
AdvancedPlaygroundEnvironmentFeatureSchema,
|
||||
AdvancedPlaygroundFeatureSchema,
|
||||
} from 'openapi';
|
||||
// @ts-expect-error no types available
|
||||
import cartesian from 'cartesian';
|
||||
|
||||
const generateFeature = (
|
||||
context: Record<string, string>
|
||||
): AdvancedPlaygroundEnvironmentFeatureSchema => ({
|
||||
isEnabled: false,
|
||||
isEnabledInCurrentEnvironment: true,
|
||||
variant: {
|
||||
name: 'disabled',
|
||||
enabled: false,
|
||||
},
|
||||
context: {
|
||||
appName: 'playground',
|
||||
},
|
||||
variants: [],
|
||||
name: 'default',
|
||||
environment: 'development',
|
||||
projectId: 'default',
|
||||
strategies: {
|
||||
result: false,
|
||||
data: [
|
||||
{
|
||||
name: 'default',
|
||||
id: '7b233aae-cbc4-45ea-ace2-4c78c8e7e760',
|
||||
disabled: false,
|
||||
parameters: {},
|
||||
result: {
|
||||
enabled: false,
|
||||
evaluationStatus: 'complete' as 'complete',
|
||||
},
|
||||
constraints: [
|
||||
{
|
||||
inverted: false,
|
||||
values: ['k'],
|
||||
operator: 'IN',
|
||||
contextName: 'appName',
|
||||
caseInsensitive: false,
|
||||
result: false,
|
||||
},
|
||||
],
|
||||
segments: [],
|
||||
links: {
|
||||
edit: '/projects/default/features/default/strategies/edit?environmentId=development&strategyId=7b233aae-cbc4-45ea-ace2-4c78c8e7e760',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const generateInput = (
|
||||
featureCount: number,
|
||||
environments: string[],
|
||||
contextValues: { [key: string]: string[] }
|
||||
): AdvancedPlaygroundFeatureSchema[] => {
|
||||
const cartesianContext = cartesian(contextValues);
|
||||
|
||||
return Array.from(Array(featureCount)).map((_, i) => ({
|
||||
name: `feature-${i}`,
|
||||
projectId: 'default',
|
||||
environments: Object.fromEntries(
|
||||
environments.map(env => [
|
||||
env,
|
||||
cartesianContext.map(generateFeature),
|
||||
])
|
||||
),
|
||||
}));
|
||||
};
|
||||
|
||||
it('counts the correct number of combinations', () => {
|
||||
const assertCount = (
|
||||
numberOfFeatures: number,
|
||||
envs: string[],
|
||||
context: { [k: string]: string[] }
|
||||
) => {
|
||||
const totalCombinations =
|
||||
numberOfFeatures *
|
||||
envs.length *
|
||||
Object.values(context)
|
||||
.map(contextValues => contextValues.length)
|
||||
.reduce((total, n) => total + n);
|
||||
const input = generateInput(numberOfFeatures, envs, context);
|
||||
expect(countCombinations(input)).toEqual(totalCombinations);
|
||||
};
|
||||
|
||||
assertCount(1, ['development'], { x: ['2'] });
|
||||
assertCount(10, ['development', 'production'], {
|
||||
x: ['1', '2'],
|
||||
y: ['x', 'abc'],
|
||||
});
|
||||
assertCount(5, ['development'], { x: ['1', '2'] });
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
import { AdvancedPlaygroundFeatureSchema } from 'openapi';
|
||||
|
||||
export const countCombinations = (
|
||||
features: AdvancedPlaygroundFeatureSchema[]
|
||||
) =>
|
||||
features.reduce(
|
||||
(total, feature) =>
|
||||
total +
|
||||
Object.values(feature.environments).flatMap(env => Object.keys(env))
|
||||
.length,
|
||||
0
|
||||
);
|
@ -40,7 +40,8 @@ export type CustomEvents =
|
||||
| 'demo-open-demo-web'
|
||||
| 'context-usage'
|
||||
| 'segment-usage'
|
||||
| 'strategy-add';
|
||||
| 'strategy-add'
|
||||
| 'playground';
|
||||
|
||||
export const usePlausibleTracker = () => {
|
||||
const plausible = useContext(PlausibleContext);
|
||||
|
@ -3613,6 +3613,13 @@ caniuse-lite@^1.0.30001400:
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001445.tgz#cf2d4eb93f2bcdf0310de9dd6d18be271bc0b447"
|
||||
integrity sha512-8sdQIdMztYmzfTMO6KfLny878Ln9c2M0fc7EH60IjlP4Dc4PiCy7K2Vl3ITmWgOyPgVQKa5x+UP/KqFsxj4mBg==
|
||||
|
||||
cartesian@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cartesian/-/cartesian-1.0.1.tgz#ae3fc8a63e2ba7e2c4989ce696207457bcae65af"
|
||||
integrity sha512-tR3qKRYpRJ6FXEGuoBwpuCYcwydrk1N2rduy7eWg1Msepi3i5fCxheryw4VBlCqjCbk3Vhjh3eg+IGHtl5H74A==
|
||||
dependencies:
|
||||
xtend "^4.0.1"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
@ -9587,6 +9594,11 @@ xregexp@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943"
|
||||
integrity sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==
|
||||
|
||||
xtend@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
|
Loading…
Reference in New Issue
Block a user