Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions enferno/admin/models/Eventtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Eventtype(db.Model, BaseMixin):
title_ar = db.Column(db.String)
for_actor = db.Column(db.Boolean, default=False)
for_bulletin = db.Column(db.Boolean, default=False)
for_incident = db.Column(db.Boolean, default=False)
comments = db.Column(db.String)

# custom serialization method
Expand All @@ -37,6 +38,7 @@ def to_dict(self) -> dict[str, Any]:
"title_ar": self.title_ar or None,
"for_actor": self.for_actor,
"for_bulletin": self.for_bulletin,
"for_incident": self.for_incident,
"comments": self.comments,
"updated_at": DateHelper.serialize_datetime(self.updated_at),
}
Expand All @@ -60,6 +62,7 @@ def from_json(self, json: dict[str, Any]) -> "Eventtype":
self.title_ar = json.get("title_ar", self.title_ar)
self.for_actor = json.get("for_actor", self.for_actor)
self.for_bulletin = json.get("for_bulletin", self.for_bulletin)
self.for_incident = json.get("for_incident", self.for_incident)
self.comments = json.get("comments", self.comments)

return self
Expand Down
11 changes: 9 additions & 2 deletions enferno/admin/templates/admin/eventtypes.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,23 @@
</v-col>
</v-row>
<v-row>
<v-col cols="12" md="6">
<v-col cols="12" md="4">
<v-checkbox label="{{ _('For Actors') }}"
v-model="editedItem.for_actor">
</v-checkbox>

</v-col>
<v-col cols="12" md="6">
<v-col cols="12" md="4">
<v-checkbox label="{{ _('For Bulletins') }}"
v-model="editedItem.for_bulletin">
</v-checkbox>

</v-col>
<v-col cols="12" md="4">
<v-checkbox label="{{ _('For Incidents') }}"
v-model="editedItem.for_incident">
</v-checkbox>

</v-col>
<v-row>
<v-col>
Expand Down Expand Up @@ -210,6 +216,7 @@
{title: "{{_('Title (ar)')}}", value: "title_ar"},
{title: "{{_('For Actors')}}", value: "for_actor"},
{title: "{{_('For Bulletins')}}", value: "for_bulletin"},
{title: "{{_('For Incidents')}}", value: "for_incident"},
{title: "{{_('Comments')}}", value: "comments"},
{% if current_user.roles_in(['Admin','Mod']) %}
{title: "{{_('Actions')}}", value: "action", sortable: false}
Expand Down
2 changes: 1 addition & 1 deletion enferno/admin/templates/admin/incidents.html
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@
saving: false,
eventDialog: false,
reviewDialog: false,
eventParams: {typ: 'for_bulletin'},
eventParams: {typ: 'for_incident'},
reviewKey: 0,

// search and relate bulletin dialog vars
Expand Down
1 change: 1 addition & 0 deletions enferno/admin/validation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ class EventtypeValidationModel(one_must_exist(["title", "title_ar"])):
title_ar: Optional[str] = None
for_actor: Optional[bool] = None
for_bulletin: Optional[bool] = None
for_incident: Optional[bool] = None
comments: Optional[str] = None
# sent by the front-end on PUT, but not used by the from_json method
id: Optional[int] = None
Expand Down
2 changes: 1 addition & 1 deletion enferno/admin/views/eventtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def api_eventtypes() -> Response:
query.append(Eventtype.title.ilike("%" + q + "%"))

