Compare commits

..

23 Commits

Author SHA1 Message Date
d6c789d90a Whoops 2021-03-02 11:24:22 +00:00
4fe7b874a4 Implement django doctor suggestions 2021-03-02 11:21:44 +00:00
ac0425740e Revert "Very initial pass at reimplementing event table fully responsive"
This reverts commit f5d875d153.
2021-03-02 11:11:18 +00:00
5382d8ae00 Revert "Further work at grid-table, including tablet layout"
This reverts commit b3939d8426.
2021-03-02 11:11:18 +00:00
08a55644c5 Delete unused signature template 2021-02-25 14:07:40 +00:00
b3939d8426 Further work at grid-table, including tablet layout 2021-02-25 14:02:34 +00:00
f775cee7dd Should fix CI 2021-02-24 22:42:30 +00:00
f5d875d153 Very initial pass at reimplementing event table fully responsive 2021-02-24 22:41:15 +00:00
f88f418503 Fixed a couple of places where profiles should have been linked but weren't 2021-02-24 18:20:51 +00:00
f3d9646607 Enable preview of event authorisation 2021-02-23 16:01:05 +00:00
798689403d Another go at CI caching 2021-02-23 13:58:03 +00:00
d1069a1745 That was silly 2021-02-23 01:27:42 +00:00
238d53a547 Try reimplementing caching on CI 2021-02-23 01:25:32 +00:00
8756e7f880 Oops 2021-02-23 01:19:38 +00:00
25c9cf25f7 Disable asset cache on ci, try to get assets working on heroku
Whyyy do things just randomly fall over
2021-02-23 01:11:33 +00:00
ad66f434de bah staticfiles 2021-02-23 01:01:36 +00:00
1aae2bff28 Damn you pipeline 2021-02-23 00:40:27 +00:00
9302cccd58 Swithc to pathlib in settings 2021-02-23 00:34:27 +00:00
123c8bfd80 Serve logo in next gen format 2021-02-22 23:53:53 +00:00
02af3870aa Can't async jquery 2021-02-22 23:48:23 +00:00
6d3a861df5 Preload fontawesome 2021-02-22 23:46:20 +00:00
0e07c50c18 Prevent search engines indexing us
Might help cut down the spam
2021-02-22 23:41:58 +00:00
8505d5e93a Squash jquery and popper together 2021-02-22 23:41:42 +00:00
29 changed files with 114 additions and 108 deletions

View File

@@ -14,30 +14,33 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Cache Static Files
id: static-cache
uses: actions/cache@v2
with:
path: 'static/'
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
- uses: bahmutov/npm-install@v1
if: steps.static-cache.outputs.cache-hit != 'true'
- run: node node_modules/gulp/bin/gulp build
if: steps.static-cache.outputs.cache-hit != 'true'
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v2
with: with:
python-version: 3.9 python-version: 3.9
- name: Cache python deps - uses: actions/cache@v2
uses: actions/cache@v2 id: pcache
with: with:
path: ${{ env.pythonLocation }} path: ~/.local/share/virtualenvs
key: ${{ env.pythonLocation }}-${{ hashFiles('Pipfile.lock') }} key: ${{ runner.os }}-pipenv-${{ hashFiles('Pipfile.lock') }}
restore-keys: |
${{ runner.os }}-pipenv-
- name: Install Dependencies - name: Install Dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install pipenv pip install pipenv
pipenv install -d pipenv install -d
# if: steps.pcache.outputs.cache-hit != 'true'
- name: Cache Static Files
id: static-cache
uses: actions/cache@v2
with:
path: 'pipeline/built_assets'
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
- uses: bahmutov/npm-install@v1
if: steps.static-cache.outputs.cache-hit != 'true'
- run: node node_modules/gulp/bin/gulp build
if: steps.static-cache.outputs.cache-hit != 'true'
- name: Basic Checks - name: Basic Checks
run: | run: |
pipenv run pycodestyle . --exclude=migrations,node_modules pipenv run pycodestyle . --exclude=migrations,node_modules

