mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-03-03 10:38:23 +00:00
Merge branch 'master' into fixed_jquery
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# 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.
|
||||
|
||||
@@ -75,4 +75,4 @@ python manage.py runserver
|
||||
Please refer to Django documentation for a full list of options available here.
|
||||
|
||||
### Committing, pushing and testing ###
|
||||
Feel free to commit as you wish, on your own branch. On my branch (master for development) do not commit code that you either know doesn't work or don't know works. If you must commit this code, please make sure you say in the commit message that it isn't working, and if you can why it isn't working. If and only if you absolutely must push, then please don't leave it as the HEAD for too long, it's not much to ask but when you are done just make sure you haven't broken the HEAD for the next person.
|
||||
Feel free to commit as you wish, on your own branch. On my branch (master for development) do not commit code that you either know doesn't work or don't know works. If you must commit this code, please make sure you say in the commit message that it isn't working, and if you can why it isn't working. If and only if you absolutely must push, then please don't leave it as the HEAD for too long, it's not much to ask but when you are done just make sure you haven't broken the HEAD for the next person.
|
||||
|
||||
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)
|
||||
dry_hire = models.BooleanField(default=False)
|
||||
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
|
||||
start_date = models.DateField()
|
||||
|
||||
@@ -37,6 +37,12 @@ class RigboardIndex(generic.TemplateView):
|
||||
class WebCalendar(generic.TemplateView):
|
||||
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):
|
||||
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):
|
||||
# output_style = :expanded or :nested or :compact or :compressed
|
||||
output_style = :compressed
|
||||
|
||||
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||
# 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 {
|
||||
position: relative;
|
||||
margin: 30px auto 0;
|
||||
|
||||
@@ -14,8 +14,28 @@
|
||||
<script src="{% static "js/moment.min.js" %}"></script>
|
||||
<script src="{% static "js/fullcalendar.js" %}"></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() {
|
||||
|
||||
viewToUrl = {
|
||||
'agendaWeek':'week',
|
||||
'agendaDay':'day',
|
||||
'month':'month'
|
||||
}
|
||||
viewFromUrl = {
|
||||
'week':'agendaWeek',
|
||||
'day':'agendaDay',
|
||||
'month':'month'
|
||||
}
|
||||
|
||||
$('#calendar').fullCalendar({
|
||||
editable: false,
|
||||
eventLimit: true, // allow "more" link when too many events
|
||||
@@ -114,8 +134,11 @@
|
||||
$('#day-button').addClass('active');
|
||||
break;
|
||||
}
|
||||
|
||||
history.replaceState(null,null,'{% url 'web_calendar' %}'+viewToUrl[view.name]+'/'+view.intervalStart.format('YYYY-MM-DD')+'/');
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
// 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>
|
||||
|
||||
@@ -1,40 +1,21 @@
|
||||
{% 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='
|
||||
|
||||
{% if change.new %}
|
||||
<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>
|
||||
<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" %}
|
||||
{% endspaceless %}'>{{ change.field.verbose_name }}</button>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% 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 %}
|
||||
<h4>{{ change.field.verbose_name }}</h4>
|
||||
|
||||
{% if change.new %}<div class="alert alert-success">{{change.new|linebreaksbr}}</div>{% endif %}
|
||||
{% if change.old %}<div class="alert alert-danger">{{change.old|linebreaksbr}}</div>{% endif %}
|
||||
|
||||
<li class="list-group-item">
|
||||
<h4 class="list-group-item-heading">{{ change.field.verbose_name }}</h4>
|
||||
{% include "RIGS/version_changes_change.html" %}
|
||||
</li>
|
||||
{% 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 %}
|
||||
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)
|
||||
|
||||
# See redirected to success page
|
||||
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||
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):
|
||||
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,9 +609,10 @@ class EventTest(LiveServerTestCase):
|
||||
save.click()
|
||||
|
||||
# See redirected to success page
|
||||
successTitle = self.browser.find_element_by_xpath('//h1').text
|
||||
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):
|
||||
self.browser.get(self.live_server_url + '/event/create/')
|
||||
# Gets redirected to login and back
|
||||
|
||||
@@ -69,6 +69,8 @@ urlpatterns = patterns('',
|
||||
# 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/(?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/activity/$',
|
||||
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.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from django.db.models import ForeignKey, IntegerField, EmailField, TextField
|
||||
from diff_match_patch import diff_match_patch
|
||||
|
||||
from RIGS import models, forms
|
||||
import datetime
|
||||
@@ -64,6 +65,25 @@ def model_compare(oldObj, newObj, excluded_keys=[]):
|
||||
return True
|
||||
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 = []
|
||||
|
||||
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-static==0.0.6
|
||||
Django==1.8.2
|
||||
|
||||
Reference in New Issue
Block a user