From 8767a55370d7c5cacdb0b97934ea1a463584bbff Mon Sep 17 00:00:00 2001 From: David Whittaker <84562015+whitdog47@users.noreply.github.com> Date: Tue, 12 Sep 2023 10:11:27 -0700 Subject: [PATCH 1/7] Allow a restricted incident priority for stable status (#3751) --- .../versions/2023-09-07_0356472ea980.py | 29 ++++++++++ src/dispatch/incident/models.py | 1 + src/dispatch/incident/priority/models.py | 6 +- src/dispatch/incident/service.py | 6 +- src/dispatch/project/models.py | 13 +++++ .../dispatch/src/incident/DetailsTab.vue | 50 +++++++++++++--- .../priority/IncidentPrioritySelect.vue | 16 +++++- .../dispatch/src/incident/priority/Table.vue | 57 ++++++++++++++++++- .../dispatch/src/incident/priority/store.js | 45 +++++++++++++++ 9 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 src/dispatch/database/revisions/tenant/versions/2023-09-07_0356472ea980.py diff --git a/src/dispatch/database/revisions/tenant/versions/2023-09-07_0356472ea980.py b/src/dispatch/database/revisions/tenant/versions/2023-09-07_0356472ea980.py new file mode 100644 index 000000000000..01a90e835da2 --- /dev/null +++ b/src/dispatch/database/revisions/tenant/versions/2023-09-07_0356472ea980.py @@ -0,0 +1,29 @@ +"""Adds new restrict to stable incident priority id + +Revision ID: 0356472ea980 +Revises: 4e57f5b1f3f3 +Create Date: 2023-09-01 15:30:52.512886 + +""" +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = "0356472ea980" +down_revision = "4e57f5b1f3f3" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("project", sa.Column("stable_priority_id", sa.Integer(), nullable=True)) + op.create_foreign_key(None, "project", "incident_priority", ["stable_priority_id"], ["id"]) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(None, "project", type_="foreignkey") + op.drop_column("project", "stable_priority_id") + # ### end Alembic commands ### diff --git a/src/dispatch/incident/models.py b/src/dispatch/incident/models.py index 4be0ce20ef9e..4b2ee2d5b3d4 100644 --- a/src/dispatch/incident/models.py +++ b/src/dispatch/incident/models.py @@ -239,6 +239,7 @@ class ProjectRead(DispatchBase): id: Optional[PrimaryKey] name: NameStr color: Optional[str] + stable_priority: Optional[IncidentPriorityRead] = None class CaseRead(DispatchBase): diff --git a/src/dispatch/incident/priority/models.py b/src/dispatch/incident/priority/models.py index 91ff59e303c8..4920201e7281 100644 --- a/src/dispatch/incident/priority/models.py +++ b/src/dispatch/incident/priority/models.py @@ -9,7 +9,6 @@ from dispatch.database.core import Base, ensure_unique_default_per_project from dispatch.models import DispatchBase, NameStr, ProjectMixin, PrimaryKey, Pagination -from dispatch.project.models import ProjectRead class IncidentPriority(Base, ProjectMixin): @@ -36,6 +35,11 @@ class IncidentPriority(Base, ProjectMixin): listen(IncidentPriority.default, "set", ensure_unique_default_per_project) +class ProjectRead(DispatchBase): + id: Optional[PrimaryKey] + name: NameStr + + # Pydantic models... class IncidentPriorityBase(DispatchBase): name: NameStr diff --git a/src/dispatch/incident/service.py b/src/dispatch/incident/service.py index 5868444da64b..3c6d06d06433 100644 --- a/src/dispatch/incident/service.py +++ b/src/dispatch/incident/service.py @@ -290,10 +290,8 @@ def update(*, db_session, incident: Incident, incident_in: IncidentUpdate) -> In ) if incident_in.status == IncidentStatus.stable: - incident_priority = incident_priority_service.get_default( - db_session=db_session, - project_id=incident.project.id, - ) + if incident.project.stable_priority: + incident_priority = incident.project.stable_priority else: incident_priority = incident_priority_service.get_by_name_or_default( db_session=db_session, diff --git a/src/dispatch/project/models.py b/src/dispatch/project/models.py index 1d6d54188be2..235043676464 100644 --- a/src/dispatch/project/models.py +++ b/src/dispatch/project/models.py @@ -12,6 +12,10 @@ from dispatch.models import DispatchBase, NameStr, PrimaryKey, Pagination from dispatch.organization.models import Organization, OrganizationRead +from dispatch.incident.priority.models import ( + IncidentPriority, + IncidentPriorityRead, +) class Project(Base): @@ -37,6 +41,13 @@ class Project(Base): send_daily_reports = Column(Boolean) + stable_priority_id = Column(Integer, nullable=True) + stable_priority = relationship( + IncidentPriority, + foreign_keys=[stable_priority_id], + primaryjoin="IncidentPriority.id == Project.stable_priority_id", + ) + @hybrid_property def slug(self): return slugify(self.name) @@ -65,10 +76,12 @@ class ProjectCreate(ProjectBase): class ProjectUpdate(ProjectBase): send_daily_reports: Optional[bool] = Field(True, nullable=True) + stable_priority_id: Optional[int] class ProjectRead(ProjectBase): id: Optional[PrimaryKey] + stable_priority: Optional[IncidentPriorityRead] = None class ProjectPagination(Pagination): diff --git a/src/dispatch/static/dispatch/src/incident/DetailsTab.vue b/src/dispatch/static/dispatch/src/incident/DetailsTab.vue index fe85c2a69e9c..0acf6bec7fac 100644 --- a/src/dispatch/static/dispatch/src/incident/DetailsTab.vue +++ b/src/dispatch/static/dispatch/src/incident/DetailsTab.vue @@ -77,15 +77,27 @@ - + + + - + + + + + + + + @@ -144,6 +161,25 @@ extend("required", { message: "This field is required", }) +extend("stableRestrictedPriority", { + params: ["status", "project"], + validate(value, { status, project }) { + if (!project) return true + const stablePriority = project.stable_priority + if (!stablePriority) return true + if (status == "Stable" && value.name != stablePriority.name) { + return false + } + return true + }, +}) + +extend("alwaysTrue", { + validate() { + return true + }, +}) + export default { name: "IncidentDetailsTab", diff --git a/src/dispatch/static/dispatch/src/incident/priority/IncidentPrioritySelect.vue b/src/dispatch/static/dispatch/src/incident/priority/IncidentPrioritySelect.vue index ae1ff06170bc..4b51569f8f06 100644 --- a/src/dispatch/static/dispatch/src/incident/priority/IncidentPrioritySelect.vue +++ b/src/dispatch/static/dispatch/src/incident/priority/IncidentPrioritySelect.vue @@ -7,6 +7,7 @@ label="Priority" return-object :loading="loading" + :error-messages="show_error" >