make transmitter creation and edit forms dyanmic based on type
Re-implementing the case-on-type of the prior db UI. To keep CSP happy along with the fact that we dynamically load the modal with django-bootstrap-modal, the javascript for these modals is in a new file, and that file's hash is kept in the CSP. Also re-introduces child_src to test fixing a safari mapbox bug Relates to #233 Fixes #387spacecruft
parent
b41b77be94
commit
2b80a3a88f
|
@ -23,11 +23,18 @@ class TransmitterModelForm(BSModalModelForm): # pylint: disable=too-many-ancest
|
|||
"""Model Form class for TransmitterEntry objects"""
|
||||
class Meta:
|
||||
model = TransmitterEntry
|
||||
# yapf: disable
|
||||
fields = [
|
||||
'description', 'status', 'type', 'uplink_low', 'uplink_high', 'downlink_low',
|
||||
'downlink_high', 'uplink_drift', 'downlink_drift', 'downlink_mode', 'uplink_mode',
|
||||
'invert', 'baud', 'citation', 'service'
|
||||
'description', 'type', 'status', 'uplink_low', 'uplink_high', 'uplink_drift',
|
||||
'uplink_mode', 'downlink_low', 'downlink_high', 'downlink_drift',
|
||||
'downlink_mode', 'invert', 'baud', 'citation', 'service'
|
||||
]
|
||||
# yapf: enable
|
||||
labels = {
|
||||
'downlink_low': _('Downlink'),
|
||||
'uplink_low': _('Uplink'),
|
||||
'invert': _('Inverted Transponder?'),
|
||||
}
|
||||
widgets = {
|
||||
'description': TextInput(),
|
||||
}
|
||||
|
@ -37,11 +44,19 @@ class TransmitterUpdateForm(BSModalModelForm): # pylint: disable=too-many-ances
|
|||
"""Model Form class for TransmitterEntry objects"""
|
||||
class Meta:
|
||||
model = TransmitterEntry
|
||||
# yapf: disable
|
||||
fields = [
|
||||
'description', 'status', 'type', 'service', 'uplink_low', 'uplink_drift',
|
||||
'uplink_high', 'downlink_low', 'uplink_mode', 'downlink_drift', 'downlink_high',
|
||||
'downlink_mode', 'invert', 'baud', 'created', 'citation'
|
||||
'description', 'type', 'status', 'uplink_low', 'uplink_high', 'uplink_drift',
|
||||
'uplink_mode', 'downlink_low', 'downlink_high', 'downlink_drift',
|
||||
'downlink_mode', 'invert', 'baud', 'citation', 'service', 'created'
|
||||
]
|
||||
# yapf: enable
|
||||
labels = {
|
||||
'downlink_low': _('Downlink'),
|
||||
'uplink_low': _('Uplink'),
|
||||
'invert': _('Inverted Transponder?'),
|
||||
'created': _('Updated'),
|
||||
}
|
||||
widgets = {
|
||||
'description': TextInput(),
|
||||
'created': TextInput(attrs={'readonly': True}),
|
||||
|
|
|
@ -315,7 +315,7 @@ class TransmitterEntry(models.Model):
|
|||
blank=True,
|
||||
null=True,
|
||||
validators=[MinValueValidator(-99999), MaxValueValidator(99999)],
|
||||
help_text="Hz"
|
||||
help_text="PPB"
|
||||
)
|
||||
downlink_low = models.BigIntegerField(
|
||||
blank=True,
|
||||
|
@ -339,7 +339,7 @@ class TransmitterEntry(models.Model):
|
|||
blank=True,
|
||||
null=True,
|
||||
validators=[MinValueValidator(-99999), MaxValueValidator(99999)],
|
||||
help_text="Hz"
|
||||
help_text="PPB"
|
||||
)
|
||||
downlink_mode = models.ForeignKey(
|
||||
Mode,
|
||||
|
|
|
@ -295,6 +295,7 @@ CSP_SCRIPT_SRC = config(
|
|||
'https://*.google-analytics.com,'
|
||||
'https://kit-free.fontawesome.com,'
|
||||
'https://kit.fontawesome.com,'
|
||||
"'sha256-poSsg4msM/d4NUuFqtWj+1p7OhspHij16g58RBWo7Nk='," # transmitter_modal.js
|
||||
)
|
||||
CSP_IMG_SRC = config(
|
||||
'CSP_IMG_SRC',
|
||||
|
@ -315,6 +316,9 @@ CSP_WORKER_SRC = config(
|
|||
default="'self',"
|
||||
'blob:'
|
||||
)
|
||||
CSP_CHILD_SRC = config(
|
||||
'CSP_CHILD_SRC', cast=lambda v: tuple(s.strip() for s in v.split(',')), default='blob:'
|
||||
)
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
|
||||
SECURE_CONTENT_TYPE_NOSNIFF = True
|
||||
SECURE_BROWSER_XSS_FILTER = True
|
||||
|
|
|
@ -23,51 +23,6 @@ function copyToClipboard(text, el) {
|
|||
}
|
||||
}
|
||||
|
||||
function transmitter_suggestion_type(selection) {
|
||||
switch(selection){
|
||||
case 'Transmitter':
|
||||
$('.input-group').show();
|
||||
$('input').prop( 'disabled', false );
|
||||
$('select').prop( 'disabled', false );
|
||||
$('input[name=\'uplink_low\']').prop( 'disabled', true );
|
||||
$('input[name=\'uplink_high\']').prop( 'disabled', true );
|
||||
$('input[name=\'uplink_drift\']').prop( 'disabled', true );
|
||||
$('input[name=\'downlink_high\']').prop( 'disabled', true );
|
||||
$('input[name=\'invert\']').prop( 'disabled', true );
|
||||
$('select[name=\'uplink_mode\']').prop( 'disabled', true );
|
||||
$('.input-group').has('input[name=\'uplink_low\']').hide();
|
||||
$('.input-group').has('input[name=\'uplink_high\']').hide();
|
||||
$('.input-group').has('input[name=\'uplink_drift\']').hide();
|
||||
$('.input-group').has('input[name=\'downlink_high\']').hide();
|
||||
$('.input-group').has('input[name=\'invert\']').hide();
|
||||
$('.input-group').has('select[name=\'uplink_mode\']').hide();
|
||||
|
||||
$('.input-group-prepend:contains(\'Downlink Low\')').html('<span class="input-group-text">Downlink</span>');
|
||||
break;
|
||||
case 'Transceiver':
|
||||
$('.input-group').show();
|
||||
$('input').prop( 'disabled', false );
|
||||
$('select').prop( 'disabled', false );
|
||||
$('input[name=\'uplink_high\']').prop( 'disabled', true );
|
||||
$('input[name=\'downlink_high\']').prop( 'disabled', true );
|
||||
$('input[name=\'invert\']').prop( 'disabled', true );
|
||||
$('.input-group').has('input[name=\'uplink_high\']').hide();
|
||||
$('.input-group').has('input[name=\'downlink_high\']').hide();
|
||||
$('.input-group').has('input[name=\'invert\']').hide();
|
||||
|
||||
$('input[name=\'downlink_low\']').prev().html('<span class="input-group-text">Downlink</span>');
|
||||
$('input[name=\'uplink_low\']').prev().html('<span class="input-group-text">Uplink</span>');
|
||||
break;
|
||||
case 'Transponder':
|
||||
$('.input-group').show();
|
||||
$('input').prop( 'disabled', false );
|
||||
$('select').prop( 'disabled', false );
|
||||
$('input[name=\'downlink_low\']').prev().html('<span class="input-group-text">Downlink Low</span>');
|
||||
$('input[name=\'uplink_low\']').prev().html('<span class="input-group-text">Uplink Low</span>');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function ppb_to_freq(freq, drift) {
|
||||
var freq_obs = freq + ((freq * drift) / Math.pow(10,9));
|
||||
return Math.round(freq_obs);
|
||||
|
@ -94,28 +49,6 @@ function format_freq(freq) {
|
|||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.transmitter_suggestion-type').on('change click', function(){
|
||||
var selection = $(this).val();
|
||||
transmitter_suggestion_type(selection);
|
||||
});
|
||||
|
||||
$('.transmitter_suggestion-modal').on('show.bs.modal', function(){
|
||||
var selection = $(this).find('.transmitter_suggestion-type').val();
|
||||
transmitter_suggestion_type(selection);
|
||||
|
||||
var downlink_ppb = parseInt($(this).find('.downlink-ppb-sugedit').val());
|
||||
if(downlink_ppb){
|
||||
var freq_down = parseInt($(this).find('input[name=\'downlink_low\']').val());
|
||||
$('.downlink-drifted-sugedit').val(ppb_to_freq(freq_down,downlink_ppb));
|
||||
}
|
||||
|
||||
var uplink_ppb = parseInt($(this).find('.uplink-ppb-sugedit').val());
|
||||
if(uplink_ppb){
|
||||
var freq_up = parseInt($(this).find('input[name=\'uplink_low\']').val());
|
||||
$('.uplink-drifted-sugedit').val(ppb_to_freq(freq_up,uplink_ppb));
|
||||
}
|
||||
});
|
||||
|
||||
// Calculate the drifted frequencies
|
||||
$('.drifted').each(function() {
|
||||
var drifted = ppb_to_freq($(this).data('freq_or'),$(this).data('drift'));
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// This script handles adjustments in the user interface of the transmitter
|
||||
// modals (like changing between Transmitter, Transceiver, and Transponder)
|
||||
//
|
||||
// NOTE: Since this script is loaded dynamically after page load, we have
|
||||
// to be cautious of CSP requirements. Any changes to this script will need
|
||||
// to have the hash recalculated and changed in settings.py under
|
||||
// CSP_SCRIPT_SRC
|
||||
|
||||
function transmitter_suggestion_type(selection) {
|
||||
switch(selection){
|
||||
case 'Transmitter':
|
||||
$('.input-group').has('input[name=\'uplink_low\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_high\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_drift\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'downlink_high\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'invert\']').addClass('d-none');
|
||||
$('.input-group').has('select[name=\'uplink_mode\']').addClass('d-none');
|
||||
$('input[name=\'uplink_high\']').val('');
|
||||
$('input[name=\'downlink_high\']').val('');
|
||||
$('select[name=\'invert\']').removeAttr('checked');
|
||||
$('input[name=\'uplink_low\']').val('');
|
||||
$('input[name=\'uplink_drift\']').val('');
|
||||
$('select[name=\'uplink_mode\']').val('');
|
||||
$('.input-group-prepend:contains(\'Downlink Low\')').html('Downlink');
|
||||
break;
|
||||
case 'Transceiver':
|
||||
$('.input-group').has('input[name=\'uplink_high\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'downlink_high\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'invert\']').addClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_low\']').removeClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_drift\']').removeClass('d-none');
|
||||
$('.input-group').has('select[name=\'uplink_mode\']').removeClass('d-none');
|
||||
$('input[name=\'uplink_high\']').val('');
|
||||
$('input[name=\'downlink_high\']').val('');
|
||||
$('select[name=\'invert\']').removeAttr('checked');
|
||||
$('input[name=\'downlink_low\']').prev().html('Downlink');
|
||||
$('input[name=\'uplink_low\']').prev().html('Uplink');
|
||||
break;
|
||||
case 'Transponder':
|
||||
$('.input-group').has('input[name=\'uplink_high\']').removeClass('d-none');
|
||||
$('.input-group').has('input[name=\'downlink_high\']').removeClass('d-none');
|
||||
$('.input-group').has('input[name=\'invert\']').removeClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_low\']').removeClass('d-none');
|
||||
$('.input-group').has('input[name=\'uplink_drift\']').removeClass('d-none');
|
||||
$('.input-group').has('select[name=\'uplink_mode\']').removeClass('d-none');
|
||||
$('input[name=\'downlink_low\']').prev().html('Downlink low');
|
||||
$('input[name=\'uplink_low\']').prev().html('Uplink low');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
transmitter_suggestion_type($('#id_type option:selected').text());
|
||||
|
||||
$('#id_type').on('change click', function () {
|
||||
var selection = $(this).val();
|
||||
transmitter_suggestion_type(selection);
|
||||
});
|
||||
});
|
|
@ -1,3 +1,4 @@
|
|||
{% load static %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
|
@ -21,7 +22,9 @@
|
|||
<div class="input-group my-1">
|
||||
<label class="input-group-prepend input-group-text" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{% render_field field class="form-control" placeholder=field.label %}
|
||||
{{ field.help_text }}
|
||||
{% if field.help_text %}
|
||||
<label class="input-group-text input-group-append">{{ field.help_text }}</label>
|
||||
{% endif %}
|
||||
<div class="{% if field.errors %} invalid{% endif %}">
|
||||
{% for error in field.errors %}
|
||||
<p class="help-block">{{ error }}</p>
|
||||
|
@ -35,6 +38,7 @@
|
|||
<button type="button" class="submit-btn btn btn-satnogs-primary">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
<script src="{% static 'js/transmitter_modal.js' %}"></script>
|
||||
{% else %}
|
||||
<div class="modal-body">
|
||||
<div class="text-danger">You need to login first to add a new transmitter suggestion.</div>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{% load static %}
|
||||
{% load widget_tweaks %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
|
@ -21,7 +22,9 @@
|
|||
<div class="input-group my-1">
|
||||
<label class="input-group-prepend input-group-text" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{% render_field field class="form-control" placeholder=field.label %}
|
||||
{{ field.help_text }}
|
||||
{% if field.help_text %}
|
||||
<label class="input-group-text input-group-append">{{ field.help_text }}</label>
|
||||
{% endif %}
|
||||
<div class="{% if field.errors %} invalid{% endif %}">
|
||||
{% for error in field.errors %}
|
||||
<p class="help-block">{{ error }}</p>
|
||||
|
@ -35,6 +38,7 @@
|
|||
<button type="button" class="submit-btn btn btn-satnogs-primary">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
<script src="{% static 'js/transmitter_modal.js' %}"></script>
|
||||
{% else %}
|
||||
<div class="modal-body">
|
||||
<div class="text-danger">You need to login first to add a new transmitter suggestion.</div>
|
||||
|
|
|
@ -15,6 +15,7 @@ docopts==0.6.1
|
|||
execnet==1.7.1
|
||||
factory-boy==2.12.0
|
||||
filelock==3.0.12
|
||||
iniconfig==1.0.1
|
||||
mock==4.0.2
|
||||
more-itertools==8.4.0
|
||||
packaging==20.4
|
||||
|
@ -26,9 +27,8 @@ pytest-cov==2.10.0
|
|||
pytest-django==3.9.0
|
||||
pytest-forked==1.2.0
|
||||
pytest-xdist==1.33.0
|
||||
pytest==5.4.3
|
||||
pytest==6.0.1
|
||||
text-unidecode==1.3
|
||||
toml==0.10.1
|
||||
tox==3.16.1
|
||||
virtualenv==20.0.28
|
||||
wcwidth==0.2.5
|
||||
tox==3.16.0
|
||||
virtualenv==20.0.29
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
# Please edit 'setup.cfg' to add top-level dependencies and use
|
||||
# './contrib/refresh-requirements.sh to regenerate this file
|
||||
|
||||
amqp==2.6.0
|
||||
amqp==2.6.1
|
||||
attrs==19.3.0
|
||||
billiard==3.6.3.0
|
||||
cachetools==4.1.1
|
||||
celery==4.3.0
|
||||
certifi==2020.6.20
|
||||
cffi==1.14.0
|
||||
cffi==1.14.1
|
||||
chardet==3.0.4
|
||||
cryptography==3.0
|
||||
defusedxml==0.6.0
|
||||
|
@ -31,9 +31,9 @@ django-redis-cache==2.0.0
|
|||
django-shortuuidfield==0.1.3
|
||||
django-widget-tweaks==1.4.8
|
||||
djangorestframework==3.10.3
|
||||
dnspython==2.0.0
|
||||
dnspython==1.16.0
|
||||
enum34==1.1.10
|
||||
eventlet==0.25.2
|
||||
eventlet==0.26.1
|
||||
frozendict==1.2
|
||||
greenlet==0.4.16
|
||||
gunicorn==19.9.0
|
||||
|
@ -70,7 +70,7 @@ rjsmin==1.1.0
|
|||
rush==2018.12.1
|
||||
satellitetle==0.9.0
|
||||
satnogs-decoders==1.7.0
|
||||
sentry-sdk==0.16.2
|
||||
sentry-sdk==0.16.3
|
||||
sgp4==2.12
|
||||
shortuuid==1.0.1
|
||||
simplejson==3.17.2
|
||||
|
|
Loading…
Reference in New Issue