Skip to content

Commit 796193d

Browse files
committed
feat: add available filters endpoint
1 parent 66caf8f commit 796193d

7 files changed

Lines changed: 127 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { type AvailableFiltersRequestDto, type AvailableFiltersResponseDto } from 'marble-api';
2+
import * as R from 'remeda';
3+
4+
export type AvailableFilterType = 'string' | 'number' | 'boolean';
5+
export type FiltersTypes = 'triggerObject';
6+
7+
export type AvailableFiltersRequest = {
8+
scenarioId: string;
9+
start: string;
10+
end: string;
11+
};
12+
13+
export type AvailableFiltersResponse = {
14+
name: string;
15+
type: AvailableFilterType;
16+
source: FiltersTypes;
17+
}[];
18+
19+
export const adaptAvailableFiltersResponse = (
20+
response: AvailableFiltersResponseDto,
21+
): AvailableFiltersResponse => {
22+
return response.map((item) => ({
23+
name: item.name,
24+
type: item.type as AvailableFilterType,
25+
source: R.toCamelCase(item.source) as FiltersTypes,
26+
}));
27+
};
28+
29+
export const transformAvailableFiltersRequest = (
30+
request: AvailableFiltersRequest,
31+
): AvailableFiltersRequestDto => {
32+
return {
33+
scenario_id: request.scenarioId,
34+
start: request.start,
35+
end: request.end,
36+
};
37+
};

packages/app-builder/src/models/analytics/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './available-filters';
12
export * from './decisions-outcomes-perday';
23
export * as legacyAnalytics from './legacy-analytics';
34

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { useAgnosticNavigation } from '@app-builder/contexts/AgnosticNavigationContext';
2+
import { AvailableFiltersResponse } from '@app-builder/models/analytics/available-filters';
3+
import { getRoute } from '@app-builder/utils/routes';
4+
import { useQuery } from '@tanstack/react-query';
5+
6+
export const useGetAvailableFilters = ({
7+
scenarioId,
8+
dateRange,
9+
}: {
10+
scenarioId: string;
11+
dateRange: { start: string; end: string };
12+
}) => {
13+
const navigate = useAgnosticNavigation();
14+
15+
const endpoint = getRoute('/ressources/analytics/available_filters/:scenarioId', {
16+
scenarioId,
17+
});
18+
return useQuery({
19+
queryKey: ['analytics', 'available-filters', scenarioId, dateRange],
20+
queryFn: async () => {
21+
const response = await fetch(endpoint, {
22+
method: 'POST',
23+
headers: {
24+
'Content-Type': 'application/json',
25+
},
26+
body: JSON.stringify({ scenarioId, start: dateRange.start, end: dateRange.end }),
27+
});
28+
const result = await response.json();
29+
if (result.redirectTo) {
30+
navigate(result.redirectTo);
31+
return;
32+
}
33+
34+
return result as Promise<AvailableFiltersResponse>;
35+
},
36+
});
37+
};

packages/app-builder/src/repositories/AnalyticsRepository.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import {
99
mergeDateRanges,
1010
transformDecisionOutcomesPerDayQuery,
1111
} from '@app-builder/models/analytics';
12+
import {
13+
type AvailableFiltersRequest,
14+
type AvailableFiltersResponse,
15+
adaptAvailableFiltersResponse,
16+
transformAvailableFiltersRequest,
17+
} from '@app-builder/models/analytics/available-filters';
1218

1319
import { compareAsc, compareDesc, differenceInDays } from 'date-fns';
1420

@@ -17,6 +23,7 @@ export interface AnalyticsRepository {
1723
getDecisionOutcomesPerDay(
1824
args: DecisionOutcomesPerDayQuery,
1925
): Promise<DecisionOutcomesPerPeriod | null>;
26+
getAvailableFilters(args: AvailableFiltersRequest): Promise<AvailableFiltersResponse>;
2027
}
2128

2229
export function makeGetAnalyticsRepository() {
@@ -85,5 +92,13 @@ export function makeGetAnalyticsRepository() {
8592
return null;
8693
}
8794
},
95+
96+
getAvailableFilters: async (
97+
args: AvailableFiltersRequest,
98+
): Promise<AvailableFiltersResponse> => {
99+
return client
100+
.getAvailableFilters(transformAvailableFiltersRequest(args))
101+
.then((response) => adaptAvailableFiltersResponse(response));
102+
},
88103
});
89104
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { initServerServices } from '@app-builder/services/init.server';
2+
import { getRoute } from '@app-builder/utils/routes';
3+
import { ActionFunctionArgs } from '@remix-run/node';
4+
import { z } from 'zod/v4';
5+
6+
const urlParamsSchema = z.object({
7+
scenarioId: z.uuidv4(),
8+
});
9+
10+
const queryParamsSchema = z.object({
11+
start: z.iso.datetime(),
12+
end: z.iso.datetime(),
13+
});
14+
15+
export async function action({ request, params }: ActionFunctionArgs) {
16+
const { authService } = initServerServices(request);
17+
const { analytics } = await authService.isAuthenticated(request, {
18+
failureRedirect: getRoute('/sign-in'),
19+
});
20+
21+
const urlParams = urlParamsSchema.parse(params);
22+
const queryParams = queryParamsSchema.parse(await request.json());
23+
24+
const query = await analytics.getAvailableFilters({
25+
scenarioId: urlParams.scenarioId,
26+
start: queryParams.start,
27+
end: queryParams.end,
28+
});
29+
return Response.json(query);
30+
}

packages/app-builder/src/utils/routes/routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ export const routes = [
370370
"path": "healthcheck",
371371
"file": "routes/healthcheck.ts"
372372
},
373+
{
374+
"id": "routes/ressources+/analytics+/available_filters.$scenarioId",
375+
"path": "ressources/analytics/available_filters/:scenarioId",
376+
"file": "routes/ressources+/analytics+/available_filters.$scenarioId.ts"
377+
},
373378
{
374379
"id": "routes/ressources+/analytics+/decisions_outcomes_per_day.$scenarioId",
375380
"path": "ressources/analytics/decisions_outcomes_per_day/:scenarioId",

packages/app-builder/src/utils/routes/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export type RoutePath =
5353
| '/upload/:objectType'
5454
| '/app-router'
5555
| '/healthcheck'
56+
| '/ressources/analytics/available_filters/:scenarioId'
5657
| '/ressources/analytics/decisions_outcomes_per_day/:scenarioId'
5758
| '/ressources/analytics/query/:queryName'
5859
| '/ressources/annotations/download-file/:annotationId/:fileId'
@@ -246,6 +247,7 @@ export type RouteID =
246247
| 'routes/_index'
247248
| 'routes/app-router'
248249
| 'routes/healthcheck'
250+
| 'routes/ressources+/analytics+/available_filters.$scenarioId'
249251
| 'routes/ressources+/analytics+/decisions_outcomes_per_day.$scenarioId'
250252
| 'routes/ressources+/analytics+/query.$queryName'
251253
| 'routes/ressources+/annotations+/download-file.$annotationId.$fileId'

0 commit comments

Comments
 (0)