View File

@@ -9,23 +9,18 @@ https://docs.djangoproject.com/en/1.7/ref/settings/
""" """
import datetime import datetime
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) from pathlib import Path
import os
import secrets import secrets
import sentry_sdk import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.django import DjangoIntegration
from envparse import env from envparse import env
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY', default='gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e') SECRET_KEY = env('SECRET_KEY', default='gxhy(a#5mhp289_=6xx$7jh=eh$ymxg^ymc+di*0c*geiu3p_e')
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', cast=bool, default=True) DEBUG = env('DEBUG', cast=bool, default=True)
STAGING = env('STAGING', cast=bool, default=False) STAGING = env('STAGING', cast=bool, default=False)
@@ -97,7 +92,7 @@ WSGI_APPLICATION = 'PyRIGS.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': str(BASE_DIR / 'db.sqlite3'),
} }
} }
@@ -235,19 +230,16 @@ DATETIME_INPUT_FORMATS = ('%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S')
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATIC_URL = '/static/' STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/') STATIC_ROOT = str(BASE_DIR / 'static/')
STATIC_DIRS = [
os.path.join(BASE_DIR, 'static/'),
]
STATICFILES_DIRS = [ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'pipeline/built_assets'), str(BASE_DIR / 'pipeline/built_assets'),
] ]
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ 'DIRS': [
os.path.join(BASE_DIR, 'templates') BASE_DIR / 'templates'
], ],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
@@ -261,7 +253,7 @@ TEMPLATES = [
"django.template.context_processors.request", "django.template.context_processors.request",
"django.contrib.messages.context_processors.messages", "django.contrib.messages.context_processors.messages",
], ],
'debug': DEBUG or CI 'debug': DEBUG
}, },
}, },
] ]

View File

@@ -27,13 +27,14 @@ urlpatterns = [
path('', include('users.urls')), path('', include('users.urls')),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path("robots.txt", TemplateView.as_view(template_name="robots.txt", content_type="text/plain")),
] ]
if settings.DEBUG: if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns() urlpatterns += staticfiles_urlpatterns()
import debug_toolbar import debug_toolbar
urlpatterns = [ urlpatterns += [
path('__debug__/', include(debug_toolbar.urls)), path('__debug__/', include(debug_toolbar.urls)),
path('bootstrap/', TemplateView.as_view(template_name="bootstrap.html")), path('bootstrap/', TemplateView.as_view(template_name="bootstrap.html")),
] + urlpatterns ]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-03-02 11:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0041_auto_20210208_1603'),
]
operations = [
migrations.AlterField(
model_name='profile',
name='phone',
field=models.CharField(blank=True, default='', max_length=13),
),
]

View File

