mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2025-02-16 18:20:48 +01:00
Better filtering + optional columns in ticket list view
This commit is contained in:
parent
c20dafe952
commit
f8c652d506
@ -77,13 +77,16 @@ def get_search_filter_args(search):
|
|||||||
|
|
||||||
DATATABLES_ORDER_COLUMN_CHOICES = Choices(
|
DATATABLES_ORDER_COLUMN_CHOICES = Choices(
|
||||||
('0', 'id'),
|
('0', 'id'),
|
||||||
|
('1', 'title'),
|
||||||
('2', 'priority'),
|
('2', 'priority'),
|
||||||
('3', 'title'),
|
('3', 'queue'),
|
||||||
('4', 'queue'),
|
('4', 'status'),
|
||||||
('5', 'status'),
|
('5', 'created'),
|
||||||
('6', 'created'),
|
('6', 'due_date'),
|
||||||
('7', 'due_date'),
|
('7', 'assigned_to'),
|
||||||
('8', 'assigned_to')
|
('8', 'submitter_email'),
|
||||||
|
#('9', 'time_spent'),
|
||||||
|
('10', 'kbitem'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -123,10 +126,9 @@ class __Query__:
|
|||||||
|
|
||||||
sorting: The name of the column to sort by
|
sorting: The name of the column to sort by
|
||||||
"""
|
"""
|
||||||
for key in self.params.get('filtering', {}).keys():
|
filter = self.params.get('filtering', {})
|
||||||
filter = {key: self.params['filtering'][key]}
|
filter_or = self.params.get('filtering_or', {})
|
||||||
queryset = queryset.filter(**filter)
|
queryset = queryset.filter((Q(**filter) | Q(**filter_or)) & self.get_search_filter_args())
|
||||||
queryset = queryset.filter(self.get_search_filter_args())
|
|
||||||
sorting = self.params.get('sorting', None)
|
sorting = self.params.get('sorting', None)
|
||||||
if sorting:
|
if sorting:
|
||||||
sortreverse = self.params.get('sortreverse', None)
|
sortreverse = self.params.get('sortreverse', None)
|
||||||
@ -177,7 +179,7 @@ class __Query__:
|
|||||||
queryset = objects.all().order_by(order_by)
|
queryset = objects.all().order_by(order_by)
|
||||||
total = queryset.count()
|
total = queryset.count()
|
||||||
|
|
||||||
if search_value:
|
if search_value: # Dead code currently
|
||||||
queryset = queryset.filter(get_search_filter_args(search_value))
|
queryset = queryset.filter(get_search_filter_args(search_value))
|
||||||
|
|
||||||
count = queryset.count()
|
count = queryset.count()
|
||||||
|
@ -22,13 +22,14 @@ class DatatablesTicketSerializer(serializers.ModelSerializer):
|
|||||||
row_class = serializers.SerializerMethodField()
|
row_class = serializers.SerializerMethodField()
|
||||||
time_spent = serializers.SerializerMethodField()
|
time_spent = serializers.SerializerMethodField()
|
||||||
queue = serializers.SerializerMethodField()
|
queue = serializers.SerializerMethodField()
|
||||||
|
kbitem = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Ticket
|
model = Ticket
|
||||||
# fields = '__all__'
|
# fields = '__all__'
|
||||||
fields = ('ticket', 'id', 'priority', 'title', 'queue', 'status',
|
fields = ('ticket', 'id', 'priority', 'title', 'queue', 'status',
|
||||||
'created', 'due_date', 'assigned_to', 'submitter', 'row_class',
|
'created', 'due_date', 'assigned_to', 'submitter', 'row_class',
|
||||||
'time_spent')
|
'time_spent', 'kbitem')
|
||||||
|
|
||||||
def get_queue(self, obj):
|
def get_queue(self, obj):
|
||||||
return ({"title": obj.queue.title, "id": obj.queue.id})
|
return ({"title": obj.queue.title, "id": obj.queue.id})
|
||||||
@ -62,3 +63,7 @@ class DatatablesTicketSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
def get_row_class(self, obj):
|
def get_row_class(self, obj):
|
||||||
return (obj.get_priority_css_class)
|
return (obj.get_priority_css_class)
|
||||||
|
|
||||||
|
def get_kbitem(self, obj):
|
||||||
|
return obj.kbitem.title if obj.kbitem else ""
|
||||||
|
|
||||||
|
380
helpdesk/static/helpdesk/vendor/datatables/css/buttons.dataTables.css
vendored
Normal file
380
helpdesk/static/helpdesk/vendor/datatables/css/buttons.dataTables.css
vendored
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
@keyframes dtb-spinner {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-o-keyframes dtb-spinner {
|
||||||
|
100% {
|
||||||
|
-o-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-ms-keyframes dtb-spinner {
|
||||||
|
100% {
|
||||||
|
-ms-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes dtb-spinner {
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-moz-keyframes dtb-spinner {
|
||||||
|
100% {
|
||||||
|
-moz-transform: rotate(360deg);
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div.dt-button-info {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 400px;
|
||||||
|
margin-top: -100px;
|
||||||
|
margin-left: -200px;
|
||||||
|
background-color: white;
|
||||||
|
border: 2px solid #111;
|
||||||
|
box-shadow: 3px 3px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 21;
|
||||||
|
}
|
||||||
|
div.dt-button-info h2 {
|
||||||
|
padding: 0.5em;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
}
|
||||||
|
div.dt-button-info > div {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-button-collection-title {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.3em 0 0.5em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-button-collection-title:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.dt-button,
|
||||||
|
div.dt-button,
|
||||||
|
a.dt-button {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-right: 0.333em;
|
||||||
|
margin-bottom: 0.333em;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.88em;
|
||||||
|
line-height: 1.6em;
|
||||||
|
color: black;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, white 0%, #e9e9e9 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, white 0%, #e9e9e9 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, white 0%, #e9e9e9 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, white 0%, #e9e9e9 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, white 0%, #e9e9e9 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='white', EndColorStr='#e9e9e9');
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
button.dt-button.disabled,
|
||||||
|
div.dt-button.disabled,
|
||||||
|
a.dt-button.disabled {
|
||||||
|
color: #999;
|
||||||
|
border: 1px solid #d0d0d0;
|
||||||
|
cursor: default;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #ffffff 0%, #f9f9f9 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #ffffff 0%, #f9f9f9 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ffffff', EndColorStr='#f9f9f9');
|
||||||
|
}
|
||||||
|
button.dt-button:active:not(.disabled), button.dt-button.active:not(.disabled),
|
||||||
|
div.dt-button:active:not(.disabled),
|
||||||
|
div.dt-button.active:not(.disabled),
|
||||||
|
a.dt-button:active:not(.disabled),
|
||||||
|
a.dt-button.active:not(.disabled) {
|
||||||
|
background-color: #e2e2e2;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #f3f3f3 0%, #e2e2e2 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f3f3f3', EndColorStr='#e2e2e2');
|
||||||
|
box-shadow: inset 1px 1px 3px #999999;
|
||||||
|
}
|
||||||
|
button.dt-button:active:not(.disabled):hover:not(.disabled), button.dt-button.active:not(.disabled):hover:not(.disabled),
|
||||||
|
div.dt-button:active:not(.disabled):hover:not(.disabled),
|
||||||
|
div.dt-button.active:not(.disabled):hover:not(.disabled),
|
||||||
|
a.dt-button:active:not(.disabled):hover:not(.disabled),
|
||||||
|
a.dt-button.active:not(.disabled):hover:not(.disabled) {
|
||||||
|
box-shadow: inset 1px 1px 3px #999999;
|
||||||
|
background-color: #cccccc;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #eaeaea 0%, #cccccc 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #eaeaea 0%, #cccccc 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#eaeaea', EndColorStr='#cccccc');
|
||||||
|
}
|
||||||
|
button.dt-button:hover,
|
||||||
|
div.dt-button:hover,
|
||||||
|
a.dt-button:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
button.dt-button:hover:not(.disabled),
|
||||||
|
div.dt-button:hover:not(.disabled),
|
||||||
|
a.dt-button:hover:not(.disabled) {
|
||||||
|
border: 1px solid #666;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #f9f9f9 0%, #e0e0e0 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#e0e0e0');
|
||||||
|
}
|
||||||
|
button.dt-button:focus:not(.disabled),
|
||||||
|
div.dt-button:focus:not(.disabled),
|
||||||
|
a.dt-button:focus:not(.disabled) {
|
||||||
|
border: 1px solid #426c9e;
|
||||||
|
text-shadow: 0 1px 0 #c4def1;
|
||||||
|
outline: none;
|
||||||
|
background-color: #79ace9;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #bddef4 0%, #79ace9 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #bddef4 0%, #79ace9 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #bddef4 0%, #79ace9 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #bddef4 0%, #79ace9 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #bddef4 0%, #79ace9 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#bddef4', EndColorStr='#79ace9');
|
||||||
|
}
|
||||||
|
|
||||||
|
.dt-button embed {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-buttons {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
div.dt-buttons.buttons-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-button-collection {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 150px;
|
||||||
|
margin-top: 3px;
|
||||||
|
padding: 8px 8px 4px 8px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.4);
|
||||||
|
background-color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 2002;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
div.dt-button-collection button.dt-button,
|
||||||
|
div.dt-button-collection div.dt-button,
|
||||||
|
div.dt-button-collection a.dt-button {
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
float: none;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
div.dt-button-collection button.dt-button:active:not(.disabled), div.dt-button-collection button.dt-button.active:not(.disabled),
|
||||||
|
div.dt-button-collection div.dt-button:active:not(.disabled),
|
||||||
|
div.dt-button-collection div.dt-button.active:not(.disabled),
|
||||||
|
div.dt-button-collection a.dt-button:active:not(.disabled),
|
||||||
|
div.dt-button-collection a.dt-button.active:not(.disabled) {
|
||||||
|
background-color: #dadada;
|
||||||
|
/* Fallback */
|
||||||
|
background-image: -webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
|
||||||
|
/* Chrome 10+, Saf5.1+, iOS 5+ */
|
||||||
|
background-image: -moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
|
||||||
|
/* FF3.6 */
|
||||||
|
background-image: -ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
|
||||||
|
/* IE10 */
|
||||||
|
background-image: -o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);
|
||||||
|
/* Opera 11.10+ */
|
||||||
|
background-image: linear-gradient(to bottom, #f0f0f0 0%, #dadada 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f0f0f0', EndColorStr='#dadada');
|
||||||
|
box-shadow: inset 1px 1px 3px #666;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.fixed {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -75px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.fixed.two-column {
|
||||||
|
margin-left: -200px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.fixed.three-column {
|
||||||
|
margin-left: -225px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.fixed.four-column {
|
||||||
|
margin-left: -300px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection > :last-child {
|
||||||
|
display: block !important;
|
||||||
|
-webkit-column-gap: 8px;
|
||||||
|
-moz-column-gap: 8px;
|
||||||
|
-ms-column-gap: 8px;
|
||||||
|
-o-column-gap: 8px;
|
||||||
|
column-gap: 8px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection > :last-child > * {
|
||||||
|
-webkit-column-break-inside: avoid;
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.two-column {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.two-column > :last-child {
|
||||||
|
padding-bottom: 1px;
|
||||||
|
-webkit-column-count: 2;
|
||||||
|
-moz-column-count: 2;
|
||||||
|
-ms-column-count: 2;
|
||||||
|
-o-column-count: 2;
|
||||||
|
column-count: 2;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.three-column {
|
||||||
|
width: 450px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.three-column > :last-child {
|
||||||
|
padding-bottom: 1px;
|
||||||
|
-webkit-column-count: 3;
|
||||||
|
-moz-column-count: 3;
|
||||||
|
-ms-column-count: 3;
|
||||||
|
-o-column-count: 3;
|
||||||
|
column-count: 3;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.four-column {
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
div.dt-button-collection.four-column > :last-child {
|
||||||
|
padding-bottom: 1px;
|
||||||
|
-webkit-column-count: 4;
|
||||||
|
-moz-column-count: 4;
|
||||||
|
-ms-column-count: 4;
|
||||||
|
-o-column-count: 4;
|
||||||
|
column-count: 4;
|
||||||
|
}
|
||||||
|
div.dt-button-collection .dt-button {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dt-button-background {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
/* Fallback */
|
||||||
|
background: -ms-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);
|
||||||
|
/* IE10 Consumer Preview */
|
||||||
|
background: -moz-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);
|
||||||
|
/* Firefox */
|
||||||
|
background: -o-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);
|
||||||
|
/* Opera */
|
||||||
|
background: -webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0, 0, 0, 0.3)), color-stop(1, rgba(0, 0, 0, 0.7)));
|
||||||
|
/* Webkit (Safari/Chrome 10) */
|
||||||
|
background: -webkit-radial-gradient(center, ellipse farthest-corner, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);
|
||||||
|
/* Webkit (Chrome 11+) */
|
||||||
|
background: radial-gradient(ellipse farthest-corner at center, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.7) 100%);
|
||||||
|
/* W3C Markup, IE10 Release Preview */
|
||||||
|
z-index: 2001;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 640px) {
|
||||||
|
div.dt-buttons {
|
||||||
|
float: none !important;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button.dt-button.processing,
|
||||||
|
div.dt-button.processing,
|
||||||
|
a.dt-button.processing {
|
||||||
|
color: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
button.dt-button.processing:after,
|
||||||
|
div.dt-button.processing:after,
|
||||||
|
a.dt-button.processing:after {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin: -8px 0 0 -8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
content: ' ';
|
||||||
|
border: 2px solid #282828;
|
||||||
|
border-radius: 50%;
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-right-color: transparent;
|
||||||
|
animation: dtb-spinner 1500ms infinite linear;
|
||||||
|
-o-animation: dtb-spinner 1500ms infinite linear;
|
||||||
|
-ms-animation: dtb-spinner 1500ms infinite linear;
|
||||||
|
-webkit-animation: dtb-spinner 1500ms infinite linear;
|
||||||
|
-moz-animation: dtb-spinner 1500ms infinite linear;
|
||||||
|
}
|
206
helpdesk/static/helpdesk/vendor/datatables/js/buttons.colVis.js
vendored
Normal file
206
helpdesk/static/helpdesk/vendor/datatables/js/buttons.colVis.js
vendored
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/*!
|
||||||
|
* Column visibility buttons for Buttons and DataTables.
|
||||||
|
* 2016 SpryMedia Ltd - datatables.net/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function( factory ){
|
||||||
|
if ( typeof define === 'function' && define.amd ) {
|
||||||
|
// AMD
|
||||||
|
define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
|
||||||
|
return factory( $, window, document );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
else if ( typeof exports === 'object' ) {
|
||||||
|
// CommonJS
|
||||||
|
module.exports = function (root, $) {
|
||||||
|
if ( ! root ) {
|
||||||
|
root = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $ || ! $.fn.dataTable ) {
|
||||||
|
$ = require('datatables.net')(root, $).$;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $.fn.dataTable.Buttons ) {
|
||||||
|
require('datatables.net-buttons')(root, $);
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory( $, root, root.document );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Browser
|
||||||
|
factory( jQuery, window, document );
|
||||||
|
}
|
||||||
|
}(function( $, window, document, undefined ) {
|
||||||
|
'use strict';
|
||||||
|
var DataTable = $.fn.dataTable;
|
||||||
|
|
||||||
|
|
||||||
|
$.extend( DataTable.ext.buttons, {
|
||||||
|
// A collection of column visibility buttons
|
||||||
|
colvis: function ( dt, conf ) {
|
||||||
|
return {
|
||||||
|
extend: 'collection',
|
||||||
|
text: function ( dt ) {
|
||||||
|
return dt.i18n( 'buttons.colvis', 'Column visibility' );
|
||||||
|
},
|
||||||
|
className: 'buttons-colvis',
|
||||||
|
buttons: [ {
|
||||||
|
extend: 'columnsToggle',
|
||||||
|
columns: conf.columns,
|
||||||
|
columnText: conf.columnText
|
||||||
|
} ]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Selected columns with individual buttons - toggle column visibility
|
||||||
|
columnsToggle: function ( dt, conf ) {
|
||||||
|
var columns = dt.columns( conf.columns ).indexes().map( function ( idx ) {
|
||||||
|
return {
|
||||||
|
extend: 'columnToggle',
|
||||||
|
columns: idx,
|
||||||
|
columnText: conf.columnText
|
||||||
|
};
|
||||||
|
} ).toArray();
|
||||||
|
|
||||||
|
return columns;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Single button to toggle column visibility
|
||||||
|
columnToggle: function ( dt, conf ) {
|
||||||
|
return {
|
||||||
|
extend: 'columnVisibility',
|
||||||
|
columns: conf.columns,
|
||||||
|
columnText: conf.columnText
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Selected columns with individual buttons - set column visibility
|
||||||
|
columnsVisibility: function ( dt, conf ) {
|
||||||
|
var columns = dt.columns( conf.columns ).indexes().map( function ( idx ) {
|
||||||
|
return {
|
||||||
|
extend: 'columnVisibility',
|
||||||
|
columns: idx,
|
||||||
|
visibility: conf.visibility,
|
||||||
|
columnText: conf.columnText
|
||||||
|
};
|
||||||
|
} ).toArray();
|
||||||
|
|
||||||
|
return columns;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Single button to set column visibility
|
||||||
|
columnVisibility: {
|
||||||
|
columns: undefined, // column selector
|
||||||
|
text: function ( dt, button, conf ) {
|
||||||
|
return conf._columnText( dt, conf );
|
||||||
|
},
|
||||||
|
className: 'buttons-columnVisibility',
|
||||||
|
action: function ( e, dt, button, conf ) {
|
||||||
|
var col = dt.columns( conf.columns );
|
||||||
|
var curr = col.visible();
|
||||||
|
|
||||||
|
col.visible( conf.visibility !== undefined ?
|
||||||
|
conf.visibility :
|
||||||
|
! (curr.length ? curr[0] : false )
|
||||||
|
);
|
||||||
|
},
|
||||||
|
init: function ( dt, button, conf ) {
|
||||||
|
var that = this;
|
||||||
|
button.attr( 'data-cv-idx', conf.columns );
|
||||||
|
|
||||||
|
dt
|
||||||
|
.on( 'column-visibility.dt'+conf.namespace, function (e, settings) {
|
||||||
|
if ( ! settings.bDestroying && settings.nTable == dt.settings()[0].nTable ) {
|
||||||
|
that.active( dt.column( conf.columns ).visible() );
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
.on( 'column-reorder.dt'+conf.namespace, function (e, settings, details) {
|
||||||
|
if ( dt.columns( conf.columns ).count() !== 1 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This button controls the same column index but the text for the column has
|
||||||
|
// changed
|
||||||
|
button.text( conf._columnText( dt, conf ) );
|
||||||
|
|
||||||
|
// Since its a different column, we need to check its visibility
|
||||||
|
that.active( dt.column( conf.columns ).visible() );
|
||||||
|
} );
|
||||||
|
|
||||||
|
this.active( dt.column( conf.columns ).visible() );
|
||||||
|
},
|
||||||
|
destroy: function ( dt, button, conf ) {
|
||||||
|
dt
|
||||||
|
.off( 'column-visibility.dt'+conf.namespace )
|
||||||
|
.off( 'column-reorder.dt'+conf.namespace );
|
||||||
|
},
|
||||||
|
|
||||||
|
_columnText: function ( dt, conf ) {
|
||||||
|
// Use DataTables' internal data structure until this is presented
|
||||||
|
// is a public API. The other option is to use
|
||||||
|
// `$( column(col).node() ).text()` but the node might not have been
|
||||||
|
// populated when Buttons is constructed.
|
||||||
|
var idx = dt.column( conf.columns ).index();
|
||||||
|
var title = dt.settings()[0].aoColumns[ idx ].sTitle
|
||||||
|
.replace(/\n/g," ") // remove new lines
|
||||||
|
.replace(/<br\s*\/?>/gi, " ") // replace line breaks with spaces
|
||||||
|
.replace(/<select(.*?)<\/select>/g, "") // remove select tags, including options text
|
||||||
|
.replace(/<!\-\-.*?\-\->/g, "") // strip HTML comments
|
||||||
|
.replace(/<.*?>/g, "") // strip HTML
|
||||||
|
.replace(/^\s+|\s+$/g,""); // trim
|
||||||
|
|
||||||
|
return conf.columnText ?
|
||||||
|
conf.columnText( dt, idx, title ) :
|
||||||
|
title;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
colvisRestore: {
|
||||||
|
className: 'buttons-colvisRestore',
|
||||||
|
|
||||||
|
text: function ( dt ) {
|
||||||
|
return dt.i18n( 'buttons.colvisRestore', 'Restore visibility' );
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function ( dt, button, conf ) {
|
||||||
|
conf._visOriginal = dt.columns().indexes().map( function ( idx ) {
|
||||||
|
return dt.column( idx ).visible();
|
||||||
|
} ).toArray();
|
||||||
|
},
|
||||||
|
|
||||||
|
action: function ( e, dt, button, conf ) {
|
||||||
|
dt.columns().every( function ( i ) {
|
||||||
|
// Take into account that ColReorder might have disrupted our
|
||||||
|
// indexes
|
||||||
|
var idx = dt.colReorder && dt.colReorder.transpose ?
|
||||||
|
dt.colReorder.transpose( i, 'toOriginal' ) :
|
||||||
|
i;
|
||||||
|
|
||||||
|
this.visible( conf._visOriginal[ idx ] );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
colvisGroup: {
|
||||||
|
className: 'buttons-colvisGroup',
|
||||||
|
|
||||||
|
action: function ( e, dt, button, conf ) {
|
||||||
|
dt.columns( conf.show ).visible( true, false );
|
||||||
|
dt.columns( conf.hide ).visible( false, false );
|
||||||
|
|
||||||
|
dt.columns.adjust();
|
||||||
|
},
|
||||||
|
|
||||||
|
show: [],
|
||||||
|
|
||||||
|
hide: []
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
return DataTable.Buttons;
|
||||||
|
}));
|
2015
helpdesk/static/helpdesk/vendor/datatables/js/dataTables.buttons.js
vendored
Normal file
2015
helpdesk/static/helpdesk/vendor/datatables/js/dataTables.buttons.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
<!-- DataTables CSS-->
|
<!-- DataTables CSS-->
|
||||||
<link href="{% static 'helpdesk/vendor/datatables/css/dataTables.bootstrap4.css' %}" rel="stylesheet">
|
<link href="{% static 'helpdesk/vendor/datatables/css/dataTables.bootstrap4.css' %}" rel="stylesheet">
|
||||||
|
<link href="{% static 'helpdesk/vendor/datatables/css/buttons.dataTables.css' %}" rel="stylesheet">
|
||||||
|
|
||||||
<!-- MetisMenu CSS -->
|
<!-- MetisMenu CSS -->
|
||||||
<link href="{% static 'helpdesk/vendor/metisMenu/metisMenu.min.css' %}" rel="stylesheet">
|
<link href="{% static 'helpdesk/vendor/metisMenu/metisMenu.min.css' %}" rel="stylesheet">
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
<script src="{% static 'helpdesk/vendor/chart.js/Chart.min.js' %}"></script>
|
<script src="{% static 'helpdesk/vendor/chart.js/Chart.min.js' %}"></script>
|
||||||
<script src="{% static 'helpdesk/vendor/datatables/js/jquery.dataTables.js' %}"></script>
|
<script src="{% static 'helpdesk/vendor/datatables/js/jquery.dataTables.js' %}"></script>
|
||||||
<script src="{% static 'helpdesk/vendor/datatables/js/dataTables.bootstrap4.js' %}"></script>
|
<script src="{% static 'helpdesk/vendor/datatables/js/dataTables.bootstrap4.js' %}"></script>
|
||||||
|
<script src="{% static 'helpdesk/vendor/datatables/js/dataTables.buttons.js' %}"></script>
|
||||||
|
<script src="{% static 'helpdesk/vendor/datatables/js/buttons.colVis.js' %}"></script>
|
||||||
|
|
||||||
<!-- jQuery UI DatePicker -->
|
<!-- jQuery UI DatePicker -->
|
||||||
<script src='{% static "helpdesk/vendor/jquery-ui/jquery-ui.min.js" %}' type='text/javascript' language='javascript'></script>
|
<script src='{% static "helpdesk/vendor/jquery-ui/jquery-ui.min.js" %}' type='text/javascript' language='javascript'></script>
|
||||||
|
@ -6,7 +6,16 @@
|
|||||||
<label for='id_statuses'>{% trans "Knowledge base item(s)" %}:</label>
|
<label for='id_statuses'>{% trans "Knowledge base item(s)" %}:</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-sm-3">
|
<div class="col col-sm-3">
|
||||||
<select id='id_kbitems' name='kbitem' multiple='selected' size='5'>{% for s in kbitem_choices %}<option value='{{ s.0 }}'{% if s.0|in_list:query_params.filtering.kbitem__in %} selected='selected'{% endif %}>{{ s.1 }}</option>{% endfor %}</select>
|
<select id='id_kbitems' name='kbitem' multiple='selected' size='5'>
|
||||||
|
{% with magic_number=-1 %}
|
||||||
|
<option value='{{magic_number}}'{% if magic_number|in_list:query_params.filtering.kbitem__in %} selected='selected'{% endif %}>
|
||||||
|
{% trans "Uncategorized" %}
|
||||||
|
</option>
|
||||||
|
{% endwith %}
|
||||||
|
{% for s in kbitem_choices %}
|
||||||
|
<option value='{{ s.0 }}'{% if s.0|in_list:query_params.filtering.kbitem__in %} selected='selected'{% endif %}>{{ s.1 }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-sm-6">
|
<div class="col col-sm-6">
|
||||||
<button class="filterBuilderRemove btn btn-danger btn-sm float-right"><i class="fas fa-trash-alt"></i></button>
|
<button class="filterBuilderRemove btn btn-danger btn-sm float-right"><i class="fas fa-trash-alt"></i></button>
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col col-sm-3">
|
<div class="col col-sm-3">
|
||||||
<select id='id_owners' name='assigned_to' multiple='selected' size='5'>
|
<select id='id_owners' name='assigned_to' multiple='selected' size='5'>
|
||||||
|
{% with magic_number=-1 %}
|
||||||
|
<option value='{{magic_number}}'{% if magic_number|in_list:query_params.filtering.assigned_to__id__in %} selected='selected'{% endif %}>
|
||||||
|
{% trans "Unassigned" %}
|
||||||
|
</option>
|
||||||
|
{% endwith %}
|
||||||
{% for u in user_choices %}
|
{% for u in user_choices %}
|
||||||
<option value='{{ u.id }}'{% if u.id|in_list:query_params.filtering.assigned_to__id__in %} selected='selected'{% endif %}>
|
<option value='{{ u.id }}'{% if u.id|in_list:query_params.filtering.assigned_to__id__in %} selected='selected'{% endif %}>
|
||||||
{{ u.get_username }}{% ifequal u user %} {% trans "(ME)" %}{% endifequal %}
|
{{ u.get_username }}{% ifequal u user %} {% trans "(ME)" %}{% endifequal %}
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
<th>{% trans "Owner" %}</th>
|
<th>{% trans "Owner" %}</th>
|
||||||
<th>{% trans "Submitter" %}</th>
|
<th>{% trans "Submitter" %}</th>
|
||||||
<th>{% trans "Time Spent" %}</th>
|
<th>{% trans "Time Spent" %}</th>
|
||||||
|
<th>{% trans "KB item" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@ -98,7 +99,7 @@
|
|||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label='{% trans "Set KB Item" %}'>
|
<optgroup label='{% trans "Set KB Item" %}'>
|
||||||
<option value='kbitem_none'>{% trans "No KB Item" %}</option>
|
<option value='kbitem_none'>{% trans "No KB Item" %}</option>
|
||||||
{% for kbi in kb_items %}<option value='kbitem_{{ kbi.id }}'>{{ kbi.title }}</option>{% endfor %}
|
{% for kbi in kb_items %}<option value='kbitem_{{ kbi.id }}'>{{kbi.category.title}}: {{ kbi.title }}</option>{% endfor %}
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-arrow-circle-right"></i> {% trans "Go" %}</button>
|
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-arrow-circle-right"></i> {% trans "Go" %}</button>
|
||||||
@ -307,6 +308,8 @@
|
|||||||
{
|
{
|
||||||
$( row ).addClass(data.row_class);
|
$( row ).addClass(data.row_class);
|
||||||
},
|
},
|
||||||
|
dom: 'ltBp',
|
||||||
|
buttons: ["colvis"],
|
||||||
|
|
||||||
"columns": [
|
"columns": [
|
||||||
{"data": "id",
|
{"data": "id",
|
||||||
@ -343,16 +346,18 @@
|
|||||||
priority = "danger";
|
priority = "danger";
|
||||||
}
|
}
|
||||||
return '<p class="text-'+priority+'">'+data+'</p>';
|
return '<p class="text-'+priority+'">'+data+'</p>';
|
||||||
}
|
},
|
||||||
|
"visible": false,
|
||||||
},
|
},
|
||||||
{"data": "queue",
|
{"data": "queue",
|
||||||
"render": function(data, type, row, meta) {
|
"render": function(data, type, row, meta) {
|
||||||
return data.title;
|
return data.title;
|
||||||
}
|
},
|
||||||
|
"visible": false,
|
||||||
},
|
},
|
||||||
{"data": "status"},
|
{"data": "status"},
|
||||||
{"data": "created"},
|
{"data": "created"},
|
||||||
{"data": "due_date"},
|
{"data": "due_date", "visible": false},
|
||||||
{"data": "assigned_to",
|
{"data": "assigned_to",
|
||||||
"render": function(data, type, row, meta) {
|
"render": function(data, type, row, meta) {
|
||||||
if (data != "None") {
|
if (data != "None") {
|
||||||
@ -364,7 +369,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{"data": "submitter"},
|
{"data": "submitter"},
|
||||||
{"data": "time_spent"},
|
{"data": "time_spent", "visible": false},
|
||||||
|
{"data": "kbitem"},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -819,6 +819,7 @@ def ticket_list(request):
|
|||||||
# a query, to be saved if needed:
|
# a query, to be saved if needed:
|
||||||
query_params = {
|
query_params = {
|
||||||
'filtering': {},
|
'filtering': {},
|
||||||
|
'filtering_or': {},
|
||||||
'sorting': None,
|
'sorting': None,
|
||||||
'sortreverse': False,
|
'sortreverse': False,
|
||||||
'search_string': '',
|
'search_string': '',
|
||||||
@ -884,12 +885,19 @@ def ticket_list(request):
|
|||||||
('status', 'status__in'),
|
('status', 'status__in'),
|
||||||
('kbitem', 'kbitem__in'),
|
('kbitem', 'kbitem__in'),
|
||||||
]
|
]
|
||||||
|
filter_null_params = dict([
|
||||||
|
('queue', 'queue__id__isnull'),
|
||||||
|
('assigned_to', 'assigned_to__id__isnull'),
|
||||||
|
('status', 'status__isnull'),
|
||||||
|
('kbitem', 'kbitem__isnull'),
|
||||||
|
])
|
||||||
for param, filter_command in filter_in_params:
|
for param, filter_command in filter_in_params:
|
||||||
patterns = request.GET.getlist(param)
|
if not request.GET.get(param) is None:
|
||||||
if patterns:
|
patterns = request.GET.getlist(param)
|
||||||
try:
|
try:
|
||||||
pattern_pks = [int(pattern) for pattern in patterns]
|
pattern_pks = [int(pattern) for pattern in patterns]
|
||||||
|
if -1 in pattern_pks:
|
||||||
|
query_params['filtering_or'][filter_null_params[param]] = True
|
||||||
query_params['filtering'][filter_command] = pattern_pks
|
query_params['filtering'][filter_command] = pattern_pks
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user