Skip to content

Instantly share code, notes, and snippets.

@andybrackley
Created June 24, 2024 12:59
Show Gist options
  • Save andybrackley/888a92381c144e42428dd2b47ea2dae6 to your computer and use it in GitHub Desktop.
Save andybrackley/888a92381c144e42428dd2b47ea2dae6 to your computer and use it in GitHub Desktop.
import { ReportParameterCheckboxOption, ReportParameterListOption, ReportParameterOption } from './parameterTypes';
/*
/// Example Usage:
const forRiskParams = parameterGenerator<RiskParams>().pipe((gen) => [
gen.forProperty('riskCategory').fromEnum(RiskCategory),
gen.forProperty('tradeCategory').fromEnum(TradeCategory)
]);
const forAdditional = parameterGenerator<ReportOptions>().pipe((gen) => [
gen.forProperty('trimThousands').fromBoolean()
]);
*/
type ListOptionT = { label: string; value: string };
export const parameterGenerator = <T extends object>(defaults?: T, current?: T) => {
const getEnumValues = <TEnum extends object>(enm: TEnum) => {
return Object.values(enm);
};
const generator = {
forProperty: (propName: keyof T, label?: string) => {
const effectiveLabel = label ?? (propName as string);
const selected = current ? current[propName] : defaults ? defaults[propName] : undefined;
const fromList = (options: ListOptionT[]): ReportParameterOption => {
const selectedOption =
options.find((option) => option.value === selected) ??
(options.length > 0 ? options[0] : undefined);
const asDropdown: ReportParameterListOption = {
type: 'list',
title: effectiveLabel,
options: options,
selected: selectedOption
};
return {
propertyName: propName as string,
option: asDropdown
};
};
return {
fromBoolean: (): ReportParameterOption => {
const asCheckbox: ReportParameterCheckboxOption = {
type: 'checkbox',
title: effectiveLabel,
isChecked: current
? (current[propName] as boolean)
: defaults
? (defaults[propName] as boolean)
: false
};
return {
propertyName: propName as string,
option: asCheckbox
};
},
fromList: fromList,
fromEnum: <TEnum extends object>(
enm: TEnum,
filter?: (val: TEnum) => boolean
): ReportParameterOption => {
const enumValues = getEnumValues(enm).filter((k) => !filter || filter(k));
const asOptions = enumValues.map((k) => ({ label: k as string, value: k as string }));
return fromList(asOptions);
}
};
}
};
return {
pipe: <X>(f: (gen: typeof generator) => X) => f(generator)
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment