Skip to content

Commit 18f2067

Browse files
committed
Closes #6088: Improved table configuration form
1 parent 0bce1da commit 18f2067

File tree

6 files changed

+55
-21
lines changed

6 files changed

+55
-21
lines changed

docs/release-notes/version-2.11.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Enhancements (from Beta)
66

7+
* [#6088](https://github.com/netbox-community/netbox/issues/6088) - Improved table configuration form
78
* [#6097](https://github.com/netbox-community/netbox/issues/6097) - Redirect old slug-based object views
89
* [#6109](https://github.com/netbox-community/netbox/issues/6109) - Add device counts to locations table
910
* [#6121](https://github.com/netbox-community/netbox/issues/6121) - Extend parent interface assignment to VM interfaces

netbox/netbox/views/generic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def get(self, request):
182182
if request.GET.get('export') == 'table':
183183
exclude_columns = {'pk'}
184184
exclude_columns.update({
185-
col for col in table.base_columns if col not in table.visible_columns
185+
name for name, _ in table.available_columns
186186
})
187187
exporter = TableExport(
188188
export_format=TableExport.CSV,

netbox/project-static/js/tableconfig.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
$(document).ready(function() {
2-
$('form.userconfigform input.reset').click(function(event) {
3-
// Deselect all columns when the reset button is clicked
2+
3+
// Select or reset table columns
4+
$('#save_tableconfig').click(function(event) {
5+
$('select[name="columns"] option').attr("selected", "selected");
6+
});
7+
$('#reset_tableconfig').click(function(event) {
48
$('select[name="columns"]').val([]);
59
});
610

11+
// Swap columns between available and selected lists
12+
$('#add_columns').click(function(e) {
13+
let selected_columns = $('#id_available_columns option:selected');
14+
$('#id_columns').append($(selected_columns).clone());
15+
$(selected_columns).remove();
16+
e.preventDefault();
17+
});
18+
$('#remove_columns').click(function(e) {
19+
let selected_columns = $('#id_columns option:selected');
20+
$('#id_available_columns').append($(selected_columns).clone());
21+
$(selected_columns).remove();
22+
e.preventDefault();
23+
});
24+
725
$('form.userconfigform').submit(function(event) {
826
event.preventDefault();
927

netbox/templates/utilities/templatetags/table_config_form.html

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,23 @@ <h4 class="modal-title">Table Configuration</h4>
88
</div>
99
<div class="modal-body">
1010
<form class="form-horizontal userconfigform" data-config-root="tables.{{ table_config_form.table_name }}">
11-
{% render_form table_config_form %}
12-
<div class="row">
11+
{% render_field table_config_form.available_columns %}
12+
<div class="form-group">
13+
<div class="col-md-9 col-md-offset-3">
14+
<a class="btn btn-success btn-xs" id="add_columns"><i class="mdi mdi-arrow-down-bold"></i> Add columns</a>
15+
<a class="btn btn-danger btn-xs" id="remove_columns"><i class="mdi mdi-arrow-up-bold"></i> Remove columns</a>
16+
</div>
17+
</div>
18+
{% render_field table_config_form.columns %}
19+
<div class="form-group">
1320
<div class="col-md-9 col-md-offset-3">
1421
<a class="btn btn-primary btn-xs" id="move-option-up" data-target="id_columns"><i class="mdi mdi-arrow-up-bold"></i> Move up</a>
1522
<a class="btn btn-primary btn-xs" id="move-option-down" data-target="id_columns"><i class="mdi mdi-arrow-down-bold"></i> Move down</a>
16-
<a class="btn btn-success btn-xs" id="select-all-options" data-target="id_columns"><i class="mdi mdi-expand-all-outline"></i> Select all</a>
1723
</div>
1824
</div>
1925
<div class="text-right">
20-
<input type="submit" class="btn btn-primary" value="Save" />
21-
<input type="submit" class="btn btn-danger reset" value="Reset" />
26+
<input type="submit" class="btn btn-primary" id="save_tableconfig" value="Save" />
27+
<input type="submit" class="btn btn-danger" id="reset_tableconfig" value="Reset" />
2228
</div>
2329
</form>
2430
</div>

netbox/utilities/forms/forms.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,21 @@ class TableConfigForm(BootstrapMixin, forms.Form):
161161
"""
162162
Form for configuring user's table preferences.
163163
"""
164+
available_columns = forms.MultipleChoiceField(
165+
choices=[],
166+
required=False,
167+
widget=forms.SelectMultiple(
168+
attrs={'size': 10}
169+
),
170+
label='Available columns'
171+
)
164172
columns = forms.MultipleChoiceField(
165173
choices=[],
166174
required=False,
167175
widget=forms.SelectMultiple(
168176
attrs={'size': 10}
169177
),
170-
help_text="Use the buttons below to arrange columns in the desired order, then select all columns to display."
178+
label='Selected columns'
171179
)
172180

173181
def __init__(self, table, *args, **kwargs):
@@ -176,8 +184,8 @@ def __init__(self, table, *args, **kwargs):
176184
super().__init__(*args, **kwargs)
177185

178186
# Initialize columns field based on table attributes
179-
self.fields['columns'].choices = table.configurable_columns
180-
self.fields['columns'].initial = table.visible_columns
187+
self.fields['available_columns'].choices = table.available_columns
188+
self.fields['columns'].choices = table.selected_columns
181189

182190
@property
183191
def table_name(self):

netbox/utilities/tables.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,20 @@ def __init__(self, *args, user=None, **kwargs):
107107
prefetch_fields.append('__'.join(prefetch_path))
108108
self.data.data = self.data.data.prefetch_related(None).prefetch_related(*prefetch_fields)
109109

110+
def _get_columns(self, visible=True):
111+
columns = []
112+
for name, column in self.columns.items():
113+
if column.visible == visible and name not in ['pk', 'actions']:
114+
columns.append((name, column.verbose_name))
115+
return columns
116+
110117
@property
111-
def configurable_columns(self):
112-
selected_columns = [
113-
(name, self.columns[name].verbose_name) for name in self.sequence if name not in ['pk', 'actions']
114-
]
115-
available_columns = [
116-
(name, column.verbose_name) for name, column in self.columns.items() if name not in self.sequence and name not in ['pk', 'actions']
117-
]
118-
return selected_columns + available_columns
118+
def available_columns(self):
119+
return self._get_columns(visible=False)
119120

120121
@property
121-
def visible_columns(self):
122-
return [name for name in self.sequence if self.columns[name].visible]
122+
def selected_columns(self):
123+
return self._get_columns(visible=True)
123124

124125

125126
#

0 commit comments

Comments
 (0)