Skip to content

Commit 0a734e2

Browse files
feat: add contextual filtering
Co-authored-by: Antoine Hurard <[email protected]>
1 parent f04b61f commit 0a734e2

File tree

5 files changed

+41
-3
lines changed

5 files changed

+41
-3
lines changed

src/models/layer.model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export interface Layer extends Document {
119119
opacity: number;
120120
layerDefinition?: LayerDefinition;
121121
popupInfo?: PopupElement[];
122+
contextFilters: string;
122123
}
123124

124125
/** Mongoose layer schema declaration */
@@ -170,6 +171,7 @@ const layerSchema = new Schema(
170171
enum: Object.values(GeometryType),
171172
},
172173
},
174+
contextFilters: String,
173175
},
174176
{
175177
timestamps: { createdAt: 'createdAt', updatedAt: 'modifiedAt' },

src/routes/gis/index.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ router.get('/feature', async (req, res) => {
154154
const longitudeField = get(req, 'query.longitudeField');
155155
const geoField = get(req, 'query.geoField');
156156
const layerType = get(req, 'query.type', GeometryType.POINT);
157+
const contextFilters = JSON.parse(
158+
decodeURIComponent(get(req, 'query.contextFilters', null))
159+
);
157160
// const tolerance = get(req, 'query.tolerance', 1);
158161
// const highQuality = get(req, 'query.highquality', true);
159162
// turf.simplify(geoJsonData, {
@@ -225,17 +228,23 @@ router.get('/feature', async (req, res) => {
225228
// const filterPolygon = getFilterPolygon(req.query);
226229

227230
if (aggregation) {
228-
query = `query recordsAggregation($resource: ID!, $aggregation: ID!) {
229-
recordsAggregation(resource: $resource, aggregation: $aggregation)
231+
query = `query recordsAggregation($resource: ID!, $aggregation: ID!, $contextFilters: JSON) {
232+
recordsAggregation(resource: $resource, aggregation: $aggregation, contextFilters: $contextFilters)
230233
}`;
231234
variables = {
232235
resource: resourceData._id,
233236
aggregation: aggregation._id,
237+
contextFilters,
234238
};
235239
} else if (layout) {
236240
query = buildQuery(layout.query);
237241
variables = {
238-
filter: layout.query.filter,
242+
filter: {
243+
logic: 'and',
244+
filters: contextFilters
245+
? [layout.query.filter, contextFilters]
246+
: [layout.query.filter],
247+
},
239248
};
240249
} else {
241250
return res.status(404).send(i18next.t('common.errors.dataNotFound'));

src/schema/inputs/layer.input.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ const LayerInputType = new GraphQLInputObjectType({
154154
}),
155155
},
156156
datasource: { type: LayerDataSourceInputType },
157+
contextFilters: { type: GraphQLString },
157158
}),
158159
});
159160

src/schema/query/recordsAggregation.query.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ const CREATED_BY_STAGES = [
3939
},
4040
];
4141

42+
/**
43+
* Extracts the source fields from a filter
44+
*
45+
* @param filter the filter to extract the source fields from
46+
* @param fields the fields to add the source fields to
47+
*/
48+
const extractSourceFields = (filter: any, fields: string[] = []) => {
49+
if (filter.filters) {
50+
filter.filters.forEach((f) => {
51+
extractSourceFields(f, fields);
52+
});
53+
} else if (filter.field) {
54+
if (typeof filter.field === 'string' && !fields.includes(filter.field))
55+
fields.push(filter.field);
56+
}
57+
};
58+
4259
/**
4360
* Take an aggregation configuration as parameter.
4461
* Return aggregated records data.
@@ -48,6 +65,7 @@ export default {
4865
args: {
4966
resource: { type: new GraphQLNonNull(GraphQLID) },
5067
aggregation: { type: new GraphQLNonNull(GraphQLID) },
68+
contextFilters: { type: GraphQLJSON },
5169
mapping: { type: GraphQLJSON },
5270
first: { type: GraphQLInt },
5371
skip: { type: GraphQLInt },
@@ -92,6 +110,13 @@ export default {
92110

93111
const refDataNameMap: Record<string, string> = {};
94112
if (aggregation?.sourceFields && aggregation.pipeline) {
113+
if (args.contextFilters) {
114+
extractSourceFields(args.contextFilters, aggregation.sourceFields);
115+
aggregation.pipeline.unshift({
116+
type: 'filter',
117+
form: args.contextFilters,
118+
});
119+
}
95120
// Go through the aggregation source fields to update possible refData field names
96121
for (const field of aggregation.sourceFields) {
97122
// find field in resource fields

src/schema/types/layer.type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ export const LayerType = new GraphQLObjectType({
171171
modifiedAt: { type: GraphQLString },
172172
layerType: { type: LayerTypeEnum },
173173
datasource: { type: LayerDatasource },
174+
contextFilters: { type: GraphQLString },
174175
}),
175176
});
176177

0 commit comments

Comments
 (0)