diff --git a/src/dispatch/database/revisions/tenant/versions/2024-09-10_0a6702319f6a.py b/src/dispatch/database/revisions/tenant/versions/2024-09-10_0a6702319f6a.py new file mode 100644 index 000000000000..bd0a32a7d410 --- /dev/null +++ b/src/dispatch/database/revisions/tenant/versions/2024-09-10_0a6702319f6a.py @@ -0,0 +1,31 @@ +"""Adds restriction ability to incident severity + +Revision ID: 0a6702319f6a +Revises: 51eacaf1f62c +Create Date: 2024-09-10 10:13:04.192475 + +""" + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = "0a6702319f6a" +down_revision = "51eacaf1f62c" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "incident_severity", + sa.Column("allowed_for_stable_incidents", sa.Boolean(), server_default="t", nullable=True), + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("incident_severity", "allowed_for_stable_incidents") + # ### end Alembic commands ### diff --git a/src/dispatch/incident/severity/models.py b/src/dispatch/incident/severity/models.py index 8944a443d06c..94adad99f8ad 100644 --- a/src/dispatch/incident/severity/models.py +++ b/src/dispatch/incident/severity/models.py @@ -20,6 +20,7 @@ class IncidentSeverity(Base, ProjectMixin): color = Column(String) enabled = Column(Boolean, default=True) default = Column(Boolean, default=False) + allowed_for_stable_incidents = Column(Boolean, default=True, server_default="t") # This column is used to control how severities should be displayed # Lower numbers will be shown first. @@ -46,6 +47,7 @@ class IncidentSeverityBase(DispatchBase): name: NameStr project: Optional[ProjectRead] view_order: Optional[int] + allowed_for_stable_incidents: Optional[bool] class IncidentSeverityCreate(IncidentSeverityBase): @@ -67,6 +69,7 @@ class IncidentSeverityReadMinimal(DispatchBase): description: Optional[str] = Field(None, nullable=True) enabled: Optional[bool] name: NameStr + allowed_for_stable_incidents: Optional[bool] class IncidentSeverityPagination(Pagination): diff --git a/src/dispatch/plugins/dispatch_slack/incident/interactive.py b/src/dispatch/plugins/dispatch_slack/incident/interactive.py index a72d8331ef67..866a316421f5 100644 --- a/src/dispatch/plugins/dispatch_slack/incident/interactive.py +++ b/src/dispatch/plugins/dispatch_slack/incident/interactive.py @@ -48,6 +48,7 @@ from dispatch.participant import service as participant_service from dispatch.participant.models import ParticipantUpdate from dispatch.participant_role import service as participant_role_service +from dispatch.incident.severity import service as incident_severity_service from dispatch.participant_role.enums import ParticipantRoleType from dispatch.plugin import service as plugin_service from dispatch.plugins.dispatch_slack import service as dispatch_slack_service @@ -1011,7 +1012,9 @@ def handle_member_joined_channel( if participant.added_by: # Message text when someone @'s a user is not available in body, use generic added by reason - participant.added_reason = f"Participant added by {participant.added_by.individual.name}" + participant.added_reason = ( + f"Participant added by {participant.added_by.individual.name}" + ) else: # We couldn't find a user to attribute the addition to, add generic reason participant.added_reason = "Participant added by Dispatch" @@ -1061,7 +1064,9 @@ def handle_member_joined_channel( if participant.added_by: # Message text when someone @'s a user is not available in body, use generic added by reason - participant.added_reason = f"Participant added by {participant.added_by.individual.name}" + participant.added_reason = ( + f"Participant added by {participant.added_by.individual.name}" + ) else: # We couldn't find a user to attribute the addition to, add generic reason participant.added_reason = "Participant added by Dispatch" @@ -1980,6 +1985,20 @@ def handle_update_incident_submission_event( user: DispatchUser, ) -> None: """Handles the update incident submission""" + incident_severity_id = form_data[DefaultBlockIds.incident_severity_select]["value"] + incident_severity = incident_severity_service.get( + db_session=db_session, incident_severity_id=incident_severity_id + ) + status = form_data[DefaultBlockIds.incident_status_select]["name"] + if not incident_severity.allowed_for_stable_incidents and ( + status == IncidentStatus.stable or status == IncidentStatus.closed + ): + errors = { + DefaultBlockIds.incident_severity_select: f"Severity cannot be {incident_severity.name} for {status} incidents" + } + ack(response_action="errors", errors=errors) + return + ack_incident_update_submission_event(ack=ack) incident = incident_service.get(db_session=db_session, incident_id=context["subject"].id) diff --git a/src/dispatch/static/dispatch/src/case/priority/NewEditSheet.vue b/src/dispatch/static/dispatch/src/case/priority/NewEditSheet.vue index d7939cca557d..7e76b5289521 100644 --- a/src/dispatch/static/dispatch/src/case/priority/NewEditSheet.vue +++ b/src/dispatch/static/dispatch/src/case/priority/NewEditSheet.vue @@ -86,7 +86,7 @@ diff --git a/src/dispatch/static/dispatch/src/case/severity/NewEditSheet.vue b/src/dispatch/static/dispatch/src/case/severity/NewEditSheet.vue index 764126294af8..58a3481c4d3d 100644 --- a/src/dispatch/static/dispatch/src/case/severity/NewEditSheet.vue +++ b/src/dispatch/static/dispatch/src/case/severity/NewEditSheet.vue @@ -79,7 +79,7 @@ diff --git a/src/dispatch/static/dispatch/src/case/type/NewEditSheet.vue b/src/dispatch/static/dispatch/src/case/type/NewEditSheet.vue index 1da007fa37c0..bc9b75150613 100644 --- a/src/dispatch/static/dispatch/src/case/type/NewEditSheet.vue +++ b/src/dispatch/static/dispatch/src/case/type/NewEditSheet.vue @@ -130,7 +130,7 @@ diff --git a/src/dispatch/static/dispatch/src/incident/DetailsTab.vue b/src/dispatch/static/dispatch/src/incident/DetailsTab.vue index 86dd69202c3b..d98c362d30cc 100644 --- a/src/dispatch/static/dispatch/src/incident/DetailsTab.vue +++ b/src/dispatch/static/dispatch/src/incident/DetailsTab.vue @@ -62,7 +62,7 @@ - + diff --git a/src/dispatch/static/dispatch/src/incident/priority/NewEditSheet.vue b/src/dispatch/static/dispatch/src/incident/priority/NewEditSheet.vue index 7bc67abb43bc..e397bdc0865b 100644 --- a/src/dispatch/static/dispatch/src/incident/priority/NewEditSheet.vue +++ b/src/dispatch/static/dispatch/src/incident/priority/NewEditSheet.vue @@ -112,7 +112,7 @@ diff --git a/src/dispatch/static/dispatch/src/incident/severity/IncidentSeveritySelect.vue b/src/dispatch/static/dispatch/src/incident/severity/IncidentSeveritySelect.vue index f336f0270516..cedef63a75c7 100644 --- a/src/dispatch/static/dispatch/src/incident/severity/IncidentSeveritySelect.vue +++ b/src/dispatch/static/dispatch/src/incident/severity/IncidentSeveritySelect.vue @@ -7,6 +7,7 @@ label="Severity" return-object :loading="loading" + :error-messages="show_error" :rules="[is_severity_in_project]" >