2023-02-14 17:03:53 +01:00
|
|
|
import { weightTypes } from 'constants/weightTypes';
|
2022-08-23 14:04:09 +02:00
|
|
|
import { IUiConfig } from 'interfaces/uiConfig';
|
2023-01-12 11:34:45 +01:00
|
|
|
import { INavigationMenuItem } from 'interfaces/route';
|
2022-04-06 12:22:24 +02:00
|
|
|
import { IFeatureVariant } from 'interfaces/featureToggle';
|
2022-07-22 13:15:28 +02:00
|
|
|
import { format, isValid } from 'date-fns';
|
2023-01-27 09:13:57 +01:00
|
|
|
import { IFeatureVariantEdit } from 'component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal';
|
2020-08-03 13:33:16 +02:00
|
|
|
|
2023-08-10 09:28:10 +02:00
|
|
|
/**
|
|
|
|
* Handle feature flags and configuration for different plans.
|
|
|
|
*/
|
2023-01-12 11:34:45 +01:00
|
|
|
export const filterByConfig =
|
|
|
|
(config: IUiConfig) => (r: INavigationMenuItem) => {
|
|
|
|
if (r.flag) {
|
|
|
|
// Check if the route's `flag` is enabled in IUiConfig.flags.
|
|
|
|
const flags = config.flags as unknown as Record<string, boolean>;
|
|
|
|
return Boolean(flags[r.flag]);
|
|
|
|
}
|
2022-04-06 12:22:24 +02:00
|
|
|
|
2023-09-11 14:26:40 +02:00
|
|
|
if (r.notFlag) {
|
|
|
|
const flags = config.flags as unknown as Record<string, boolean>;
|
|
|
|
|
|
|
|
return !(flags[r.notFlag] === true);
|
|
|
|
}
|
|
|
|
|
2023-01-12 11:34:45 +01:00
|
|
|
if (r.configFlag) {
|
|
|
|
// Check if the route's `configFlag` is enabled in IUiConfig.
|
|
|
|
return Boolean(config[r.configFlag]);
|
|
|
|
}
|
2022-08-23 14:04:09 +02:00
|
|
|
|
2023-01-12 11:34:45 +01:00
|
|
|
return true;
|
|
|
|
};
|
2021-07-16 15:41:54 +02:00
|
|
|
|
2021-02-26 10:42:34 +01:00
|
|
|
export const scrollToTop = () => {
|
|
|
|
window.scrollTo(0, 0);
|
|
|
|
};
|
|
|
|
|
2023-08-10 09:28:10 +02:00
|
|
|
export const mapRouteLink = (route: INavigationMenuItem) => ({
|
|
|
|
...route,
|
|
|
|
path: route.path.replace('/*', ''),
|
|
|
|
route: route.path,
|
|
|
|
});
|
|
|
|
|
2022-04-06 12:22:24 +02:00
|
|
|
export const trim = (value: string): string => {
|
2023-10-02 14:25:46 +02:00
|
|
|
if (value?.trim) {
|
2020-02-27 21:36:07 +01:00
|
|
|
return value.trim();
|
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
};
|
2020-05-20 16:32:29 +02:00
|
|
|
|
2022-07-22 13:15:28 +02:00
|
|
|
export const parseDateValue = (value: string) => {
|
|
|
|
const date = new Date(value);
|
2023-10-02 14:25:46 +02:00
|
|
|
return `${format(date, 'yyyy-MM-dd')}T${format(date, 'HH:mm')}`;
|
2022-07-22 13:15:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
export const parseValidDate = (value: string): Date | undefined => {
|
|
|
|
const parsed = new Date(value);
|
|
|
|
|
|
|
|
if (isValid(parsed)) {
|
|
|
|
return parsed;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const calculateVariantWeight = (weight: number) => {
|
|
|
|
return weight / 10.0;
|
|
|
|
};
|
|
|
|
|
2022-04-06 12:22:24 +02:00
|
|
|
export function updateWeight(variants: IFeatureVariant[], totalWeight: number) {
|
2022-02-04 10:36:08 +01:00
|
|
|
if (variants.length === 0) {
|
2021-10-28 13:32:29 +02:00
|
|
|
return [];
|
|
|
|
}
|
2020-08-03 13:33:16 +02:00
|
|
|
const variantMetadata = variants.reduce(
|
|
|
|
({ remainingPercentage, variableVariantCount }, variant) => {
|
|
|
|
if (variant.weight && variant.weightType === weightTypes.FIX) {
|
|
|
|
remainingPercentage -= Number(variant.weight);
|
|
|
|
} else {
|
|
|
|
variableVariantCount += 1;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
remainingPercentage,
|
|
|
|
variableVariantCount,
|
|
|
|
};
|
|
|
|
},
|
2023-10-02 14:25:46 +02:00
|
|
|
{ remainingPercentage: totalWeight, variableVariantCount: 0 },
|
2020-08-03 13:33:16 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
const { remainingPercentage, variableVariantCount } = variantMetadata;
|
|
|
|
|
|
|
|
if (remainingPercentage < 0) {
|
|
|
|
throw new Error('The traffic distribution total must equal 100%');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!variableVariantCount) {
|
2021-10-08 11:23:29 +02:00
|
|
|
throw new Error('There must be at least one variable variant');
|
2020-08-03 13:33:16 +02:00
|
|
|
}
|
|
|
|
|
2022-04-06 12:22:24 +02:00
|
|
|
const percentage = parseInt(
|
2023-10-02 14:25:46 +02:00
|
|
|
String(remainingPercentage / variableVariantCount),
|
2022-04-06 12:22:24 +02:00
|
|
|
);
|
2020-05-20 16:32:29 +02:00
|
|
|
|
2023-10-02 14:25:46 +02:00
|
|
|
return variants.map((variant) => {
|
2020-08-03 13:33:16 +02:00
|
|
|
if (variant.weightType !== weightTypes.FIX) {
|
|
|
|
variant.weight = percentage;
|
|
|
|
}
|
|
|
|
return variant;
|
2020-05-20 16:32:29 +02:00
|
|
|
});
|
|
|
|
}
|
2020-11-27 22:23:44 +01:00
|
|
|
|
2023-01-27 09:13:57 +01:00
|
|
|
export function updateWeightEdit(
|
|
|
|
variants: IFeatureVariantEdit[],
|
2023-10-02 14:25:46 +02:00
|
|
|
totalWeight: number,
|
2023-01-27 09:13:57 +01:00
|
|
|
) {
|
|
|
|
if (variants.length === 0) {
|
|
|
|
return [];
|
|
|
|
}
|
2023-07-26 16:08:11 +02:00
|
|
|
let { remainingPercentage, variableVariantCount } = variants.reduce(
|
2023-01-27 09:13:57 +01:00
|
|
|
({ remainingPercentage, variableVariantCount }, variant) => {
|
|
|
|
if (variant.weight && variant.weightType === weightTypes.FIX) {
|
|
|
|
remainingPercentage -= Number(variant.weight);
|
2023-07-26 16:08:11 +02:00
|
|
|
}
|
|
|
|
if (variant.weightType === weightTypes.VARIABLE) {
|
2023-01-27 09:13:57 +01:00
|
|
|
variableVariantCount += 1;
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
remainingPercentage,
|
|
|
|
variableVariantCount,
|
|
|
|
};
|
|
|
|
},
|
2023-10-02 14:25:46 +02:00
|
|
|
{ remainingPercentage: totalWeight, variableVariantCount: 0 },
|
2023-01-27 09:13:57 +01:00
|
|
|
);
|
|
|
|
|
2023-07-26 16:08:11 +02:00
|
|
|
const getPercentage = () =>
|
|
|
|
Math.round(remainingPercentage / variableVariantCount);
|
2023-01-27 09:13:57 +01:00
|
|
|
|
2023-10-02 14:25:46 +02:00
|
|
|
return variants.map((variant) => {
|
2023-01-27 09:13:57 +01:00
|
|
|
if (variant.weightType !== weightTypes.FIX) {
|
2023-07-26 16:08:11 +02:00
|
|
|
const percentage = getPercentage(); // round "as we go" - clean best effort approach
|
|
|
|
remainingPercentage -= percentage;
|
|
|
|
variableVariantCount -= 1;
|
|
|
|
|
2023-01-27 09:13:57 +01:00
|
|
|
variant.weight = percentage;
|
|
|
|
}
|
2023-07-26 16:08:11 +02:00
|
|
|
|
2023-01-27 09:13:57 +01:00
|
|
|
return variant;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-01-07 13:52:55 +01:00
|
|
|
export const modalStyles = {
|
|
|
|
overlay: {
|
|
|
|
position: 'absolute',
|
|
|
|
top: 0,
|
|
|
|
left: 0,
|
|
|
|
right: 0,
|
|
|
|
bottom: 0,
|
|
|
|
backgroundColor: 'rgba(0, 0, 0, 0.25)',
|
|
|
|
zIndex: 5,
|
|
|
|
},
|
|
|
|
content: {
|
|
|
|
width: '500px',
|
|
|
|
maxWidth: '90%',
|
|
|
|
margin: '0',
|
|
|
|
top: '50%',
|
|
|
|
left: '50%',
|
|
|
|
right: 'auto',
|
|
|
|
bottom: 'auto',
|
|
|
|
transform: 'translate(-50%, -50%)',
|
|
|
|
},
|
|
|
|
};
|