Skip to content

Commit

Permalink
Fixes feedback table and inconsistent incident filtering (#1458)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevgliss authored Jul 19, 2021
1 parent 8aea672 commit 5eb0795
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 86 deletions.
42 changes: 27 additions & 15 deletions src/dispatch/database/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@

from sqlalchemy import or_, orm, func, desc
from sqlalchemy_filters import apply_pagination, apply_sort, apply_filters
from sqlalchemy_filters.filters import build_filters, get_named_models
from sqlalchemy_filters.models import get_query_models


from dispatch.auth.models import DispatchUser
from dispatch.auth.service import get_current_user, get_current_role
from dispatch.enums import UserRoles, Visibility
from dispatch.feedback.models import Feedback
from dispatch.incident.models import Incident
from dispatch.feedback.models import Feedback
from dispatch.task.models import Task
from dispatch.plugin.models import Plugin, PluginInstance
from dispatch.incident_type.models import IncidentType
from dispatch.individual.models import IndividualContact
from dispatch.participant.models import Participant
from dispatch.plugin.models import Plugin, PluginInstance
from dispatch.project.models import Project
from dispatch.search.fulltext.composite_search import CompositeSearch
from dispatch.task.models import Task


from .core import (
Expand Down Expand Up @@ -75,20 +76,31 @@ def apply_model_specific_filters(
return query


def apply_model_specific_joins(model: Base, query: orm.query):
def apply_filter_specific_joins(model: Base, filter_spec: dict, query: orm.query):
"""Applies any model specific implicity joins."""
# this is required because by default sqlalchemy-filter's auto-join
# knows nothing about how to join many-many relationships.
model_map = {
Feedback: [(Incident, False), (Project, False)],
Task: [(Incident, False), (Project, False)],
PluginInstance: [(Plugin, False)],
Incident: [(Incident.tags, True), (Incident.terms, True)],
DispatchUser: [(DispatchUser.organizations, True)],
(Feedback, "Project"): (Incident, False),
(Feedback, "Incident"): (Incident, False),
(Task, "Project"): (Incident, False),
(Task, "Incident"): (Incident, False),
(Task, "IncidentPriority"): (Incident, False),
(Task, "IncidentType"): (Incident, False),
(PluginInstance, "Plugin"): (Plugin, False),
(DispatchUser, "Organization"): (DispatchUser.organizations, True),
(Incident, "Tag"): (Incident.tags, True),
(Incident, "TagType"): (Incident.tags, True),
(Incident, "Terms"): (Incident.terms, True),
}
filters = build_filters(filter_spec)
filter_models = get_named_models(filters)

joined_models = model_map.get(model, [])

for model, is_outer in joined_models:
query = query.join(model, isouter=is_outer)
for filter_model in filter_models:
if model_map.get((model, filter_model)):
joined_model, is_outer = model_map[(model, filter_model)]
if joined_model not in get_query_models(query).values():
query = query.join(joined_model, isouter=is_outer)

return query

Expand Down Expand Up @@ -194,7 +206,6 @@ def search_filter_sort_paginate(
sort_spec = create_sort_spec(model, sort_by, descending)

query = db_session.query(model_cls)
query = apply_model_specific_joins(model_cls, query)

if query_str:
sort = False if sort_by else True
Expand All @@ -203,6 +214,7 @@ def search_filter_sort_paginate(
query = apply_model_specific_filters(model_cls, query, current_user, role)

if filter_spec:
query = apply_filter_specific_joins(model_cls, filter_spec, query)
query = apply_filters(query, filter_spec)

query = apply_sort(query, sort_spec)
Expand Down
9 changes: 6 additions & 3 deletions src/dispatch/incident/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
IncidentPriorityRead,
)
from dispatch.incident_type.models import IncidentTypeCreate, IncidentTypeRead, IncidentTypeBase
from dispatch.individual.models import IndividualContactCreate
from dispatch.models import DispatchBase, ProjectMixin, TimeStampMixin
from dispatch.participant.models import Participant, ParticipantRead, ParticipantUpdate
from dispatch.participant_role.models import ParticipantRole, ParticipantRoleType
Expand Down Expand Up @@ -239,9 +238,13 @@ def total_cost(self):
storage = relationship(
"Storage", uselist=False, backref="incident", cascade="all, delete-orphan"
)
tags = relationship("Tag", secondary=assoc_incident_tags, backref="incidents")
tags = relationship(
"Tag",
secondary=assoc_incident_tags,
backref="incidents",
)
tasks = relationship("Task", backref="incident", cascade="all, delete-orphan")
terms = relationship("Term", secondary=assoc_incident_terms, backref="incidents", lazy="joined")
terms = relationship("Term", secondary=assoc_incident_terms, backref="incidents")
ticket = relationship("Ticket", uselist=False, backref="incident", cascade="all, delete-orphan")
workflow_instances = relationship(
"WorkflowInstance", backref="incident", cascade="all, delete-orphan"
Expand Down
4 changes: 2 additions & 2 deletions src/dispatch/search_filter/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from sqlalchemy_filters import apply_filters

from dispatch.database.core import Base, get_class_by_tablename, get_table_name_by_class_instance
from dispatch.database.service import apply_model_specific_joins
from dispatch.database.service import apply_filter_specific_joins
from dispatch.project import service as project_service

from .models import SearchFilter, SearchFilterCreate, SearchFilterUpdate
Expand All @@ -30,7 +30,7 @@ def match(*, db_session, filter_spec: List[dict], class_instance: Base):
model_cls = get_class_by_tablename(table_name)
query = db_session.query(model_cls)

query = apply_model_specific_joins(model_cls, query)
query = apply_filter_specific_joins(model_cls, filter_spec, query)
query = apply_filters(query, filter_spec)
return query.filter(model_cls.id == class_instance.id).one_or_none()

Expand Down
3 changes: 1 addition & 2 deletions src/dispatch/static/dispatch/src/feedback/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
loading-text="Loading... Please wait"
>
<template v-slot:item.participant="{ item }">
<participant :participant="item.participant" />
<participant v-if="item.participant" :participant="item.participant" />
</template>
<template v-slot:item.created_at="{ item }">
<v-tooltip bottom>
Expand Down Expand Up @@ -134,7 +134,6 @@ export default {
vm.feedback,
vm.project,
vm.participant,
vm.project,
],
() => {
this.page = 1
Expand Down
65 changes: 5 additions & 60 deletions src/dispatch/static/dispatch/src/feedback/TableFilterDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<v-list dense>
<v-list-item>
<v-list-item-content>
<incident-combobox v-model="localIncident" />
<incident-combobox v-model="incident" />
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-content>
<project-combobox v-model="localProject" />
<project-combobox v-model="project" />
</v-list-item-content>
</v-list-item>
</v-list>
Expand All @@ -27,52 +27,13 @@

<script>
import { sum } from "lodash"
import SearchUtils from "@/search/utils"
import { mapFields } from "vuex-map-fields"
import IncidentCombobox from "@/incident/IncidentCombobox.vue"
import ProjectCombobox from "@/project/ProjectCombobox.vue"
import FeedbackApi from "@/feedback/api"
export default {
name: "FeedbackTableFilterDialog",
props: {
incident: {
type: Array,
default: function () {
return []
},
},
project: {
type: [String, Array],
default: function () {
return []
},
},
},
methods: {
fetchData() {
let filterOptions = {
itemsPerPage: -1,
descending: [false],
sortBy: ["created_at"],
filters: {
project: this.localProject,
incident: this.incident,
},
}
filterOptions = SearchUtils.createParametersFromTableOptions(filterOptions)
this.$emit("loading", "error")
this.$emit("filterOptions", filterOptions)
FeedbackApi.getAll(filterOptions).then((response) => {
this.$emit("update", response.data.items)
this.$emit("loading", false)
})
},
},
components: {
IncidentCombobox,
ProjectCombobox,
Expand All @@ -81,29 +42,13 @@ export default {
data() {
return {
display: false,
localProject: typeof this.project === "string" ? [{ name: this.project }] : this.project,
localIncident: typeof this.incident === "string" ? [{ name: this.incident }] : this.incident,
}
},
created() {
this.fetchData()
this.$watch(
(vm) => [vm.localIncident, vm.localProject],
() => {
this.fetchData()
}
)
},
computed: {
filters() {
return {
incident: this.localIncident,
project: this.localProject,
}
},
...mapFields("feedback", ["table.options.filters.incident", "table.options.filters.project"]),
numFilters: function () {
return sum([this.localIncident.length, this.localProject.length])
return sum([this.incident.length, this.project.length])
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion src/dispatch/static/dispatch/src/feedback/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const getters = {
const actions = {
getAll: debounce(({ commit, state }) => {
commit("SET_TABLE_LOADING", "primary")
let params = SearchUtils.createParametersFromTableOptions(state.table.options)
let params = SearchUtils.createParametersFromTableOptions({ ...state.table.options })
return FeedbackApi.getAll(params).then((response) => {
commit("SET_TABLE_LOADING", false)
commit("SET_TABLE_ROWS", response.data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
@update:search-input="fetchData({ q: $event })"
chips
clearable
close
deletable-chips
hide-selected
item-text="name"
multiple
no-filter
v-model="incident"
>
<template v-slot:selection="{ attr, on, item, selected }">
Expand All @@ -23,7 +23,7 @@
<template v-slot:item="{ item }">
<v-list-item-content>
<v-list-item-title v-text="item.name" />
<v-list-item-subtitle v-text="item.title" />
<v-list-item-subtitle style="width: 200px" class="text-truncate" v-text="item.title" />
</v-list-item-content>
</template>
<template v-slot:no-data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
<template>
<v-list-item-content>
<v-list-item-title v-text="data.item.name" />
<v-list-item-subtitle v-text="data.item.title" />
<v-list-item-subtitle
style="width: 200px"
class="text-truncate"
v-text="data.item.title"
/>
</v-list-item-content>
</template>
</template>
Expand Down
1 change: 1 addition & 0 deletions src/dispatch/static/dispatch/src/task/NewEditSheet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export default {
"selected.loading",
"dialogs.showCreateEdit",
]),
...mapFields("route", ["query"]),
},
methods: {
Expand Down

0 comments on commit 5eb0795

Please sign in to comment.