From f6c22345b65f505d76804cb0b7cc1cabf8ec9f2f Mon Sep 17 00:00:00 2001 From: subinasr Date: Fri, 26 Jun 2026 11:51:14 +0545 Subject: [PATCH 1/2] fix(gallery): file size limit and user information in query --- apps/content/serializers.py | 5 +++++ apps/gallery/graphql/types.py | 3 ++- apps/gallery/serializers.py | 6 ++++++ apps/gallery/tests/queries_test.py | 2 +- apps/reports/serializers.py | 9 +++++++++ schema.graphql | 2 +- utils/validators.py | 17 +++++++++++++++++ 7 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 utils/validators.py diff --git a/apps/content/serializers.py b/apps/content/serializers.py index 1f7a042..6c94d28 100644 --- a/apps/content/serializers.py +++ b/apps/content/serializers.py @@ -1,8 +1,10 @@ import typing +from django.core.files import File from rest_framework import serializers from apps.reports.models import Report, ReportVisibility +from utils.validators import validate_image_size from .models import NewsPost, NewsPostReport @@ -23,6 +25,9 @@ class Meta: "author": {"required": False}, } + def validate_cover_image(self, value: File) -> File: + return validate_image_size(value) + @typing.override def create(self, validated_data: dict) -> NewsPost: request = self.context.get("request") diff --git a/apps/gallery/graphql/types.py b/apps/gallery/graphql/types.py index b1e9534..14c8eb9 100644 --- a/apps/gallery/graphql/types.py +++ b/apps/gallery/graphql/types.py @@ -3,6 +3,7 @@ from asgiref.sync import sync_to_async from apps.gallery.models import GalleryAlbum, GalleryImage +from apps.users.graphql.types import UserType from utils.graphql.types import DjangoFileType @@ -22,7 +23,7 @@ class GalleryAlbumType: title: strawberry.auto description: strawberry.auto cover_image: GalleryImageType | None - created_by_id: strawberry.ID + created_by: UserType created_at: strawberry.auto updated_at: strawberry.auto diff --git a/apps/gallery/serializers.py b/apps/gallery/serializers.py index 3d03e19..057f5dd 100644 --- a/apps/gallery/serializers.py +++ b/apps/gallery/serializers.py @@ -1,7 +1,10 @@ import typing +from django.core.files import File from rest_framework import serializers +from utils.validators import validate_image_size + from .models import GalleryAlbum, GalleryImage @@ -31,3 +34,6 @@ class GalleryImageSerializer(serializers.ModelSerializer): class Meta: model = GalleryImage fields = ["album", "image", "caption", "order"] + + def validate_image(self, value: File) -> File: + return validate_image_size(value) diff --git a/apps/gallery/tests/queries_test.py b/apps/gallery/tests/queries_test.py index afc448a..2bbf2ec 100644 --- a/apps/gallery/tests/queries_test.py +++ b/apps/gallery/tests/queries_test.py @@ -16,7 +16,7 @@ class Query: id title description - createdById + createdBy { id email fullName } createdAt } } diff --git a/apps/reports/serializers.py b/apps/reports/serializers.py index 9eccc29..16a9714 100644 --- a/apps/reports/serializers.py +++ b/apps/reports/serializers.py @@ -1,7 +1,10 @@ import typing +from django.core.files import File from rest_framework import serializers +from utils.validators import validate_image_size, validate_report_file_size + from .models import Link, Report, ReportContentType, ReportVisibility, ThematicArea @@ -40,6 +43,12 @@ class Meta: "uploaded_by": {"required": False}, } + def validate_cover_image(self, value: File) -> File: + return validate_image_size(value) + + def validate_file(self, value: File) -> File: + return validate_report_file_size(value) + def validate_visibility(self, value: int) -> int: if self.instance and self.instance.visibility == ReportVisibility.PRIVATE and value == ReportVisibility.PUBLIC: raise serializers.ValidationError("Cannot change visibility from PRIVATE to PUBLIC.") diff --git a/schema.graphql b/schema.graphql index 66b6861..7d400de 100644 --- a/schema.graphql +++ b/schema.graphql @@ -505,7 +505,7 @@ type GalleryAlbumType { title: String! description: String coverImage: GalleryImageType - createdById: ID! + createdBy: UserType! createdAt: DateTime! updatedAt: DateTime! imagesCount: Int! diff --git a/utils/validators.py b/utils/validators.py new file mode 100644 index 0000000..21727af --- /dev/null +++ b/utils/validators.py @@ -0,0 +1,17 @@ +from django.core.files import File +from rest_framework import serializers + +MAX_IMAGE_SIZE = 2 * 1024 * 1024 # 2 MB +MAX_REPORT_FILE_SIZE = 5 * 1024 * 1024 # 5 MB + + +def validate_image_size[F: File | None](value: F) -> F: + if value is not None and value.size > MAX_IMAGE_SIZE: + raise serializers.ValidationError("Image size must not exceed 2 MB.") + return value + + +def validate_report_file_size[F: File | None](value: F) -> F: + if value is not None and value.size > MAX_REPORT_FILE_SIZE: + raise serializers.ValidationError("File size must not exceed 5 MB.") + return value From b294ccfc45c52e78a8b160927f08aeb78532c775 Mon Sep 17 00:00:00 2001 From: sudip-khanal Date: Wed, 1 Jul 2026 10:56:19 +0545 Subject: [PATCH 2/2] feat(seed-data): update seed data --- apps/dashboards/serializers.py | 11 +- apps/dashboards/tests/mutations_test.py | 9 +- seed_data/db.json | 341 ++++++++++++------------ 3 files changed, 176 insertions(+), 185 deletions(-) diff --git a/apps/dashboards/serializers.py b/apps/dashboards/serializers.py index b80607f..1e6c0a2 100644 --- a/apps/dashboards/serializers.py +++ b/apps/dashboards/serializers.py @@ -40,12 +40,11 @@ def validate(self, data: dict) -> dict: # type: ignore[reportIncompatibleMethod is_active = data.get("is_active", instance.is_active if instance else True) show_on_home = data.get("show_on_home", instance.show_on_home if instance else False) - if show_on_home and not is_active: - raise serializers.ValidationError( - { - "non_field_errors": "A dashboard must be active to be shown on the home page.", - }, - ) + # NOTE: This is intentional. If a dashboard is marked inactive, we automatically + # remove it from the home page to keep it consistent with the frontend + # "Show on Home" logic. + if not is_active and show_on_home: + data["show_on_home"] = False # Home dashboard limit validation if show_on_home: diff --git a/apps/dashboards/tests/mutations_test.py b/apps/dashboards/tests/mutations_test.py index cbca88e..775222b 100644 --- a/apps/dashboards/tests/mutations_test.py +++ b/apps/dashboards/tests/mutations_test.py @@ -71,6 +71,7 @@ class Mutation: title isActive capacityAndResourceId + showOnHome } } } @@ -186,8 +187,7 @@ def test_create_dashboard_show_on_home_requires_active(self): }, ) resp = content["data"]["createExternalDashboard"] - assert resp["ok"] is False - assert resp["errors"] is not None + assert resp["ok"] is True def test_update_dashboard_deactivate_while_show_on_home(self): self.force_login(self.staff) @@ -197,8 +197,9 @@ def test_update_dashboard_deactivate_while_show_on_home(self): variables={"id": str(dashboard.pk), "data": {"isActive": False}}, ) resp = content["data"]["updateExternalDashboard"] - assert resp["ok"] is False - assert resp["errors"] is not None + assert resp["ok"] is True + assert resp["result"]["isActive"] is False + assert resp["result"]["showOnHome"] is False def test_viewer_cannot_create(self): self.force_login(self.viewer) diff --git a/seed_data/db.json b/seed_data/db.json index 1c2ef44..fc8b599 100644 --- a/seed_data/db.json +++ b/seed_data/db.json @@ -16,6 +16,118 @@ "created_at": "2026-05-12T11:02:36.572Z" } }, +{ + "model": "dashboards.capacityandresource", + "pk": "a1378004-7892-4d5b-b9a5-304cc7a2dbd6", + "fields": { + "created_at": "2026-05-15T04:42:31.563Z", + "updated_at": "2026-05-15T04:44:50.175Z", + "title": "Ethiopia Drug Store and Pharmacy", + "description": "Monitor and allocate capacity and resources effectively to support humanitarian operations and response efforts.", + "region": null, + "is_active": true, + "order": 1, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "25417636-5508-4b1d-9197-524c8a7817f3", + "fields": { + "created_at": "2026-05-15T04:45:09.319Z", + "updated_at": "2026-05-15T04:54:58.248Z", + "title": "Emergency Medical Service", + "description": "Monitor, coordinate, and manage emergency medical service operations and response activities.", + "region": null, + "is_active": true, + "order": 2, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "0339969d-a96f-4c1a-939d-cf03d42646a9", + "fields": { + "created_at": "2026-05-15T04:45:51.070Z", + "updated_at": "2026-05-15T04:55:06.866Z", + "title": "ERCS Fleet Tracking", + "description": "Track, monitor, and manage fleet movement, vehicle usage, and transportation efficiency in real time.", + "region": null, + "is_active": true, + "order": 3, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "eac83bc9-a29d-4f96-9a04-9abe0402f89b", + "fields": { + "created_at": "2026-05-15T04:46:20.391Z", + "updated_at": "2026-05-15T04:55:17.395Z", + "title": "Landholdings", + "description": "Maintain, organize, and monitor records of organizational land assets and property details.", + "region": null, + "is_active": true, + "order": 4, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "92f9ff2d-5c0d-4377-88d8-40ab0fe12309", + "fields": { + "created_at": "2026-05-15T04:46:43.083Z", + "updated_at": "2026-05-15T04:55:26.400Z", + "title": "Membership and Volunteer", + "description": "Manage member and volunteer profiles, engagement, and participation across programs and activities.", + "region": null, + "is_active": true, + "order": 5, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "1fa60c54-dbb6-4acf-8f85-0573d25f9dd3", + "fields": { + "created_at": "2026-05-15T04:47:04.204Z", + "updated_at": "2026-05-15T04:54:39.594Z", + "title": "Project Balance", + "description": "Track, review, and manage project budgets, expenses, and overall financial performance.", + "region": null, + "is_active": true, + "order": 6, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "b819a9b3-f4d2-4bd1-ba73-c2c504b0f7bf", + "fields": { + "created_at": "2026-05-15T04:47:52.551Z", + "updated_at": "2026-05-15T04:56:35.863Z", + "title": "Restoring Family Link (RFL)", + "description": "Support and manage processes for family tracing, reunification, and related humanitarian services.", + "region": null, + "is_active": true, + "order": 7, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, +{ + "model": "dashboards.capacityandresource", + "pk": "846652f5-3277-416f-ace9-bca7142c1a96", + "fields": { + "created_at": "2026-05-15T04:48:20.347Z", + "updated_at": "2026-05-15T04:48:20.347Z", + "title": "Hospitals", + "description": "View, update, and manage hospital information, resources, and service availability across regions.", + "region": null, + "is_active": true, + "order": 8, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, { "model": "dashboards.externaldashboard", "pk": "a3728d9b-8421-4c83-8db4-73c4df0c242b", @@ -27,6 +139,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiMzQzYjk3M2EtZDQwMS00YzIyLWFlYjYtMTBkNmFhZWUxZTA0IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 30, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 1, "is_active": true, @@ -44,6 +157,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiMzQzYjk3M2EtZDQwMS00YzIyLWFlYjYtMTBkNmFhZWUxZTA0IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 30, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 2, "is_active": true, @@ -61,12 +175,31 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZjFmNjczOTItNjU1Yy00ODE3LWI0NmUtZWQzNzgwZWY3OWE5IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "a1378004-7892-4d5b-b9a5-304cc7a2dbd6", "show_on_home": false, "order": 1, "is_active": true, "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" } }, +{ + "model": "dashboards.externaldashboard", + "pk": "8e848a27-b8fb-4572-8dc4-6fffb9f83fdf", + "fields": { + "created_at": "2026-05-15T04:40:41.672Z", + "updated_at": "2026-05-15T04:40:41.672Z", + "title": "EDP-2", + "description": "", + "url": "https://app.powerbi.com/view?r=eyJrIjoiZDk1ZmU0OTgtOTc4Zi00OGY1LWFiN2EtOTRjZDYxY2VlZWI4IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", + "page": 40, + "region": null, + "capacity_and_resource": "a1378004-7892-4d5b-b9a5-304cc7a2dbd6", + "show_on_home": false, + "order": 2, + "is_active": true, + "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" + } +}, { "model": "dashboards.externaldashboard", "pk": "5ac17c60-fdd3-4784-b665-f322399da438", @@ -78,6 +211,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZThiZWVlZmMtNzk1OS00N2IwLWJjNWMtZmY2ZjgyM2RkZjcxIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "25417636-5508-4b1d-9197-524c8a7817f3", "show_on_home": false, "order": 1, "is_active": true, @@ -86,17 +220,18 @@ }, { "model": "dashboards.externaldashboard", - "pk": "fdbf10f4-4582-4347-9b51-f4345b03fd81", + "pk": "16c4ba29-d8e3-4053-abf5-6a32b998aad7", "fields": { - "created_at": "2026-05-15T04:56:16.606Z", - "updated_at": "2026-05-15T04:56:16.606Z", - "title": "RFL", + "created_at": "2026-05-15T04:51:13.468Z", + "updated_at": "2026-05-15T04:51:13.468Z", + "title": "EMS-2", "description": "", - "url": "https://app.powerbi.com/view?r=eyJrIjoiZTViYjIwMmEtZWJmYy00MWJiLTg0NTYtMmU2YzQ1MjVlNjM5IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", + "url": "https://app.powerbi.com/view?r=eyJrIjoiZTFmMjZmN2ItMmJhZC00ZTU2LWJlY2UtYzdjOGUzZjdlZmY5IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "25417636-5508-4b1d-9197-524c8a7817f3", "show_on_home": false, - "order": 1, + "order": 2, "is_active": true, "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" } @@ -112,6 +247,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiMDg4ZmU5NjItZjFmNS00NTllLThmMzAtZDlmNWE0MTAyZjRiIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9&cacheUpdate=1778820678655", "page": 40, "region": null, + "capacity_and_resource": "0339969d-a96f-4c1a-939d-cf03d42646a9", "show_on_home": false, "order": 1, "is_active": true, @@ -129,6 +265,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZGJjNTEwODQtNDMzYy00NDAwLTg2YWItMDlhMDQ0NTRhNWYyIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "92f9ff2d-5c0d-4377-88d8-40ab0fe12309", "show_on_home": false, "order": 1, "is_active": true, @@ -146,6 +283,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZGE0ZGY5ZWUtNzFkMS00NGRhLTg0MmEtZmM4ZTEwYzcxMjIyIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "eac83bc9-a29d-4f96-9a04-9abe0402f89b", "show_on_home": false, "order": 1, "is_active": true, @@ -163,6 +301,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiNTQ5MDRjZmQtZDUxZi00MTgxLWI0M2MtNzhhNTI1OTJmMTRkIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9&pageName=ReportSection", "page": 40, "region": null, + "capacity_and_resource": "1fa60c54-dbb6-4acf-8f85-0573d25f9dd3", "show_on_home": false, "order": 1, "is_active": true, @@ -171,34 +310,18 @@ }, { "model": "dashboards.externaldashboard", - "pk": "16c4ba29-d8e3-4053-abf5-6a32b998aad7", - "fields": { - "created_at": "2026-05-15T04:51:13.468Z", - "updated_at": "2026-05-15T04:51:13.468Z", - "title": "EMS-2", - "description": "", - "url": "https://app.powerbi.com/view?r=eyJrIjoiZTFmMjZmN2ItMmJhZC00ZTU2LWJlY2UtYzdjOGUzZjdlZmY5IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", - "page": 40, - "region": null, - "show_on_home": false, - "order": 2, - "is_active": true, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" - } -}, -{ - "model": "dashboards.externaldashboard", - "pk": "8e848a27-b8fb-4572-8dc4-6fffb9f83fdf", + "pk": "fdbf10f4-4582-4347-9b51-f4345b03fd81", "fields": { - "created_at": "2026-05-15T04:40:41.672Z", - "updated_at": "2026-05-15T04:40:41.672Z", - "title": "EDP-2", + "created_at": "2026-05-15T04:56:16.606Z", + "updated_at": "2026-05-15T04:56:16.606Z", + "title": "RFL", "description": "", - "url": "https://app.powerbi.com/view?r=eyJrIjoiZDk1ZmU0OTgtOTc4Zi00OGY1LWFiN2EtOTRjZDYxY2VlZWI4IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", + "url": "https://app.powerbi.com/view?r=eyJrIjoiZTViYjIwMmEtZWJmYy00MWJiLTg0NTYtMmU2YzQ1MjVlNjM5IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 40, "region": null, + "capacity_and_resource": "b819a9b3-f4d2-4bd1-ba73-c2c504b0f7bf", "show_on_home": false, - "order": 2, + "order": 1, "is_active": true, "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" } @@ -214,6 +337,7 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZGNlNjQxMTgtN2EzZS00NmE2LWExZTMtOTY3NTRmYjllYjczIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9&cacheUpdate=1778822328708", "page": 50, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 1, "is_active": true, @@ -222,15 +346,16 @@ }, { "model": "dashboards.externaldashboard", - "pk": "fcf44273-7683-48fd-ac59-072ca4bd2632", + "pk": "de33b005-12d8-4430-84cc-98ed271287a6", "fields": { - "created_at": "2026-05-15T05:24:31.499Z", - "updated_at": "2026-05-15T05:24:31.499Z", - "title": "DR-2", + "created_at": "2026-05-15T05:23:58.940Z", + "updated_at": "2026-05-15T05:23:58.940Z", + "title": "DR-1", "description": "", - "url": "https://app.powerbi.com/view?r=eyJrIjoiYTViNTJhMTItZTRhYi00MDVkLWIzYmQtMGY1Zjc4ZDhhZjUzIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", + "url": "https://app.powerbi.com/view?r=eyJrIjoiNzJkYTUyOTgtN2IwNi00YTM0LWEwZGYtMjQ5NTk0MTI1OTc4IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 60, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 1, "is_active": true, @@ -239,15 +364,16 @@ }, { "model": "dashboards.externaldashboard", - "pk": "de33b005-12d8-4430-84cc-98ed271287a6", + "pk": "fcf44273-7683-48fd-ac59-072ca4bd2632", "fields": { - "created_at": "2026-05-15T05:23:58.940Z", - "updated_at": "2026-05-15T05:23:58.940Z", - "title": "DR-1", + "created_at": "2026-05-15T05:24:31.499Z", + "updated_at": "2026-05-15T05:24:31.499Z", + "title": "DR-2", "description": "", - "url": "https://app.powerbi.com/view?r=eyJrIjoiNzJkYTUyOTgtN2IwNi00YTM0LWEwZGYtMjQ5NTk0MTI1OTc4IiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", + "url": "https://app.powerbi.com/view?r=eyJrIjoiYTViNTJhMTItZTRhYi00MDVkLWIzYmQtMGY1Zjc4ZDhhZjUzIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 60, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 1, "is_active": true, @@ -265,146 +391,11 @@ "url": "https://app.powerbi.com/view?r=eyJrIjoiZjMyMTdiYWQtZTZmNi00OTQ3LWE2N2MtMWE0Mzk3NWU2ZDdkIiwidCI6ImY2NmI3ZDQ2LTA0OTktNDM1Mi1iOTc3LTIwNWJjOTgzNzI2MCIsImMiOjh9", "page": 70, "region": null, + "capacity_and_resource": null, "show_on_home": false, "order": 1, "is_active": true, "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d" } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "a1378004-7892-4d5b-b9a5-304cc7a2dbd6", - "fields": { - "created_at": "2026-05-15T04:42:31.563Z", - "updated_at": "2026-05-15T04:44:50.175Z", - "title": "Ethiopia Drug Store and Pharmacy", - "description": "Monitor and allocate capacity and resources effectively to support humanitarian operations and response efforts.", - "region": null, - "is_active": true, - "order": 1, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "5416c79d-0de2-4f69-8be4-d28565d54943", - "8e848a27-b8fb-4572-8dc4-6fffb9f83fdf" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "25417636-5508-4b1d-9197-524c8a7817f3", - "fields": { - "created_at": "2026-05-15T04:45:09.319Z", - "updated_at": "2026-05-15T04:54:58.248Z", - "title": "Emergency Medical Service", - "description": "Monitor, coordinate, and manage emergency medical service operations and response activities.", - "region": null, - "is_active": true, - "order": 2, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "5ac17c60-fdd3-4784-b665-f322399da438", - "16c4ba29-d8e3-4053-abf5-6a32b998aad7" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "0339969d-a96f-4c1a-939d-cf03d42646a9", - "fields": { - "created_at": "2026-05-15T04:45:51.070Z", - "updated_at": "2026-05-15T04:55:06.866Z", - "title": "ERCS Fleet Tracking", - "description": "Track, monitor, and manage fleet movement, vehicle usage, and transportation efficiency in real time.", - "region": null, - "is_active": true, - "order": 3, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "8182f454-3912-4015-bec7-be2d9a976b52" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "eac83bc9-a29d-4f96-9a04-9abe0402f89b", - "fields": { - "created_at": "2026-05-15T04:46:20.391Z", - "updated_at": "2026-05-15T04:55:17.395Z", - "title": "Landholdings", - "description": "Maintain, organize, and monitor records of organizational land assets and property details.", - "region": null, - "is_active": true, - "order": 4, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "d57f6490-dbf1-426a-9074-9b2a9ddd4606" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "92f9ff2d-5c0d-4377-88d8-40ab0fe12309", - "fields": { - "created_at": "2026-05-15T04:46:43.083Z", - "updated_at": "2026-05-15T04:55:26.400Z", - "title": "Membership and Volunteer", - "description": "Manage member and volunteer profiles, engagement, and participation across programs and activities.", - "region": null, - "is_active": true, - "order": 5, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "f33e6d68-fcf5-4620-9008-e05dc3bc572b" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "1fa60c54-dbb6-4acf-8f85-0573d25f9dd3", - "fields": { - "created_at": "2026-05-15T04:47:04.204Z", - "updated_at": "2026-05-15T04:54:39.594Z", - "title": "Project Balance", - "description": "Track, review, and manage project budgets, expenses, and overall financial performance.", - "region": null, - "is_active": true, - "order": 6, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "be9569c0-09e7-4b2e-b71c-056d43ef4f22" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "b819a9b3-f4d2-4bd1-ba73-c2c504b0f7bf", - "fields": { - "created_at": "2026-05-15T04:47:52.551Z", - "updated_at": "2026-05-15T04:56:35.863Z", - "title": "Restoring Family Link (RFL)", - "description": "Support and manage processes for family tracing, reunification, and related humanitarian services.", - "region": null, - "is_active": true, - "order": 7, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [ - "fdbf10f4-4582-4347-9b51-f4345b03fd81" - ] - } -}, -{ - "model": "dashboards.capacityandresource", - "pk": "846652f5-3277-416f-ace9-bca7142c1a96", - "fields": { - "created_at": "2026-05-15T04:48:20.347Z", - "updated_at": "2026-05-15T04:48:20.347Z", - "title": "Hospitals", - "description": "View, update, and manage hospital information, resources, and service availability across regions.", - "region": null, - "is_active": true, - "order": 8, - "created_by": "55173c82-1e55-4120-9aee-6a346db69c6d", - "dashboards": [] - } } ]