@@ -21,7 +21,7 @@ from reversion.models import Version
class Profile(AbstractUser): class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=False) initials = models.CharField(max_length=5, unique=True, null=True, blank=False)
phone = models.CharField(max_length=13, null=True, default='') phone = models.CharField(max_length=13, blank=True, default='')
api_key = models.CharField(max_length=40, blank=True, editable=False, default='') api_key = models.CharField(max_length=40, blank=True, editable=False, default='')
is_approved = models.BooleanField(default=False) is_approved = models.BooleanField(default=False)
# Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that... # Currently only populated by the admin approval email. TODO: Populate it each time we send any email, might need that...
@@ -707,7 +707,7 @@ class RiskAssessment(models.Model, RevisionMixin):
] ]
@cached_property @cached_property
def fields(self): def fieldz(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created] return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
@property @property
@@ -792,16 +792,16 @@ class EventChecklist(models.Model, RevisionMixin):
inverted_fields = [] inverted_fields = []
@cached_property
def fields(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
class Meta: class Meta:
ordering = ['event'] ordering = ['event']
permissions = [ permissions = [
('review_eventchecklist', 'Can review Event Checklists') ('review_eventchecklist', 'Can review Event Checklists')
] ]
@cached_property
def fieldz(self):
return [n.name for n in list(self._meta.get_fields()) if n.name != 'reviewed_at' and n.name != 'reviewed_by' and not n.is_relation and not n.auto_created]
@property @property
def activity_feed_string(self): def activity_feed_string(self):
return str(self.event) return str(self.event)

View File

@@ -11,7 +11,7 @@ import simplejson
from PyPDF2 import PdfFileMerger, PdfFileReader from PyPDF2 import PdfFileMerger, PdfFileReader
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.staticfiles.storage import staticfiles_storage from django.contrib.staticfiles import finders
from django.core import signing from django.core import signing
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
from django.core.mail import EmailMultiAlternatives from django.core.mail import EmailMultiAlternatives
@@ -274,6 +274,7 @@ class EventArchive(generic.ListView):
class EventAuthorise(generic.UpdateView): class EventAuthorise(generic.UpdateView):
template_name = 'eventauthorisation_form.html' template_name = 'eventauthorisation_form.html'
success_template = 'eventauthorisation_success.html' success_template = 'eventauthorisation_success.html'
preview = False
def form_valid(self, form): def form_valid(self, form):
self.object = form.save() self.object = form.save()
@@ -301,6 +302,7 @@ class EventAuthorise(generic.UpdateView):
context['page_title'] = "{}: {}".format(self.event.display_id, self.event.name) context['page_title'] = "{}: {}".format(self.event.display_id, self.event.name)
if self.event.dry_hire: if self.event.dry_hire:
context['page_title'] += ' <span class="badge badge-secondary align-top">Dry Hire</span>' context['page_title'] += ' <span class="badge badge-secondary align-top">Dry Hire</span>'
context['preview'] = self.preview
return context return context
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@@ -387,7 +389,7 @@ class EventAuthorisationRequest(generic.FormView, generic.detail.SingleObjectMix
to=[email], to=[email],
reply_to=[self.request.user.email], reply_to=[self.request.user.email],
) )
css = staticfiles_storage.path('css/email.css') css = finders.find('css/email.css')
html = premailer.Premailer(get_template("eventauthorisation_client_request.html").render(context), html = premailer.Premailer(get_template("eventauthorisation_client_request.html").render(context),
external_styles=css).transform() external_styles=css).transform()
msg.attach_alternative(html, 'text/html') msg.attach_alternative(html, 'text/html')
@@ -402,8 +404,7 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
model = models.Event model = models.Event
def render_to_response(self, context, **response_kwargs): def render_to_response(self, context, **response_kwargs):
from django.contrib.staticfiles.storage import staticfiles_storage css = finders.find('css/email.css')
css = staticfiles_storage.path('css/email.css')
response = super(EventAuthoriseRequestEmailPreview, self).render_to_response(context, **response_kwargs) response = super(EventAuthoriseRequestEmailPreview, self).render_to_response(context, **response_kwargs)
assert isinstance(response, HttpResponse) assert isinstance(response, HttpResponse)
response.content = premailer.Premailer(response.rendered_content, external_styles=css).transform() response.content = premailer.Premailer(response.rendered_content, external_styles=css).transform()
@@ -417,4 +418,5 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
'sent_by': self.request.user.pk, 'sent_by': self.request.user.pk,
}) })
context['to_name'] = self.request.GET.get('to_name', None) context['to_name'] = self.request.GET.get('to_name', None)
context['target'] = 'event_authorise_form_preview'
return context return context

View File

