1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Merge branch '3090-interface-filtering' of https://github.com/hSaria/netbox into 3090-interface-filtering

This commit is contained in:
Saria Hajjar
2020-01-06 20:05:25 +00:00
5 changed files with 71 additions and 2 deletions

View File

@ -2,7 +2,9 @@
## Enhancements ## Enhancements
* [#2050](https://github.com/netbox-community/netbox/issues/2050) - Preview image attachments when hovering the link
* [#3090](https://github.com/netbox-community/netbox/issues/3090) - Add filter field for device interfaces * [#3090](https://github.com/netbox-community/netbox/issues/3090) - Add filter field for device interfaces
* [#3187](https://github.com/netbox-community/netbox/issues/3187) - Add rack selection field to rack elevations
--- ---

View File

@ -703,6 +703,34 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
) )
#
# Rack elevations
#
class RackElevationFilterForm(RackFilterForm):
field_order = ['q', 'region', 'site', 'group_id', 'id', 'status', 'role', 'tenant_group', 'tenant']
id = ChainedModelChoiceField(
queryset=Rack.objects.all(),
label='Rack',
chains=(
('site', 'site'),
('group_id', 'group_id'),
),
required=False,
widget=APISelectMultiple(
api_url='/api/dcim/racks/',
display_field='display_name',
)
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Filter the rack field based on the site and group
self.fields['site'].widget.add_filter_for('id', 'site')
self.fields['group_id'].widget.add_filter_for('id', 'group_id')
# #
# Rack reservations # Rack reservations
# #

View File

@ -388,7 +388,7 @@ class RackElevationListView(PermissionRequiredMixin, View):
'page': page, 'page': page,
'total_count': total_count, 'total_count': total_count,
'face_id': face_id, 'face_id': face_id,
'filter_form': forms.RackFilterForm(request.GET), 'filter_form': forms.RackElevationFilterForm(request.GET),
}) })

View File

@ -398,4 +398,43 @@ $(document).ready(function() {
// Account for the header height when hash-scrolling // Account for the header height when hash-scrolling
window.addEventListener('load', headerOffsetScroll); window.addEventListener('load', headerOffsetScroll);
window.addEventListener('hashchange', headerOffsetScroll); window.addEventListener('hashchange', headerOffsetScroll);
// Offset between the preview window and the window edges
const IMAGE_PREVIEW_OFFSET_X = 20
const IMAGE_PREVIEW_OFFSET_Y = 10
// Preview an image attachment when the link is hovered over
$('a.image-preview').on('mouseover', function(e) {
// Twice the offset to account for all sides of the picture
var maxWidth = window.innerWidth - (e.clientX + (IMAGE_PREVIEW_OFFSET_X * 2));
var maxHeight = window.innerHeight - (e.clientY + (IMAGE_PREVIEW_OFFSET_Y * 2));
var img = $('<img>').attr('id', 'image-preview-window').css({
display: 'none',
position: 'absolute',
maxWidth: maxWidth + 'px',
maxHeight: maxHeight + 'px',
left: e.pageX + IMAGE_PREVIEW_OFFSET_X + 'px',
top: e.pageY + IMAGE_PREVIEW_OFFSET_Y + 'px',
boxShadow: '0 0px 12px 3px rgba(0, 0, 0, 0.4)',
});
// Remove any existing preview windows and add the current one
$('#image-preview-window').remove();
$('body').append(img);
// Once loaded, show the preview if the image is indeed an image
img.on('load', function(e) {
if (e.target.complete && e.target.naturalWidth) {
$('#image-preview-window').fadeIn('fast');
}
});
// Begin loading
img.attr('src', e.target.href);
});
// Fade the image out; it will be deleted when another one is previewed
$('a.image-preview').on('mouseout', function() {
$('#image-preview-window').fadeOut('fast')
});
}); });

View File

@ -10,7 +10,7 @@
<tr{% if not attachment.size %} class="danger"{% endif %}> <tr{% if not attachment.size %} class="danger"{% endif %}>
<td> <td>
<i class="fa fa-image"></i> <i class="fa fa-image"></i>
<a href="{{ attachment.image.url }}" target="_blank">{{ attachment }}</a> <a class="image-preview" href="{{ attachment.image.url }}" target="_blank">{{ attachment }}</a>
</td> </td>
<td>{{ attachment.size|filesizeformat }}</td> <td>{{ attachment.size|filesizeformat }}</td>
<td>{{ attachment.created }}</td> <td>{{ attachment.created }}</td>