mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-03-03 18:48:23 +00:00
Merge branch 'master' into fixed_jquery
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# TEC PA & Lighting - PyRIGS #
|
# TEC PA & Lighting - PyRIGS #
|
||||||
[](https://app.wercker.com/project/bykey/b26100ecccdfb46a9a9056553daac5b7)
|
[](https://app.wercker.com/project/bykey/2dbe0517c3d83859c985ffc5a55a2802)
|
||||||
|
|
||||||
Welcome to TEC PA & Lightings PyRIGS program. This is a reimplementation of the existing Rig Information Gathering System (RIGS) that was developed using Ruby on Rails.
|
Welcome to TEC PA & Lightings PyRIGS program. This is a reimplementation of the existing Rig Information Gathering System (RIGS) that was developed using Ruby on Rails.
|
||||||
|
|
||||||
|
|||||||
20
RIGS/migrations/0024_auto_20160229_2042.py
Normal file
20
RIGS/migrations/0024_auto_20160229_2042.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('RIGS', '0023_auto_20150529_0048'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='event',
|
||||||
|
name='based_on',
|
||||||
|
field=models.ForeignKey(related_name='future_events', on_delete=django.db.models.deletion.SET_NULL, blank=True, to='RIGS.Event', null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -301,7 +301,7 @@ class Event(models.Model, RevisionMixin):
|
|||||||
status = models.IntegerField(choices=EVENT_STATUS_CHOICES, default=PROVISIONAL)
|
status = models.IntegerField(choices=EVENT_STATUS_CHOICES, default=PROVISIONAL)
|
||||||
dry_hire = models.BooleanField(default=False)
|
dry_hire = models.BooleanField(default=False)
|
||||||
is_rig = models.BooleanField(default=True)
|
is_rig = models.BooleanField(default=True)
|
||||||
based_on = models.ForeignKey('Event', related_name='future_events', blank=True, null=True)
|
based_on = models.ForeignKey('Event', on_delete=models.SET_NULL, related_name='future_events', blank=True, null=True)
|
||||||
|
|
||||||
# Timing
|
# Timing
|
||||||
start_date = models.DateField()
|
start_date = models.DateField()
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ class RigboardIndex(generic.TemplateView):
|
|||||||
class WebCalendar(generic.TemplateView):
|
class WebCalendar(generic.TemplateView):
|
||||||
template_name = 'RIGS/calendar.html'
|
template_name = 'RIGS/calendar.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(WebCalendar, self).get_context_data(**kwargs)
|
||||||
|
context['view'] = kwargs.get('view','')
|
||||||
|
context['date'] = kwargs.get('date','')
|
||||||
|
return context
|
||||||
|
|
||||||
class EventDetail(generic.DetailView):
|
class EventDetail(generic.DetailView):
|
||||||
model = models.Event
|
model = models.Event
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ fonts_dir = "fonts"
|
|||||||
|
|
||||||
# You can select your preferred output style here (can be overridden via the command line):
|
# You can select your preferred output style here (can be overridden via the command line):
|
||||||
# output_style = :expanded or :nested or :compact or :compressed
|
# output_style = :expanded or :nested or :compact or :compressed
|
||||||
|
output_style = :compressed
|
||||||
|
|
||||||
# To enable relative paths to assets via compass helper functions. Uncomment:
|
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||||
# relative_assets = true
|
# relative_assets = true
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -75,6 +75,16 @@ textarea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
del {
|
||||||
|
background-color: #f2dede;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ins {
|
||||||
|
background-color: #dff0d8;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.loading-animation {
|
.loading-animation {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 30px auto 0;
|
margin: 30px auto 0;
|
||||||
|
|||||||
@@ -14,8 +14,28 @@
|
|||||||
<script src="{% static "js/moment.min.js" %}"></script>
|
<script src="{% static "js/moment.min.js" %}"></script>
|
||||||
<script src="{% static "js/fullcalendar.js" %}"></script>
|
<script src="{% static "js/fullcalendar.js" %}"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
function getUrlVars() {
|
||||||
|
var vars = {};
|
||||||
|
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
|
||||||
|
vars[key] = value;
|
||||||
|
});
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
viewToUrl = {
|
||||||
|
'agendaWeek':'week',
|
||||||
|
'agendaDay':'day',
|
||||||
|
'month':'month'
|
||||||
|
}
|
||||||
|
viewFromUrl = {
|
||||||
|
'week':'agendaWeek',
|
||||||
|
'day':'agendaDay',
|
||||||
|
'month':'month'
|
||||||
|
}
|
||||||
|
|
||||||
$('#calendar').fullCalendar({
|
$('#calendar').fullCalendar({
|
||||||
editable: false,
|
editable: false,
|
||||||
eventLimit: true, // allow "more" link when too many events
|
eventLimit: true, // allow "more" link when too many events
|
||||||
@@ -114,8 +134,11 @@
|
|||||||
$('#day-button').addClass('active');
|
$('#day-button').addClass('active');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
history.replaceState(null,null,'{% url 'web_calendar' %}'+viewToUrl[view.name]+'/'+view.intervalStart.format('YYYY-MM-DD')+'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// set some button listeners
|
// set some button listeners
|
||||||
@@ -146,6 +169,18 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Go to the initial settings, if they're valid
|
||||||
|
view = viewFromUrl['{{view}}'];
|
||||||
|
$('#calendar').fullCalendar( 'changeView', view);
|
||||||
|
|
||||||
|
day = moment('{{date}}');
|
||||||
|
if(day.isValid()){
|
||||||
|
$('#calendar').fullCalendar( 'gotoDate', day);
|
||||||
|
}else{
|
||||||
|
console.log('Supplied date is invalid - using default')
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,40 +1,21 @@
|
|||||||
{% for change in version.field_changes %}
|
{% for change in version.field_changes %}
|
||||||
|
|
||||||
<button title="Changes to {{ change.field.verbose_name }}" type="button" class="btn btn-default btn-xs" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='
|
<button title="Changes to {{ change.field.verbose_name }}" type="button" class="btn btn-default btn-xs" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
||||||
|
{% include "RIGS/version_changes_change.html" %}
|
||||||
{% if change.new %}
|
{% endspaceless %}'>{{ change.field.verbose_name }}</button>
|
||||||
<div class="alert alert-success {% if change.long %}overflow-ellipsis{% endif %}">
|
|
||||||
{% if change.linebreaks %}
|
|
||||||
{{change.new|linebreaksbr}}
|
|
||||||
{% else %}
|
|
||||||
{{change.new}}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if change.old %}
|
|
||||||
<div class="alert alert-danger {% if change.long %}overflow-ellipsis{% endif %}">
|
|
||||||
{% if change.linebreaks %}
|
|
||||||
{{change.old|linebreaksbr}}
|
|
||||||
{% else %}
|
|
||||||
{{change.old}}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
'>{{ change.field.verbose_name }}</button>
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for itemChange in version.item_changes %}
|
{% for itemChange in version.item_changes %}
|
||||||
<button title="Changes to item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'" type="button" class="btn btn-default btn-xs" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='
|
<button title="Changes to item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'" type="button" class="btn btn-default btn-xs" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
||||||
|
<ul class="list-group">
|
||||||
{% for change in itemChange.changes %}
|
{% for change in itemChange.changes %}
|
||||||
<h4>{{ change.field.verbose_name }}</h4>
|
<li class="list-group-item">
|
||||||
|
<h4 class="list-group-item-heading">{{ change.field.verbose_name }}</h4>
|
||||||
{% if change.new %}<div class="alert alert-success">{{change.new|linebreaksbr}}</div>{% endif %}
|
{% include "RIGS/version_changes_change.html" %}
|
||||||
{% if change.old %}<div class="alert alert-danger">{{change.old|linebreaksbr}}</div>{% endif %}
|
</li>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
'>item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'</button>
|
{% endspaceless %}'>item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
26
RIGS/templates/RIGS/version_changes_change.html
Normal file
26
RIGS/templates/RIGS/version_changes_change.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{# pass in variable "change" to this template #}
|
||||||
|
{% if change.linebreaks and change.new and change.old %}
|
||||||
|
{% for diff in change.diff %}
|
||||||
|
{% if diff.type == "insert" %}
|
||||||
|
<ins>{{ diff.text|linebreaksbr }}</ins>
|
||||||
|
{% elif diff.type == "delete" %}
|
||||||
|
<del>{{diff.text|linebreaksbr}}</del>
|
||||||
|
{% else %}
|
||||||
|
<span>{{diff.text|linebreaksbr}}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% if change.old %}
|
||||||
|
<del {% if change.long %}class="overflow-ellipsis"{% endif %}>
|
||||||
|
{{change.old}}
|
||||||
|
</del>
|
||||||
|
{% endif %}
|
||||||
|
{% if change.new and change.old %}
|
||||||
|
<br/>
|
||||||
|
{% endif %}
|
||||||
|
{% if change.new %}
|
||||||
|
<ins {% if change.long %}class="overflow-ellipsis"{% endif %}>
|
||||||
|
{{change.new}}
|
||||||
|
</ins>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
@@ -420,8 +420,9 @@ class EventTest(LiveServerTestCase):
|
|||||||
e.send_keys(Keys.ENTER)
|
e.send_keys(Keys.ENTER)
|
||||||
|
|
||||||
# See redirected to success page
|
# See redirected to success page
|
||||||
|
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||||
event = models.Event.objects.get(name='Test Event Name')
|
event = models.Event.objects.get(name='Test Event Name')
|
||||||
self.assertIn("N0000%d | Test Event Name"%event.pk, self.browser.find_element_by_xpath('//h1').text)
|
self.assertIn("N0000%d | Test Event Name"%event.pk, successTitle)
|
||||||
|
|
||||||
def testEventDuplicate(self):
|
def testEventDuplicate(self):
|
||||||
testEvent = models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL, start_date=date.today() + timedelta(days=6), description="start future no end")
|
testEvent = models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL, start_date=date.today() + timedelta(days=6), description="start future no end")
|
||||||
@@ -608,8 +609,9 @@ class EventTest(LiveServerTestCase):
|
|||||||
save.click()
|
save.click()
|
||||||
|
|
||||||
# See redirected to success page
|
# See redirected to success page
|
||||||
|
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||||
event = models.Event.objects.get(name='Test Event Name')
|
event = models.Event.objects.get(name='Test Event Name')
|
||||||
self.assertIn("N0000%d | Test Event Name"%event.pk, self.browser.find_element_by_xpath('//h1').text)
|
self.assertIn("N0000%d | Test Event Name"%event.pk, successTitle)
|
||||||
|
|
||||||
def testRigNonRig(self):
|
def testRigNonRig(self):
|
||||||
self.browser.get(self.live_server_url + '/event/create/')
|
self.browser.get(self.live_server_url + '/event/create/')
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ urlpatterns = patterns('',
|
|||||||
# Rigboard
|
# Rigboard
|
||||||
url(r'^rigboard/$', login_required(rigboard.RigboardIndex.as_view()), name='rigboard'),
|
url(r'^rigboard/$', login_required(rigboard.RigboardIndex.as_view()), name='rigboard'),
|
||||||
url(r'^rigboard/calendar/$', login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
url(r'^rigboard/calendar/$', login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
||||||
|
url(r'^rigboard/calendar/(?P<view>(month|week|day))/$', login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
||||||
|
url(r'^rigboard/calendar/(?P<view>(month|week|day))/(?P<date>(\d{4}-\d{2}-\d{2}))/$', login_required()(rigboard.WebCalendar.as_view()), name='web_calendar'),
|
||||||
url(r'^rigboard/archive/$', RedirectView.as_view(permanent=True,pattern_name='event_archive')),
|
url(r'^rigboard/archive/$', RedirectView.as_view(permanent=True,pattern_name='event_archive')),
|
||||||
url(r'^rigboard/activity/$',
|
url(r'^rigboard/activity/$',
|
||||||
permission_required_with_403('RIGS.view_event')(versioning.ActivityTable.as_view()),
|
permission_required_with_403('RIGS.view_event')(versioning.ActivityTable.as_view()),
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from reversion.models import Version
|
|||||||
from django.contrib.contenttypes.models import ContentType # Used to lookup the content_type
|
from django.contrib.contenttypes.models import ContentType # Used to lookup the content_type
|
||||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
from django.db.models import ForeignKey, IntegerField, EmailField, TextField
|
from django.db.models import ForeignKey, IntegerField, EmailField, TextField
|
||||||
|
from diff_match_patch import diff_match_patch
|
||||||
|
|
||||||
from RIGS import models, forms
|
from RIGS import models, forms
|
||||||
import datetime
|
import datetime
|
||||||
@@ -64,6 +65,25 @@ def model_compare(oldObj, newObj, excluded_keys=[]):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def diff(self):
|
||||||
|
oldText = unicode(self.display_value(self._old)) or ""
|
||||||
|
newText = unicode(self.display_value(self._new)) or ""
|
||||||
|
dmp = diff_match_patch()
|
||||||
|
diffs = dmp.diff_main(oldText, newText)
|
||||||
|
dmp.diff_cleanupSemantic(diffs)
|
||||||
|
|
||||||
|
outputDiffs = []
|
||||||
|
|
||||||
|
for (op, data) in diffs:
|
||||||
|
if op == dmp.DIFF_INSERT:
|
||||||
|
outputDiffs.append({'type':'insert', 'text':data})
|
||||||
|
elif op == dmp.DIFF_DELETE:
|
||||||
|
outputDiffs.append({'type':'delete', 'text':data})
|
||||||
|
elif op == dmp.DIFF_EQUAL:
|
||||||
|
outputDiffs.append({'type':'equal', 'text':data})
|
||||||
|
return outputDiffs
|
||||||
|
|
||||||
changes = []
|
changes = []
|
||||||
|
|
||||||
for thisField in theFields:
|
for thisField in theFields:
|
||||||
|
|||||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@@ -1,3 +1,4 @@
|
|||||||
|
diff-match-patch==20121119
|
||||||
dj-database-url==0.3.0
|
dj-database-url==0.3.0
|
||||||
dj-static==0.0.6
|
dj-static==0.0.6
|
||||||
Django==1.8.2
|
Django==1.8.2
|
||||||
|
|||||||
Reference in New Issue
Block a user