@@ -6,7 +6,7 @@ from io import BytesIO
from PyPDF2 import PdfFileReader, PdfFileMerger from PyPDF2 import PdfFileReader, PdfFileMerger
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage from django.contrib.staticfiles import finders
from django.core.cache import cache from django.core.cache import cache
from django.core.mail import EmailMessage, EmailMultiAlternatives from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.db.models.signals import post_save from django.db.models.signals import post_save
@@ -63,7 +63,7 @@ def send_eventauthorisation_success_email(instance):
reply_to=[settings.AUTHORISATION_NOTIFICATION_ADDRESS], reply_to=[settings.AUTHORISATION_NOTIFICATION_ADDRESS],
) )
css = staticfiles_storage.path('css/email.css') css = finders.find('css/email.css')
html = Premailer(get_template("eventauthorisation_client_success.html").render(context), html = Premailer(get_template("eventauthorisation_client_success.html").render(context),
external_styles=css).transform() external_styles=css).transform()
client_email.attach_alternative(html, 'text/html') client_email.attach_alternative(html, 'text/html')
@@ -121,7 +121,7 @@ def send_admin_awaiting_approval_email(user, request, **kwargs):
to=[admin.email], to=[admin.email],
reply_to=[user.email], reply_to=[user.email],
) )
css = staticfiles_storage.path('css/email.css') css = finders.find('css/email.css')
html = Premailer(get_template("admin_awaiting_approval.html").render(context), html = Premailer(get_template("admin_awaiting_approval.html").render(context),
external_styles=css).transform() external_styles=css).transform()
email.attach_alternative(html, 'text/html') email.attach_alternative(html, 'text/html')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
RIGS/static/imgs/logo.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -7,7 +7,7 @@
{% if not request.is_ajax %} {% if not request.is_ajax %}
{% if perms.RIGS.view_event %} {% if perms.RIGS.view_event %}
<div class="col-sm-12 text-right"> <div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %} {% include 'partials/event_detail_buttons.html' %}
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
@@ -77,7 +77,7 @@
{% endif %} {% endif %}
{% if not request.is_ajax and perms.RIGS.view_event %} {% if not request.is_ajax and perms.RIGS.view_event %}
<div class="col-sm-12 text-right"> <div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %} {% include 'partials/event_detail_buttons.html' %}
</div> </div>
{% endif %} {% endif %}
{% if event.is_rig %} {% if event.is_rig %}
@@ -97,7 +97,7 @@
</div> </div>
{% if not request.is_ajax and perms.RIGS.view_event %} {% if not request.is_ajax and perms.RIGS.view_event %}
<div class="col-sm-12 text-right"> <div class="col-sm-12 text-right">
{% include 'event_detail_buttons.html' %} {% include 'partials/event_detail_buttons.html' %}
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE document SYSTEM "rml.dtd"> <!DOCTYPE document SYSTEM "rml.dtd">
<document filename="{{filename}}"> <document filename="{{filename}}">
<docinit> <docinit>
<registerTTFont faceName="OpenSans" fileName="static/fonts/OpenSans-Regular.tff"/> <registerTTFont faceName="OpenSans" fileName="static/fonts/OpenSans-Regular.tff"/>

View File

@@ -1,10 +0,0 @@
<blockTable style="signatureTable" colWidths="50,120,60,120,35,110">
<tr>
<td>Signature</td>
<td></td>
<td>Print Name</td>
<td></td>
<td>Date</td>
<td></td>
</tr>
</blockTable>

View File

@@ -4,7 +4,7 @@
<p>Hi {{ to_name|default:"there" }},</p> <p>Hi {{ to_name|default:"there" }},</p>
<p><b>{{ request.user.get_full_name }}</b> has requested that you authorise <b>N{{ object.pk|stringformat:"05d" }} <p><b>{{ request.user.get_full_name }}</b> has requested that you authorise <b>{{ object.display_id }}
| {{ object.name }}</b>{% if not to_name %} on behalf of <b>{{ object.person.name }}</b>{% endif %}.</p> | {{ object.name }}</b>{% if not to_name %} on behalf of <b>{{ object.person.name }}</b>{% endif %}.</p>
<p> <p>
@@ -23,7 +23,7 @@
<table border="0" cellspacing="0" cellpadding="0"> <table border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td class="button" align="center"> <td class="button" align="center">
<a href="{{ request.scheme }}://{{ request.get_host }}{% url 'event_authorise' object.pk hmac %}"> <a href="{{ request.scheme }}://{{ request.get_host }}{% url target|default:'event_authorise' object.pk hmac %}">
Complete Authorisation Form Complete Authorisation Form
</a> </a>
</td> </td>

