diff --git a/frontend/src/components/FiltersForm/FiltersForm.jsx b/frontend/src/components/FiltersForm/FiltersForm.jsx
index c4124ee2..89afb7ca 100644
--- a/frontend/src/components/FiltersForm/FiltersForm.jsx
+++ b/frontend/src/components/FiltersForm/FiltersForm.jsx
@@ -158,7 +158,7 @@ const LoadingSkeleton = () => (
);
export const FiltersForm = () => {
- const { setCategories } = useCategories();
+ const { categories: selectedFilters, setCategories } = useCategories();
const [categoriesData, setCategoriesData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
@@ -188,8 +188,11 @@ export const FiltersForm = () => {
useEffect(() => {
const fetchCategories = async () => {
setIsLoading(true);
- const categoriesData = await httpService.getCategoriesData();
- setCategoriesData(categoriesData);
+ const { categories, defaultChecked } = await httpService.getCategoriesData();
+ setCategoriesData(categories);
+ if (Object.keys(defaultChecked).length > 0) {
+ setCategories(defaultChecked);
+ }
setIsLoading(false);
};
fetchCategories();
@@ -208,6 +211,7 @@ export const FiltersForm = () => {
type="checkbox"
id={name}
value={name}
+ checked={Boolean(selectedFilters[category]?.includes(name))}
/>
{translation}
{tooltipData && (
diff --git a/frontend/src/services/http/httpService.js b/frontend/src/services/http/httpService.js
index 678a90c5..93a0c97c 100644
--- a/frontend/src/services/http/httpService.js
+++ b/frontend/src/services/http/httpService.js
@@ -47,13 +47,15 @@ export const httpService = {
* Fetches complete categories data including subcategories in a single request.
* Uses the /api/categories-full endpoint to avoid waterfall requests.
*
- * @returns {Promise} Promise resolving to array of category data tuples
+ * @returns {Promise<{categories: Array, defaultChecked: Object}>} Promise resolving to
+ * the array of category data tuples plus a map of category key to the option values
+ * that should be pre-checked by default.
*/
getCategoriesData: async () => {
const response = await fetch(CATEGORIES_FULL).then(res => res.json());
// Transform to expected format: [[key, name], options, help?, optionsHelp?]
- return response.categories.map(category => {
+ const categories = response.categories.map(category => {
const categoryTuple = [category.key, category.name];
const options = category.options;
@@ -67,6 +69,15 @@ export const httpService = {
}
return [categoryTuple, options];
});
+
+ const defaultChecked = {};
+ for (const category of response.categories) {
+ if (category.default_checked?.length) {
+ defaultChecked[category.key] = category.default_checked;
+ }
+ }
+
+ return { categories, defaultChecked };
},
/**
diff --git a/frontend/tests/FiltersForm.test.jsx b/frontend/tests/FiltersForm.test.jsx
index cc4c2261..d97d390c 100644
--- a/frontend/tests/FiltersForm.test.jsx
+++ b/frontend/tests/FiltersForm.test.jsx
@@ -19,7 +19,7 @@ const categories = [
],
];
-httpService.getCategoriesData.mockResolvedValue(categories);
+httpService.getCategoriesData.mockResolvedValue({ categories, defaultChecked: {} });
describe('Creates good filter_form box', () => {
beforeAll(() => {
@@ -90,3 +90,29 @@ describe('Creates good filter_form box', () => {
expect(queryByLabelText(/Help: Inaczej rodzaje/i)).toBeInTheDocument();
});
});
+
+describe('Pre-checks options configured as default-checked', () => {
+ beforeEach(() => {
+ httpService.getCategoriesData.mockResolvedValueOnce({
+ categories,
+ defaultChecked: { types: ['shoes'] },
+ });
+ return act(() =>
+ render(
+
+
+ ,
+ ),
+ );
+ });
+
+ it('renders the default-checked option as checked', () => {
+ const shoesCheckbox = document.querySelector('#shoes');
+ expect(shoesCheckbox.checked).toBe(true);
+ });
+
+ it('leaves options not listed as default-checked unchecked', () => {
+ const clothesCheckbox = document.querySelector('#clothes');
+ expect(clothesCheckbox.checked).toBe(false);
+ });
+});
diff --git a/goodmap/core_api.py b/goodmap/core_api.py
index 2def128f..47b7fce0 100644
--- a/goodmap/core_api.py
+++ b/goodmap/core_api.py
@@ -440,12 +440,14 @@ def get_categories_full():
result = []
categories_options_help = categories_data.get("categories_options_help", {})
+ categories_default_checked = categories_data.get("categories_default_checked", {})
for key, options in categories_data["categories"].items():
category_entry = {
"key": key,
"name": gettext(key),
"options": make_tuple_translation(options),
+ "default_checked": categories_default_checked.get(key, []),
}
if CategoriesHelp in feature_flags:
diff --git a/goodmap/db.py b/goodmap/db.py
index 91aec3c5..3b745381 100644
--- a/goodmap/db.py
+++ b/goodmap/db.py
@@ -608,11 +608,17 @@ def json_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: self.data.get("categories_options_help", {}).get(category_type, [])
},
+ "categories_default_checked": {
+ category_type: self.data.get("categories_default_checked", {}).get(
+ category_type, []
+ )
+ },
}
return {
"categories": self.data["categories"],
"categories_help": self.data.get("categories_help", []),
"categories_options_help": self.data.get("categories_options_help", {}),
+ "categories_default_checked": self.data.get("categories_default_checked", {}),
}
@@ -627,11 +633,15 @@ def json_file_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: data.get("categories_options_help", {}).get(category_type, [])
},
+ "categories_default_checked": {
+ category_type: data.get("categories_default_checked", {}).get(category_type, [])
+ },
}
return {
"categories": data["categories"],
"categories_help": data.get("categories_help", []),
"categories_options_help": data.get("categories_options_help", {}),
+ "categories_default_checked": data.get("categories_default_checked", {}),
}
@@ -645,11 +655,15 @@ def google_json_db_get_category_data(self, category_type=None):
"categories_options_help": {
category_type: data.get("categories_options_help", {}).get(category_type, [])
},
+ "categories_default_checked": {
+ category_type: data.get("categories_default_checked", {}).get(category_type, [])
+ },
}
return {
"categories": data.get("categories", {}),
"categories_help": data.get("categories_help", []),
"categories_options_help": data.get("categories_options_help", {}),
+ "categories_default_checked": data.get("categories_default_checked", {}),
}
@@ -668,13 +682,24 @@ def mongodb_db_get_category_data(self, category_type=None):
category_type, []
)
},
+ "categories_default_checked": {
+ category_type: config_doc.get("categories_default_checked", {}).get(
+ category_type, []
+ )
+ },
}
return {
"categories": config_doc.get("categories", {}),
"categories_help": config_doc.get("categories_help", []),
"categories_options_help": config_doc.get("categories_options_help", {}),
+ "categories_default_checked": config_doc.get("categories_default_checked", {}),
}
- return {"categories": {}, "categories_help": [], "categories_options_help": {}}
+ return {
+ "categories": {},
+ "categories_help": [],
+ "categories_options_help": {},
+ "categories_default_checked": {},
+ }
def get_category_data(db):
diff --git a/tests/unit_tests/test_core_api.py b/tests/unit_tests/test_core_api.py
index a613ccd5..75da7aed 100644
--- a/tests/unit_tests/test_core_api.py
+++ b/tests/unit_tests/test_core_api.py
@@ -170,6 +170,42 @@ def test_categories_full_endpoint(test_app):
assert category["options"][0] == ["test", "test-translated"]
assert category["options"][1] == ["test2", "test2-translated"]
+ # No default-checked options configured for this category
+ assert category["default_checked"] == []
+
+
+@mock.patch("goodmap.core_api.gettext", fake_translation)
+def test_categories_full_endpoint_with_default_checked():
+ test_app = create_test_app(
+ db_overrides={
+ "categories": {"test-category": ["opt1", "opt2"]},
+ "categories_default_checked": {"test-category": ["opt1"]},
+ }
+ )
+ response = test_app.get("/api/categories-full")
+ assert response.status_code == 200
+ data = response.json
+ assert data is not None
+
+ category = data["categories"][0]
+ assert category["default_checked"] == ["opt1"]
+
+
+@mock.patch("goodmap.core_api.gettext", fake_translation)
+def test_categories_full_endpoint_without_default_checked():
+ test_app = create_test_app(
+ db_overrides={
+ "categories": {"test-category": ["opt1", "opt2"]},
+ }
+ )
+ response = test_app.get("/api/categories-full")
+ assert response.status_code == 200
+ data = response.json
+ assert data is not None
+
+ category = data["categories"][0]
+ assert category["default_checked"] == []
+
@mock.patch("goodmap.core_api.gettext", fake_translation)
def test_categories_full_endpoint_with_multiple_categories():
diff --git a/tests/unit_tests/test_db.py b/tests/unit_tests/test_db.py
index 893e53d9..6243166d 100644
--- a/tests/unit_tests/test_db.py
+++ b/tests/unit_tests/test_db.py
@@ -112,6 +112,7 @@
"location_obligatory_fields": [["name", "str"]],
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
data_json = json.dumps({"map": data})
@@ -1422,6 +1423,7 @@ def test_json_db_get_category_data():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1434,6 +1436,7 @@ def test_json_db_get_category_data_specific_category():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1449,6 +1452,7 @@ def test_json_file_db_get_category_data(tmp_path):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1464,6 +1468,7 @@ def test_json_file_db_get_category_data_specific_category(tmp_path):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1480,6 +1485,7 @@ def test_google_json_db_get_category_data(mock_cli):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1496,6 +1502,7 @@ def test_google_json_db_get_category_data_specific_category(mock_cli):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1509,6 +1516,7 @@ def test_mongodb_db_get_category_data(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
db = MongoDB("mongodb://localhost:27017", "test_db")
@@ -1518,6 +1526,7 @@ def test_mongodb_db_get_category_data(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1531,6 +1540,7 @@ def test_mongodb_db_get_category_data_specific_category(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
db = MongoDB("mongodb://localhost:27017", "test_db")
@@ -1540,6 +1550,7 @@ def test_mongodb_db_get_category_data_specific_category(mock_client):
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected
@@ -1553,7 +1564,12 @@ def test_mongodb_db_get_category_data_no_config(mock_client):
db = MongoDB("mongodb://localhost:27017", "test_db")
extend_db_with_goodmap_queries(db, LocationBase)
category_data = mongodb_db_get_category_data(db)
- expected = {"categories": {}, "categories_help": [], "categories_options_help": {}}
+ expected = {
+ "categories": {},
+ "categories_help": [],
+ "categories_options_help": {},
+ "categories_default_checked": {},
+ }
assert category_data == expected
@@ -1565,6 +1581,7 @@ def test_get_category_data():
"categories": {"test-category": ["searchable", "unsearchable"]},
"categories_help": ["Help text for categories"],
"categories_options_help": {"test-category": ["Help for test category"]},
+ "categories_default_checked": {"test-category": ["searchable"]},
}
assert category_data == expected