typ = request.args.get("typ", None)
if typ and typ in ["for_bulletin", "for_actor"]:
if typ and typ in ["for_bulletin", "for_actor", "for_incident"]:
query.append(getattr(Eventtype, typ) == True)
result = (
Eventtype.query.filter(*query)
Expand Down
46 changes: 23 additions & 23 deletions enferno/data/eventtypes.csv
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
id,title,title_ar,comments,for_actor,for_bulletin
10,Birth,,,1,0
11,Death,,,1,0
12,Detained/Abducted,,,1,0
13,Released,,,1,0
14,Missing,,,1,0
15,Returned,,,1,0
16,Wounded,,,1,0
17,Defected,,,1,0
18,IDP,,,1,0
19,Refugee,,,1,0
20,Other,,,1,0
21,Burial,,,1,0
22,Trial,,,1,0
23,Residence,,,1,0
24,Found,,,1,0
25,Stillbirth,,,1,0
26,Sighting,,,1,0
27,Held,,,1,0
28,Publication,,,1,0
29,Incident,,,0,1
30,Post-Incident,,,0,1
31,Non-Incident,,,0,1
id,title,title_ar,comments,for_actor,for_bulletin,for_incident
10,Birth,,,1,0,0
11,Death,,,1,0,0
12,Detained/Abducted,,,1,0,0
13,Released,,,1,0,0
14,Missing,,,1,0,0
15,Returned,,,1,0,0
16,Wounded,,,1,0,0
17,Defected,,,1,0,0
18,IDP,,,1,0,0
19,Refugee,,,1,0,0
20,Other,,,1,0,0
21,Burial,,,1,0,0
22,Trial,,,1,0,0
23,Residence,,,1,0,0
24,Found,,,1,0,0
25,Stillbirth,,,1,0,0
26,Sighting,,,1,0,0
27,Held,,,1,0,0
28,Publication,,,1,0,0
29,Incident,,,0,1,1
30,Post-Incident,,,0,1,1
31,Non-Incident,,,0,1,1
2 changes: 1 addition & 1 deletion enferno/static/js/components/IncidentSearchBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ const IncidentSearchBox = Vue.defineComponent({
<search-field
v-model="q.etype"
api="/admin/api/eventtypes/"
:query-params="{ typ: 'for_bulletin' }"
:query-params="{ typ: 'for_incident' }"
item-title="title"
item-value="id"
:multiple="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""add for_incident to eventtype

Gives event types their own Incidents toggle, independent of Bulletins. Until now
the Incidents screen reused the `for_bulletin` flag, so event types could not be
scoped to Incidents separately. Existing rows are backfilled with `for_bulletin`
so the Incidents event-type list stays identical on day one; admins can then
curate it from there.

Revision ID: c7d2e9f4a1b8
Revises: b3f1c2a4d5e6
Create Date: 2026-06-27

"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "c7d2e9f4a1b8"
down_revision = "b3f1c2a4d5e6"
branch_labels = None
depends_on = None


def upgrade():
op.add_column(
"eventtype",
sa.Column("for_incident", sa.Boolean(), server_default=sa.false(), nullable=True),
)
# Preserve current behavior: Incidents previously borrowed the Bulletin flag.
op.execute("UPDATE eventtype SET for_incident = for_bulletin")


def downgrade():
op.drop_column("eventtype", "for_incident")
2 changes: 2 additions & 0 deletions tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ class Meta:
comments = factory.Faker("paragraph")
for_actor = False
for_bulletin = False
for_incident = False
comments = factory.Faker("sentence")


Expand Down Expand Up @@ -553,6 +554,7 @@ def _create_eventtype(entity_type):
eventtype = EventtypeFactory()
eventtype.for_actor = entity_type.lower() == "actor"
eventtype.for_bulletin = entity_type.lower() == "bulletin"
eventtype.for_incident = entity_type.lower() == "incident"
session.add(eventtype)
session.commit()
request.addfinalizer(lambda: session.delete(eventtype))
Expand Down
9 changes: 8 additions & 1 deletion tests/test_lookup_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,14 @@
"event_types": (
"/admin/api/eventtypes/",
"/admin/api/eventtype/",
{"item": {"title": "TestEventtype", "for_bulletin": True, "for_actor": False}},
{
"item": {
"title": "TestEventtype",
"for_bulletin": True,
"for_actor": False,
"for_incident": False,
}
},
{"item": {"title": "Updated"}},
ADMIN_MOD_UPDATE,
),
Expand Down
Loading