View File

@@ -1,9 +1,6 @@
{% extends 'eventauthorisation.html' %} {% extends 'eventauthorisation.html' %}
{% load widget_tweaks %} {% load widget_tweaks %}
{% block js %}
{% endblock %}
{% block authorisation %} {% block authorisation %}
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
@@ -86,7 +83,7 @@
<div class="text-right"> <div class="text-right">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-primary btn-lg" type="submit">Authorise</button> <button class="btn btn-primary btn-lg" type="submit" {% if preview %}disabled="" data-toggle="tooltip" title="This is only a preview!"{%endif%}>Authorise</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -30,14 +30,6 @@
{% render_field form.email type="email" class+="form-control" %} {% render_field form.email type="email" class+="form-control" %}
</div> </div>
</div> </div>
<div class="text-right col-sm-3 offset-sm-9">
<div class="form-group">
<button type="submit" class="form-control btn btn-primary">
<i class="fas fa-paper-plane"></i>
Send
</button>
</div>
</div>
</form> </form>
</div> </div>
</div> </div>
@@ -48,3 +40,14 @@
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block footer %}
<div class="form-row">
<div class="btn-group" role="group">
<a type="button" target="_blank" href="{% url 'event_authorise_preview' object.pk %}" class="btn btn-info text-nowrap"><span class="fas fa-drafting-compass"></span> Preview</a>
<button type="submit" class="form-control btn btn-primary" form="auth-request-form">
<span class="fas fa-paper-plane"></span> Send
</button>
</div>
</div>
{% endblock %}

View File

