a lot
This commit is contained in:
@@ -3,7 +3,7 @@ export const operators = {
|
||||
isNot: 'Is not',
|
||||
contains: 'Contains',
|
||||
doesNotContain: 'Not contains',
|
||||
};
|
||||
} as const;
|
||||
|
||||
export const chartTypes = {
|
||||
linear: 'Linear',
|
||||
@@ -12,7 +12,8 @@ export const chartTypes = {
|
||||
pie: 'Pie',
|
||||
metric: 'Metric',
|
||||
area: 'Area',
|
||||
};
|
||||
map: 'Map',
|
||||
} as const;
|
||||
|
||||
export const lineTypes = {
|
||||
monotone: 'Monotone',
|
||||
@@ -30,14 +31,14 @@ export const lineTypes = {
|
||||
bumpY: 'Bump Y',
|
||||
bump: 'Bump',
|
||||
linearClosed: 'Linear closed',
|
||||
};
|
||||
} as const;
|
||||
|
||||
export const intervals = {
|
||||
minute: 'Minute',
|
||||
day: 'Day',
|
||||
hour: 'Hour',
|
||||
month: 'Month',
|
||||
};
|
||||
minute: 'minute',
|
||||
day: 'day',
|
||||
hour: 'hour',
|
||||
month: 'month',
|
||||
} as const;
|
||||
|
||||
export const alphabetIds = [
|
||||
'A',
|
||||
@@ -65,6 +66,13 @@ export const timeRanges = {
|
||||
'1y': '1y',
|
||||
} as const;
|
||||
|
||||
export const metrics = {
|
||||
sum: 'sum',
|
||||
average: 'average',
|
||||
min: 'min',
|
||||
max: 'max',
|
||||
} as const;
|
||||
|
||||
export function isMinuteIntervalEnabledByRange(range: keyof typeof timeRanges) {
|
||||
return range === '30min' || range === '1h';
|
||||
}
|
||||
@@ -77,7 +85,9 @@ export function isHourIntervalEnabledByRange(range: keyof typeof timeRanges) {
|
||||
);
|
||||
}
|
||||
|
||||
export function getDefaultIntervalByRange(range: keyof typeof timeRanges) {
|
||||
export function getDefaultIntervalByRange(
|
||||
range: keyof typeof timeRanges
|
||||
): keyof typeof intervals {
|
||||
if (range === '30min' || range === '1h') {
|
||||
return 'minute';
|
||||
} else if (range === 'today' || range === '24h') {
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
import { isNumber } from 'mathjs';
|
||||
|
||||
export const round = (num: number, decimals = 2) => {
|
||||
const factor = Math.pow(10, decimals);
|
||||
return Math.round((num + Number.EPSILON) * factor) / factor;
|
||||
};
|
||||
|
||||
export const average = (arr: number[]) =>
|
||||
arr.reduce((p, c) => p + c, 0) / arr.length;
|
||||
export const average = (arr: (number | null)[]) => {
|
||||
const filtered = arr.filter(isNumber);
|
||||
return filtered.reduce((p, c) => p + c, 0) / filtered.length;
|
||||
};
|
||||
|
||||
export const sum = (arr: number[]) =>
|
||||
round(arr.reduce((acc, item) => acc + item, 0));
|
||||
export const sum = (arr: (number | null)[]): number =>
|
||||
round(arr.filter(isNumber).reduce((acc, item) => acc + item, 0));
|
||||
|
||||
export const min = (arr: (number | null)[]): number =>
|
||||
Math.min(...arr.filter(isNumber));
|
||||
|
||||
export const max = (arr: (number | null)[]): number =>
|
||||
Math.max(...arr.filter(isNumber));
|
||||
|
||||
export const isFloat = (n: number) => n % 1 !== 0;
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { anyPass, isEmpty, isNil, reject } from 'ramda';
|
||||
|
||||
export function toDots(
|
||||
obj: Record<string, unknown>,
|
||||
path = ''
|
||||
): Record<string, number | string | boolean> {
|
||||
return Object.entries(obj).reduce((acc, [key, value]) => {
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return {
|
||||
...acc,
|
||||
...toDots(value as Record<string, unknown>, `${path}${key}.`),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[`${path}${key}`]: value,
|
||||
};
|
||||
}, {});
|
||||
}
|
||||
|
||||
export const strip = reject(anyPass([isEmpty, isNil]));
|
||||
6
apps/web/src/utils/truncate.ts
Normal file
6
apps/web/src/utils/truncate.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export function truncate(str: string, len: number) {
|
||||
if (str.length <= len) {
|
||||
return str;
|
||||
}
|
||||
return str.slice(0, len) + '...';
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
chartTypes,
|
||||
intervals,
|
||||
lineTypes,
|
||||
metrics,
|
||||
operators,
|
||||
timeRanges,
|
||||
} from './constants';
|
||||
@@ -15,11 +16,21 @@ export function objectToZodEnums<K extends string>(
|
||||
return [firstKey!, ...otherKeys];
|
||||
}
|
||||
|
||||
export const mapKeys = objectToZodEnums;
|
||||
|
||||
export const zChartEvent = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
displayName: z.string().optional(),
|
||||
segment: z.enum(['event', 'user', 'user_average', 'one_event_per_user']),
|
||||
property: z.string().optional(),
|
||||
segment: z.enum([
|
||||
'event',
|
||||
'user',
|
||||
'user_average',
|
||||
'one_event_per_user',
|
||||
'property_sum',
|
||||
'property_average',
|
||||
]),
|
||||
filters: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -43,6 +54,8 @@ export const zLineType = z.enum(objectToZodEnums(lineTypes));
|
||||
|
||||
export const zTimeInterval = z.enum(objectToZodEnums(intervals));
|
||||
|
||||
export const zMetric = z.enum(objectToZodEnums(metrics));
|
||||
|
||||
export const zChartInput = z.object({
|
||||
name: z.string(),
|
||||
chartType: zChartType,
|
||||
@@ -52,9 +65,11 @@ export const zChartInput = z.object({
|
||||
breakdowns: zChartBreakdowns,
|
||||
range: z.enum(objectToZodEnums(timeRanges)),
|
||||
previous: z.boolean(),
|
||||
});
|
||||
|
||||
export const zChartInputWithDates = zChartInput.extend({
|
||||
formula: z.string().optional(),
|
||||
metric: zMetric,
|
||||
unit: z.string().optional(),
|
||||
previousIndicatorInverted: z.boolean().optional(),
|
||||
projectId: z.string(),
|
||||
startDate: z.string().nullish(),
|
||||
endDate: z.string().nullable(),
|
||||
endDate: z.string().nullish(),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user