Skip to content

Commit

Permalink
feat: add self-join button and api to cases (#4907)
Browse files Browse the repository at this point in the history
* feat: add self-join button and api to cases

* only allow adding to dedicated channel cases

* change references to incident logic and language to cases

* reference to incident id in CaseJoinPermission

* remove unused value and setup map actions in caseStatus.vue
  • Loading branch information
wssheldon authored Jul 2, 2024
1 parent 1a0c241 commit 0bcb2be
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 6 deletions.
14 changes: 14 additions & 0 deletions src/dispatch/auth/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,20 @@ def has_required_permissions(
return current_user.email in participant_emails


class CaseJoinPermission(BasePermission):
def has_required_permissions(
self,
request: Request,
) -> bool:
pk = PrimaryKeyModel(id=request.path_params["case_id"])
current_case = case_service.get(db_session=request.state.db, case_id=pk.id)

if current_case.visibility == Visibility.restricted:
return OrganizationAdminPermission(request=request)

return True


class FeedbackDeletePermission(BasePermission):
def has_required_permissions(
self,
Expand Down
4 changes: 3 additions & 1 deletion src/dispatch/case/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from datetime import datetime
from typing import Any, ForwardRef, List, Optional

from pydantic import validator
from pydantic import Field, validator
from sqlalchemy import (
Boolean,
Column,
Expand Down Expand Up @@ -230,6 +230,7 @@ class ProjectRead(DispatchBase):
id: Optional[PrimaryKey]
name: NameStr
color: Optional[str]
allow_self_join: Optional[bool] = Field(True, nullable=True)


# Pydantic models...
Expand Down Expand Up @@ -281,6 +282,7 @@ class CaseReadMinimal(CaseBase):
closed_at: Optional[datetime] = None
created_at: Optional[datetime] = None
escalated_at: Optional[datetime] = None
dedicated_channel: Optional[bool]
name: Optional[NameStr]
project: ProjectRead
reporter: Optional[ParticipantReadMinimal]
Expand Down
25 changes: 24 additions & 1 deletion src/dispatch/case/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# NOTE: define permissions before enabling the code block below
from dispatch.auth.permissions import (
CaseEditPermission,
# CaseJoinPermission,
CaseJoinPermission,
PermissionsDependency,
CaseViewPermission,
)
Expand All @@ -27,6 +27,7 @@
from dispatch.individual.models import IndividualContactRead

from .flows import (
case_add_or_reactivate_participant_flow,
case_closed_create_flow,
case_delete_flow,
case_escalated_create_flow,
Expand Down Expand Up @@ -338,3 +339,25 @@ def delete_case(
}
],
) from None


@router.post(
"/{case_id}/join",
summary="Adds an individual to a case.",
dependencies=[Depends(PermissionsDependency([CaseJoinPermission]))],
)
def join_case(
db_session: DbSession,
organization: OrganizationSlug,
case_id: PrimaryKey,
current_case: CurrentCase,
current_user: CurrentUser,
background_tasks: BackgroundTasks,
):
"""Adds an individual to a case."""
background_tasks.add_task(
case_add_or_reactivate_participant_flow,
current_user.email,
case_id=current_case.id,
organization_slug=organization,
)
36 changes: 33 additions & 3 deletions src/dispatch/static/dispatch/src/case/CaseStatus.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
<template>
<v-badge bordered :color="color" dot location="left" offset-x="-16">
{{ status }}
</v-badge>
<div class="text-no-wrap">
<v-badge bordered :color="color" dot location="left" offset-x="-16">
{{ status }}
</v-badge>
<template v-if="status !== 'Closed' && dedicatedChannel">
<v-tooltip location="bottom" text="Join" v-if="allowSelfJoin">
<template #activator="{ props }">
<v-btn
v-bind="props"
icon="mdi-account-plus"
variant="text"
density="comfortable"
class="ml-1"
@click.stop="joinCase(id)"
/>
</template>
</v-tooltip>
</template>
</div>
</template>

<script>
import { mapActions } from "vuex"
export default {
name: "CaseStatus",
Expand All @@ -17,6 +35,14 @@ export default {
type: Number,
required: true,
},
allowSelfJoin: {
type: Boolean,
required: true,
},
dedicatedChannel: {
type: Boolean,
required: true,
},
},
computed: {
Expand All @@ -31,5 +57,9 @@ export default {
)
},
},
methods: {
...mapActions("case_management", ["joinCase"]),
},
}
</script>
7 changes: 6 additions & 1 deletion src/dispatch/static/dispatch/src/case/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@
<case-priority :priority="value" />
</template>
<template #item.status="{ item }">
<case-status :status="item.status" :id="item.id" />
<case-status
:status="item.status"
:id="item.id"
:allowSelfJoin="item.project.allow_self_join"
:dedicatedChannel="item.dedicated_channel"
/>
</template>
<template #item.project.name="{ item }">
<v-chip size="small" :color="item.project.color">
Expand Down
4 changes: 4 additions & 0 deletions src/dispatch/static/dispatch/src/case/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export default {
return API.delete(`/${resource}/${caseId}`)
},

join(caseId, payload) {
return API.post(`/${resource}/${caseId}/join`, payload)
},

createAllResources(caseId, payload) {
return API.post(`/${resource}/${caseId}/resources`, payload)
},
Expand Down
9 changes: 9 additions & 0 deletions src/dispatch/static/dispatch/src/case/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,15 @@ const actions = {
)
})
},
joinCase({ commit }, caseId) {
CaseApi.join(caseId, {}).then(() => {
commit(
"notification_backend/addBeNotification",
{ text: "You have successfully joined the case.", type: "success" },
{ root: true }
)
})
},
getEnabledPlugins() {
if (!state.selected.project) {
return false
Expand Down

0 comments on commit 0bcb2be

Please sign in to comment.