@@ -21,7 +21,7 @@
<th scope="col">Event</th> <th scope="col">Event</th>
{# mmm hax #} {# mmm hax #}
{% if object_list.0 != None %} {% if object_list.0 != None %}
{% for field in object_list.0.fields %} {% for field in object_list.0.fieldz %}
<th scope="col">{{ object_list.0|verbose_name:field|title }}</th> <th scope="col">{{ object_list.0|verbose_name:field|title }}</th>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
@@ -33,7 +33,7 @@
<tr class="{% if object.reviewed_by %}table-success{%endif%}"> <tr class="{% if object.reviewed_by %}table-success{%endif%}">
{# General #} {# General #}
<th scope="row"><a href="{% url 'event_detail' object.event.pk %}">{{ object.event }}</a></th> <th scope="row"><a href="{% url 'event_detail' object.event.pk %}">{{ object.event }}</a></th>
{% for field in object_list.0.fields %} {% for field in object_list.0.fieldz %}
<td>{{ object|get_field:field }}</td> <td>{{ object|get_field:field }}</td>
{% endfor %} {% endfor %}
{# Buttons #} {# Buttons #}

View File

@@ -1,15 +1,15 @@
<div class="card card-default <div class="card card-default
{% if object.authorised %} {% if event.authorised %}
card-success border-success
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %} {% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
card-warning border-warning
{% elif event.auth_request_to %} {% elif event.auth_request_to %}
card-info border-info
{% endif %} {% endif %}
"> ">
<div class="card-header">Client Authorisation</div> <div class="card-header">Client Authorisation</div>
<div class="card-body row"> <div class="card-body row">
<dl class="col-md-6"> <dl class="col-sm-6">
<dt>Authorisation Request</dt> <dt>Authorisation Request</dt>
<dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd> <dd>{{ object.auth_request_to|yesno:"Yes,No" }}</dd>
@@ -22,8 +22,8 @@
<dt>To</dt> <dt>To</dt>
<dd>{{ object.auth_request_to }}</dd> <dd>{{ object.auth_request_to }}</dd>
</dl> </dl>
<dd class="d-block d-sm-none">&nbsp;</dd> <dl class="col-sm-6">
<dl class="col-md-6"> <hr class="d-block d-sm-none">
<dt>Authorised</dt> <dt>Authorised</dt>
<dd>{{ object.authorised|yesno:"Yes,No" }}</dd> <dd>{{ object.authorised|yesno:"Yes,No" }}</dd>

View File

@@ -9,7 +9,7 @@
{% if event.internal %} {% if event.internal %}
<a class="btn item-add modal-href event-authorise-request <a class="btn item-add modal-href event-authorise-request
{% if event.authorised %} {% if event.authorised %}
btn-success btn-success active
{% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %} {% elif event.authorisation and event.authorisation.amount != event.total and event.authorisation.last_edited_at > event.auth_request_at %}
btn-warning btn-warning
{% elif event.auth_request_to %} {% elif event.auth_request_to %}
@@ -19,7 +19,7 @@
{% endif %} {% endif %}
" "
href="{% url 'event_authorise_request' object.pk %}"> href="{% url 'event_authorise_request' object.pk %}">
<i class="fas fa-paper-plane"></i> <span class="fas fa-paper-plane"></span>
<span class="d-none d-sm-inline"> <span class="d-none d-sm-inline">
{% if event.authorised %} {% if event.authorised %}
Authorised Authorised

View File

@@ -20,15 +20,7 @@
{% if event.is_rig %} {% if event.is_rig %}
<dt class="col-sm-6">Event MIC</dt> <dt class="col-sm-6">Event MIC</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">{% include 'partials/linked_name.html' with profile=event.mic %}</dd>
{% if event.mic and perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
{{ event.mic.name }}
</a>
{% else %}
{{ event.mic.name }}
{% endif %}
</dd>
{% endif %} {% endif %}
<dt class="col-sm-6">Status</dt> <dt class="col-sm-6">Status</dt>
@@ -71,7 +63,7 @@
{% if event.dry_hire %} {% if event.dry_hire %}
<dt class="col-sm-6">Checked In By</dt> <dt class="col-sm-6">Checked In By</dt>
<dd class="col-sm-6">{{ object.checked_in_by.name }}</dd> <dd class="col-sm-6">{% include 'partials/linked_name.html' with profile=event.checked_in_by %}</dd>
{% endif %} {% endif %}
{% if event.is_rig %} {% if event.is_rig %}

View File

@@ -0,0 +1,7 @@
{% if profile and perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' profile.pk %}" class="modal-href">
{{ profile.name }}
</a>
{% else %}
{{ profile.name }}
{% endif %}

View File

@@ -173,7 +173,7 @@ def title_spaced(string):
@register.filter(needs_autoescape=True) @register.filter(needs_autoescape=True)
def namewithnotes(obj, url, autoescape=True): def namewithnotes(obj, url, autoescape=True):
if hasattr(obj, 'notes') and obj.notes is not None and len(obj.notes) > 0: if hasattr(obj, 'notes') and obj.notes is not None and len(obj.notes) > 0:
return mark_safe(obj.name + " <a href='{}'><span class='far fa-sticky-note'></span></a>".format(reverse(url, kwargs={'pk': obj.pk}))) return mark_safe(obj.name + " <a href='{}'><span class='fas fa-sticky-note'></span></a>".format(reverse(url, kwargs={'pk': obj.pk})))
else: else:
return obj.name return obj.name

View File

@@ -132,6 +132,8 @@ urlpatterns = [
name='event_authorise_preview'), name='event_authorise_preview'),
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/$', rigboard.EventAuthorise.as_view(), re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/$', rigboard.EventAuthorise.as_view(),
name='event_authorise'), name='event_authorise'),
re_path(r'^event/(?P<pk>\d+)/(?P<hmac>[-:\w]+)/preview/$', rigboard.EventAuthorise.as_view(preview=True),
name='event_authorise_form_preview'),
# ICS Calendar - API key authentication # ICS Calendar - API key authentication
re_path(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(ical.CalendarICS()), re_path(r'^ical/(?P<api_pk>\d+)/(?P<api_key>\w+)/rigs.ics$', api_key_required(ical.CalendarICS()),

View File

@@ -5,7 +5,7 @@
{% button 'submit' %} {% button 'submit' %}
{% elif duplicate %} {% elif duplicate %}
<!--duplicate--> <!--duplicate-->
<button type="submit" class="btn btn-success"><i class="fas fa-check"></i> Create Duplicate</button> <button type="submit" class="btn btn-success"><span class="fas fa-check"></span> Create Duplicate</button>
{% else %} {% else %}
<!--detail view--> <!--detail view-->
<div class="btn-group"> <div class="btn-group">

View File

@@ -44,9 +44,10 @@ function scripts() {
const base_scripts = ["src.js", "util.js", "alert.js", "collapse.js", "dropdown.js", "modal.js", "konami.js"]; const base_scripts = ["src.js", "util.js", "alert.js", "collapse.js", "dropdown.js", "modal.js", "konami.js"];
const bs_select = ["bootstrap-select.js", "ajax-bootstrap-select.js"] const bs_select = ["bootstrap-select.js", "ajax-bootstrap-select.js"]
const interaction = ["html5sortable.min.js", "interaction.js"] const interaction = ["html5sortable.min.js", "interaction.js"]
return gulp.src(['node_modules/jquery/dist/jquery.js', const jpop = ["jquery.min.js", "popper.min.js"]
return gulp.src(['node_modules/jquery/dist/jquery.min.js',
/* JQuery Plugins */ /* JQuery Plugins */
'node_modules/popper.js/dist/umd/popper.js', 'node_modules/popper.js/dist/umd/popper.min.js',
/* Bootstrap Plugins */ /* Bootstrap Plugins */
'node_modules/bootstrap/js/dist/util.js', 'node_modules/bootstrap/js/dist/util.js',
'node_modules/bootstrap/js/dist/tooltip.js', 'node_modules/bootstrap/js/dist/tooltip.js',
@@ -68,6 +69,7 @@ function scripts() {
.pipe(gulpif(function(file) { return base_scripts.includes(file.relative);}, con('base.js'))) .pipe(gulpif(function(file) { return base_scripts.includes(file.relative);}, con('base.js')))
.pipe(gulpif(function(file) { return bs_select.includes(file.relative);}, con('selects.js'))) .pipe(gulpif(function(file) { return bs_select.includes(file.relative);}, con('selects.js')))
.pipe(gulpif(function(file) { return interaction.includes(file.relative);}, con('interaction.js'))) .pipe(gulpif(function(file) { return interaction.includes(file.relative);}, con('interaction.js')))
.pipe(gulpif(function(file) { return jpop.includes(file.relative);}, con('jpop.js')))
.pipe(flatten()) .pipe(flatten())
.pipe(terser()) .pipe(terser())
.pipe(gulp.dest(dest)) .pipe(gulp.dest(dest))

View File

@@ -15,14 +15,13 @@
<link rel="icon" type="image/png" href="{% static 'imgs/pyrigs-avatar.png' %}"> <link rel="icon" type="image/png" href="{% static 'imgs/pyrigs-avatar.png' %}">
<link rel="apple-touch-icon" href="{% static 'imgs/pyrigs-avatar.png' %}"> <link rel="apple-touch-icon" href="{% static 'imgs/pyrigs-avatar.png' %}">
<link href="{% static 'fonts/OpenSans-Regular.tff' %}"> <link rel="preload" href="{% static 'fonts/fa-solid-900.woff2' %}" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" type="text/css" href="{% static 'css/screen.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'css/screen.css' %}">
{% block css %} {% block css %}
{% endblock %} {% endblock %}
<script src="{% static 'js/jquery.js' %}"></script> <script src="{% static 'js/jpop.js' %}"></script>
<script src="{% static 'js/popper.js' %}"></script>
{% block preload_js %} {% block preload_js %}
{% endblock %} {% endblock %}
@@ -35,7 +34,7 @@
{% block navbar %} {% block navbar %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark flex-nowrap" role="navigation"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark flex-nowrap" role="navigation">
<a class="navbar-brand" href="{% if request.user.is_authenticated %}https://members.nottinghamtec.co.uk{%else%}https://nottinghamtec.co.uk{%endif%}"> <a class="navbar-brand" href="{% if request.user.is_authenticated %}https://members.nottinghamtec.co.uk{%else%}https://nottinghamtec.co.uk{%endif%}">
<img src="{% static 'imgs/logo.png' %}" width="40" height="40" alt="TEC's Logo: Serif 'TEC' vertically next to a blue box with the words 'PA and Lighting', surrounded by graduated rings"> <img src="{% static 'imgs/logo.webp' %}" width="40" height="40" alt="TEC's Logo: Serif 'TEC' vertically next to a blue box with the words 'PA and Lighting', surrounded by graduated rings">
</a> </a>
<div class="container"> <div class="container">
{% block titleheader %} {% block titleheader %}

View File

@@ -11,10 +11,7 @@
<meta name="color-scheme" content="light dark"> <meta name="color-scheme" content="light dark">
<link href="{% static 'fonts/OpenSans-Regular.tff' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/screen.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'css/screen.css' %}">
</head> </head>
<body> <body>

View File

@@ -33,7 +33,7 @@
<a class="list-group-item list-group-item-action" href="https://forum.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><span class="fas fa-comment-alt text-info align-middle"></span><span class="align-middle"> TEC Forum</span></a> <a class="list-group-item list-group-item-action" href="https://forum.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><span class="fas fa-comment-alt text-info align-middle"></span><span class="align-middle"> TEC Forum</span></a>
<a class="list-group-item list-group-item-action" href="//wiki.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><span class="fas fa-pen-square align-middle"></span><span class="align-middle"> TEC Wiki</span></a> <a class="list-group-item list-group-item-action" href="//wiki.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><span class="fas fa-pen-square align-middle"></span><span class="align-middle"> TEC Wiki</span></a>
{% if perms.RIGS.view_event %} {% if perms.RIGS.view_event %}
<a class="list-group-item list-group-item-action" href="//members.nottinghamtec.co.uk/price" target="_blank"><span class="fas fa-pound-sign text-warning align-middle"></span><span class="align-middle"> Price List</span></a> <a class="list-group-item list-group-item-action" href="//members.nottinghamtec.co.uk/price" target="_blank" rel="noopener noreferrer"><span class="fas fa-pound-sign text-warning align-middle"></span><span class="align-middle"> Price List</span></a>
{% endif %} {% endif %}
</div> </div>
</div> </div>

2
templates/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /

View File

@@ -16,7 +16,7 @@
<th scope="row">{{ version.revision.date_created }}</th> <th scope="row">{{ version.revision.date_created }}</th>
<td><a href="{{ version.changes.new.get_absolute_url }}">{{ version.changes.new.display_id|default:version.changes.new.pk }} | {{version.changes.new|to_class_name}}</a></td> <td><a href="{{ version.changes.new.get_absolute_url }}">{{ version.changes.new.display_id|default:version.changes.new.pk }} | {{version.changes.new|to_class_name}}</a></td>
<td>{{ version.pk }}|{{ version.revision.pk }}</td> <td>{{ version.pk }}|{{ version.revision.pk }}</td>
<td>{{ version.revision.user.name|default:"System" }}</td> <td>{% include 'partials/linked_name.html' with profile=version.revision.user %}</td>
<td> <td>
{% if version.changes.old == None %} {% if version.changes.old == None %}
Created {{version.changes.new|to_class_name}} Created {{version.changes.new|to_class_name}}