Compare commits

..

2 Commits

Author SHA1 Message Date
65b68b269f Merge branch 'master' into dependabot/pip/tornado-6.3.3 2023-09-23 18:54:55 +01:00
dependabot[bot]
147029f48f Build(deps): Bump tornado from 6.3.2 to 6.3.3
Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.3.2 to 6.3.3.
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.3.2...v6.3.3)

---
updated-dependencies:
- dependency-name: tornado
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 23:52:49 +00:00
21 changed files with 7031 additions and 3342 deletions

View File

@@ -14,9 +14,9 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PYTHONDONTWRITEBYTECODE: 1 PYTHONDONTWRITEBYTECODE: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: 3.9 python-version: 3.9
cache: 'pipenv' cache: 'pipenv'
@@ -27,7 +27,7 @@ jobs:
# if: steps.pcache.outputs.cache-hit != 'true' # if: steps.pcache.outputs.cache-hit != 'true'
- name: Cache Static Files - name: Cache Static Files
id: static-cache id: static-cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: 'pipeline/built_assets' path: 'pipeline/built_assets'
key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }} key: ${{ hashFiles('package-lock.json') }}-${{ hashFiles('pipeline/source_assets') }}
@@ -43,7 +43,7 @@ jobs:
pipenv run python3 manage.py collectstatic --noinput pipenv run python3 manage.py collectstatic --noinput
- name: Run Tests - name: Run Tests
run: pipenv run pytest -n auto --cov run: pipenv run pytest -n auto --cov
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
if: failure() if: failure()
with: with:
name: failure-screenshots ${{ matrix.test-group }} name: failure-screenshots ${{ matrix.test-group }}

14
Pipfile
View File

@@ -28,13 +28,13 @@ django-reversion = "~=3.0.9"
django-widget-tweaks = "~=1.4.8" django-widget-tweaks = "~=1.4.8"
django-htmlmin = "~=0.11.0" django-htmlmin = "~=0.11.0"
envparse = "*" envparse = "*"
gunicorn = "~=22.0.0" gunicorn = "~=20.0.4"
icalendar = "~=4.0.7" icalendar = "~=4.0.7"
idna = "~=3.7" idna = "~=2.10"
Markdown = "~=3.3.3" Markdown = "~=3.3.3"
msgpack = "~=1.0.2" msgpack = "~=1.0.2"
pep517 = "~=0.9.1" pep517 = "~=0.9.1"
Pillow = "~=10.0.1" Pillow = "~=9.3.0"
premailer = "~=3.7.0" premailer = "~=3.7.0"
progress = "~=1.5" progress = "~=1.5"
psutil = "~=5.8.0" psutil = "~=5.8.0"
@@ -47,20 +47,20 @@ python-dateutil = "~=2.8.1"
pytoml = "~=0.1.21" pytoml = "~=0.1.21"
pytz = "~=2020.5" pytz = "~=2020.5"
reportlab = "*" reportlab = "*"
requests = "~=2.32.0" requests = "~=2.31.0"
retrying = "~=1.3.3" retrying = "~=1.3.3"
simplejson = "~=3.17.2" simplejson = "~=3.17.2"
six = "~=1.15.0" six = "~=1.15.0"
soupsieve = "~=2.1" soupsieve = "~=2.1"
sqlparse = "~=0.5.0" sqlparse = "~=0.4.2"
static3 = "~=0.7.0" static3 = "~=0.7.0"
svg2rlg = "~=0.3" svg2rlg = "~=0.3"
tini = "~=3.0.1" tini = "~=3.0.1"
tornado = "~=6.3" tornado = "~=6.3"
urllib3 = "~=1.26.19" urllib3 = "~=1.26.5"
whitenoise = "~=5.2.0" whitenoise = "~=5.2.0"
yolk = "~=0.4.3" yolk = "~=0.4.3"
zipp = "~=3.19.1" zipp = "~=3.4.0"
"zope.component" = "~=4.6.2" "zope.component" = "~=4.6.2"
"zope.deferredimport" = "~=4.3.1" "zope.deferredimport" = "~=4.3.1"
"zope.deprecation" = "~=4.4.0" "zope.deprecation" = "~=4.4.0"

738
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -35,8 +35,6 @@ if DEBUG:
ALLOWED_HOSTS.append('localhost') ALLOWED_HOSTS.append('localhost')
ALLOWED_HOSTS.append('example.com') ALLOWED_HOSTS.append('example.com')
ALLOWED_HOSTS.append('127.0.0.1') ALLOWED_HOSTS.append('127.0.0.1')
ALLOWED_HOSTS.append('.app.github.dev')
CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
if not DEBUG: if not DEBUG:

View File

@@ -77,7 +77,7 @@ class Profile(AbstractUser):
@classmethod @classmethod
def users_awaiting_approval_count(cls): def users_awaiting_approval_count(cls):
# last_login = None ensures we only pick up genuinely new users, not those that have been deactivated for inactivity # last_login = None ensures we only pick up genuinely new users, not those that have been deactivated for inactivity
return Profile.objects.filter(is_approved=False, last_login=None, date_joined_date=timezone.now().date()).count() return Profile.objects.filter(is_approved=False, last_login=None).count()
def __str__(self): def __str__(self):
return self.name return self.name

View File

@@ -3,7 +3,6 @@ import urllib.error
import urllib.parse import urllib.parse
import urllib.request import urllib.request
from io import BytesIO from io import BytesIO
import datetime
from PyPDF2 import PdfFileReader, PdfFileMerger from PyPDF2 import PdfFileReader, PdfFileMerger
from django.conf import settings from django.conf import settings
@@ -111,7 +110,7 @@ def send_admin_awaiting_approval_email(user, request, **kwargs):
if admin.last_emailed is None or admin.last_emailed + settings.EMAIL_COOLDOWN <= timezone.now(): if admin.last_emailed is None or admin.last_emailed + settings.EMAIL_COOLDOWN <= timezone.now():
context = { context = {
'request': request, 'request': request,
'link_suffix': reverse("admin:RIGS_profile_changelist") + f'?is_approved__exact=0&date_joined__date={timezone.now().date()}', 'link_suffix': reverse("admin:RIGS_profile_changelist") + '?is_approved__exact=0',
'number_of_users': models.Profile.users_awaiting_approval_count(), 'number_of_users': models.Profile.users_awaiting_approval_count(),
'to_name': admin.first_name 'to_name': admin.first_name
} }

View File

@@ -26,7 +26,6 @@
var calendarEl = document.getElementById('calendar'); var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, { calendar = new FullCalendar.Calendar(calendarEl, {
firstDay: 1,
themeSystem: 'bootstrap', themeSystem: 'bootstrap',
aspectRatio: 1.5, aspectRatio: 1.5,
eventTimeFormat: { eventTimeFormat: {

View File

@@ -46,7 +46,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-12" style="container-type: inline-size;"> <div class="col-sm-12">
{% with object_list as events %} {% with object_list as events %}
{% include 'partials/event_table.html' %} {% include 'partials/event_table.html' %}
{% endwith %} {% endwith %}

View File

@@ -1,6 +1,6 @@
<h5 class="py-3"><a class="btn btn-info" data-toggle="collapse" href="#values" aria-expanded="false" aria-controls="values">View Threshold Values</a></h5> <h5 class="py-3"><a class="btn btn-info" data-toggle="collapse" href="#values" aria-expanded="false" aria-controls="values">View Threshold Values</a></h5>
<div class="row collapse" id="values"> <div class="row collapse" id="values">
<div class="col-md-6 col-sm-12"> <div class="table-responsive">
<table class="table table-bordered"> <table class="table table-bordered">
<thead> <thead>
<tr> <tr>
@@ -33,20 +33,17 @@
<thead> <thead>
<tr> <tr>
<th scope="row">Distro</th> <th scope="row">Distro</th>
<th scope="row">Max PSCC with Single Phase Supply (kA)</th> <th scope="row">Max PSSC (kA)</th>
<th scope="row">Max PSCC with Three Phase Supply (kA)</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>Intel & Toblerone distros</td> <td>Intel & Toblerone distros</td>
<td>6</td> <td>6</td>
<td>3</td>
</tr> </tr>
<tr> <tr>
<td>All other distros</td> <td>All other distros</td>
<td>10</td> <td>10</td>
<td>5</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -1,4 +1,4 @@
<div id="event_status"> <div>
<span class="badge badge-{% if event.confirmed %}success{% elif event.cancelled %}dark{% else %}warning{% endif %}">Status: {{ event.get_status_display }}</span> <span class="badge badge-{% if event.confirmed %}success{% elif event.cancelled %}dark{% else %}warning{% endif %}">Status: {{ event.get_status_display }}</span>
{% if event.is_rig %} {% if event.is_rig %}
{% if event.sum_total > 0 %} {% if event.sum_total > 0 %}

View File

@@ -1,195 +1,105 @@
{% load namewithnotes from filters %} {% load namewithnotes from filters %}
{% load markdown_tags %} {% load markdown_tags %}
<style> <div class="table-responsive">
#event_table { <table class="table mb-0" id="event_table">
display: grid; <thead>
grid-template-columns: max-content min-content minmax(max-content, 1fr) max-content; <tr>
column-gap: 1em; <th scope="col">#</th>
} <th scope="col">Dates & Times</th>
.eventgrid { <th scope="col">Event Details</th>
display: inherit; <th scope="col">MIC</th>
grid-column: 1/5; </tr>
grid-template-columns: subgrid; </thead>
padding: 1em; <tbody>
dt, dd { display: block; float: left; } {% for event in events %}
dt { clear: both; } <tr class="{% if event.cancelled %}
dd { float: right; } table-secondary
} {% elif not event.is_rig %}
.grid-header { table-info
border-bottom: 1px solid grey; {% elif not event.mic %}
border-top: 1px solid grey; table-danger
} {% elif event.confirmed and event.authorised %}
#event_status { {% if event.dry_hire or event.riskassessment %}
grid-column-start: 3; table-success
} {% else %}
#event_mic { table-warning
grid-row-start: 1; {% endif %}
grid-column-start: 4; {% else %}
} table-warning
.c-none { {% endif %}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
display: none; <!---Number-->
} <th scope="row" id="event_number">{{ event.display_id }}</th>
.c-inline { <!--Dates & Times-->
display: inline; <td id="event_dates" style="text-align: justify;">
} {% if not event.cancelled %}
@container (width <= 500px) { {% if event.meet_at %}
#event_table { <span class="text-nowrap">Meet: <strong>{{ event.meet_at|date:"D d/m/Y H:i" }}</strong></span>
grid-template-columns: 1fr !important; {% endif %}
} {% if event.access_at %}
.eventgrid { <br><span class="text-nowrap">Access: <strong>{{ event.access_at|date:"D d/m/Y H:i" }}</strong></span>
grid-column: 1/1 !important; {% endif %}
padding: 0.5em; {% endif %}
} <span class="text-nowrap">Start: <strong>{{ event.start_date|date:"D d/m/Y" }}
.grid-header { {% if event.has_start_time %}
display: none; {{ event.start_time|date:"H:i" }}
} {% endif %}</strong>
#event_dates { </span>
order: 2; {% if event.end_date %}
} <br>
#event_status { <span class="text-nowrap">End: {% if event.end_date != event.start_date %}<strong>{{ event.end_date|date:"D d/m/Y" }}{% endif %}
order: 3; {% if event.has_end_time %}
} {{ event.end_time|date:"H:i" }}
#event_mic { {% endif %}</strong>
grid-row-start: auto; </span>
grid-column-start: 4; {% endif %}
} </td>
} <!---Details-->
@container (width <= 700px) { <td id="event_details" class="w-100">
#event_table { <h4>
grid-template-columns: max-content; <a href="{% url 'event_detail' event.pk %}">
column-gap: 0.5em; {{ event.name }}
} </a>
.eventgrid { {% if event.venue %}
grid-column: 1/3; <small>at {{ event.venue|namewithnotes:'venue_detail' }}</small>
border: 1px solid grey; {% endif %}
} {% if event.dry_hire %}
#event_dates { <span class="badge badge-secondary">Dry Hire</span>
grid-row: 2; {% endif %}
grid-column: 1; </h4>
} {% if event.is_rig and not event.cancelled %}
#event_number { <h5>
grid-row: 1; <a href="{{ event.person.get_absolute_url }}">{{ event.person.name }}</a>
grid-column: 1; {% if event.organisation %}
} for <a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation.name }}</a>
#event_mic { {% endif %}
grid-column: 2; </h5>
} {% endif %}
#event_status { {% if not event.cancelled and event.description %}
grid-column: span 2; <p>{{ event.description|markdown }}</p>
} {% endif %}
.grid-header, .c-md-none { {% include 'partials/event_status.html' %}
display: none; </td>
} <!---MIC-->
} <td id="event_mic" class="text-nowrap">
@container (width > 700px) { {% if event.mic %}
.c-lg-block { {% if perms.RIGS.view_profile %}
display: block; <a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
} {% endif %}
.c-lg-inline { <img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
display: inline; {{ event.mic }}
} {% if perms.RIGS.view_profile %}
.c-lg-none, .c-md-none { </a>
display: none; {% endif %}
} {% elif event.is_rig %}
} <span class="fas fa-user-slash"></span>
</style> {% endif %}
<div id="event_table"> </td>
<div class="eventgrid grid-header font-weight-bold"> </tr>
<div id="event_number">#</div> {% empty %}
<div id="event_dates">Dates & Times</div> <tr class="bg-warning">
<div>Event Details</div> <td colspan="4">No events found</td>
<div id="event_mic">MIC</div> </tr>
</div> {% endfor %}
{% for event in events %} </tbody>
<div class="eventgrid {% if event.cancelled %} </table>
table-secondary
{% elif not event.is_rig %}
table-info
{% elif not event.mic %}
table-danger
{% elif event.confirmed and event.authorised %}
{% if event.dry_hire or event.riskassessment %}
table-success
{% else %}
table-warning
{% endif %}
{% else %}
table-warning
{% endif %}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
<!---Number-->
<div class="font-weight-bold c-none c-lg-block" id="event_number">{{ event.display_id }}</div>
<!--Dates & Times-->
<div id="event_dates" style="min-width: 180px;">
<dl>
{% if not event.cancelled %}
{% if event.meet_at %}
<dt class="font-weight-normal">Meet:</dt>
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.meet_at|date:"D d/m/Y H:i" }}</dd>
{% endif %}
{% if event.access_at %}
<dt class="font-weight-normal">Access:</dt>
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.access_at|date:"D d/m/Y H:i" }}</dd>
{% endif %}
{% endif %}
<dt class="font-weight-normal">Start:</dt>
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.start_date|date:"D d/m/Y" }}
{% if event.has_start_time %}
{{ event.start_time|date:"H:i" }}
{% endif %}
</dd>
{% if event.end_date %}
<dt class="font-weight-normal">End:</dt>
<dd class="text-nowrap font-weight-bold text-lg-right">{{ event.end_date|date:"D d/m/Y" }}
{% if event.has_end_time %}
{{ event.end_time|date:"H:i" }}
{% endif %}
</dd>
{% endif %}
</dl>
</div>
<!---Details-->
<div id="event_details" class="w-100">
<h4>
<a href="{% url 'event_detail' event.pk %}">
<span class="c-inline c-lg-none">{{ event }}</span><span class="c-none c-lg-inline">{{ event.name }}</span>
</a>
{% if event.dry_hire %}
<span class="badge badge-secondary">Dry Hire</span>
{% endif %}
<br class="c-none c-lg-inline">
{% if event.venue %}
<small>at {{ event.venue|namewithnotes:'venue_detail' }}</small>
{% endif %}
</h4>
{% if event.is_rig and not event.cancelled %}
<h5>
<a href="{{ event.person.get_absolute_url }}">{{ event.person.name }}</a>
{% if event.organisation %}
for <a href="{{ event.organisation.get_absolute_url }}">{{ event.organisation.name }}</a>
{% endif %}
</h5>
{% endif %}
{% if not event.cancelled and event.description %}
<p>{{ event.description|markdown }}</p>
{% endif %}
</div>
{% include 'partials/event_status.html' %}
<!---MIC-->
<div id="event_mic" class="text-nowrap">
<span class="c-md-none align-middle">MIC:</span>
{% if event.mic %}
{% if perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
{% endif %}
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
{{ event.mic }}
{% if perms.RIGS.view_profile %}
</a>
{% endif %}
{% elif event.is_rig %}
<span class="fas fa-exclamation"></span>
{% endif %}
</div>
</div>
{% endfor %}
</div> </div>

View File

@@ -3,8 +3,8 @@
{% block content %} {% block content %}
<div class="row align-items-center justify-content-between py-2 align-middle"> <div class="row align-items-center justify-content-between py-2 align-middle">
<div class="col-sm-12 col-md align-middle d-flex flex-wrap"> <div class="col-sm-12 col-md align-middle">
Key: <span class="table-success mr-1 px-2 rounded">Ready</span><span class="table-warning mr-1 px-2 rounded text-nowrap">Action Required</span><span class="table-danger mr-1 px-2 rounded text-nowrap">Needs MIC</span><span class="table-secondary mr-1 px-2 rounded">Cancelled</span><span class="table-info px-2 rounded text-nowrap">Non-Rig</span> Key: <span class="table-success mr-1 px-2 rounded">Ready</span><span class="table-warning mr-1 px-2 rounded">Action Required</span><span class="table-danger mr-1 px-2 rounded">Needs MIC</span><span class="table-secondary mr-1 px-2 rounded">Cancelled</span><span class="table-info px-2 rounded">Non-Rig</span>
</div> </div>
{% if perms.RIGS.add_event %} {% if perms.RIGS.add_event %}
<div class="col text-right"> <div class="col text-right">
@@ -12,7 +12,7 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div style="container-type: inline-size;">
{% include 'partials/event_table.html' %} {% include 'partials/event_table.html' %}
</div>
{% endblock %} {% endblock %}

View File

@@ -4,7 +4,7 @@
"scripts": { "scripts": {
"postdeploy": "python manage.py migrate && python manage.py generateSampleData" "postdeploy": "python manage.py migrate && python manage.py generateSampleData"
}, },
"stack": "heroku-22", "stack": "heroku-20",
"env": { "env": {
"DEBUG": { "DEBUG": {
"required": true "required": true
@@ -51,7 +51,7 @@
"url": "heroku/nodejs" "url": "heroku/nodejs"
}, },
{ {
"url": "heroku/python" "url": "https://github.com/nottinghamtec/heroku-buildpack-python"
} }
] ]
} }

View File

@@ -16,7 +16,7 @@ const con = require('gulp-concat');
const gulpif = require('gulp-if'); const gulpif = require('gulp-if');
function fonts(done) { function fonts(done) {
return gulp.src('node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.*', { encoding: false }) return gulp.src('node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.*')
.pipe(gulp.dest('pipeline/built_assets/fonts')) .pipe(gulp.dest('pipeline/built_assets/fonts'))
.pipe(browsersync.stream()); .pipe(browsersync.stream());
} }
@@ -70,16 +70,16 @@ function scripts() {
.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(gulpif(function(file) { return jpop.includes(file.relative);}, con('jpop.js')))
.pipe(flatten()) .pipe(flatten())
// Only minify if filename does not already denote it as minified .pipe(terser())
.pipe(gulpif(function(file) { return file.path.indexOf("min") == -1;},terser()))
.pipe(gulp.dest(dest)) .pipe(gulp.dest(dest))
.pipe(browsersync.stream()); .pipe(browsersync.stream());
} }
function browserSync(done) { function browserSync(done) {
spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'}); spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'});
// TODO Wait for Django server to come up before browsersync, it seems inconsistent
browsersync.init({ browsersync.init({
notify: true, notify: false,
open: false, open: false,
port: 8001, port: 8001,
proxy: '127.0.0.1:8000' proxy: '127.0.0.1:8000'

9232
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,7 @@
"cssnano": "^5.0.13", "cssnano": "^5.0.13",
"easymde": "^2.16.1", "easymde": "^2.16.1",
"fullcalendar": "^5.10.1", "fullcalendar": "^5.10.1",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-flatten": "^0.4.0", "gulp-flatten": "^0.4.0",
"gulp-if": "^3.0.0", "gulp-if": "^3.0.0",
@@ -29,12 +30,11 @@
"moment": "^2.29.4", "moment": "^2.29.4",
"node-sass": "^9.0.0", "node-sass": "^9.0.0",
"popper.js": "^1.16.1", "popper.js": "^1.16.1",
"postcss": "^8.4.31", "postcss": "^8.4.5",
"uglify-js": "^3.14.5" "uglify-js": "^3.14.5"
}, },
"devDependencies": { "devDependencies": {
"browser-sync": "^3.0.2", "browser-sync": "^2.27.11"
"gulp": "^5.0.0"
}, },
"scripts": { "scripts": {
"gulp": "gulp", "gulp": "gulp",

View File

@@ -17,12 +17,14 @@ jQuery(document).ready(function () {
}); });
} }
}); });
var easter_egg = new Konami(function () { var easter_egg = new Konami();
easter_egg.code = function () {
var s = document.createElement('script'); var s = document.createElement('script');
s.type = 'text/javascript'; s.type = 'text/javascript';
document.body.appendChild(s); document.body.appendChild(s);
s.src = '/static/js/asteroids.min.js'; s.src = '{% static "js/asteroids.min.js"%}';
}); ga('send', 'event', 'easter_egg', 'activated');
}
easter_egg.load(); easter_egg.load();
}); });
//CTRL-Enter form submission //CTRL-Enter form submission

View File

@@ -77,8 +77,17 @@
border-collapse: separate !important; border-collapse: separate !important;
border-spacing: 0; border-spacing: 0;
} }
#event_table tr th {
border-right: 0 !important;
}
#event_table tr td {
border-left: 0 !important;
}
#event_table tr td:not(:last-child) {
border-right: 0 !important;
}
@each $color, $value in $theme-colors { @each $color, $value in $theme-colors {
table.table-#{$color} { .table-#{$color} {
> td,th { > td,th {
border: 0.3em solid theme-color-level($color, -6) !important; border: 0.3em solid theme-color-level($color, -6) !important;
} }
@@ -87,11 +96,6 @@
background-color: #222 !important; background-color: #222 !important;
} }
} }
#event_row.table-#{$color} {
border: 0.3em solid theme-color-level($color, -6) !important;
background-color: #222 !important;
color: white !important;
}
} }
del { del {
color: black; color: black;
@@ -152,7 +156,4 @@
.modal { .modal {
overflow-y: auto !important; //Bootstrap Dark Theme overrides this to none for some insane reason so we need to change it back overflow-y: auto !important; //Bootstrap Dark Theme overrides this to none for some insane reason so we need to change it back
} }
.text-muted {
color: #c9c9c9 !important;
}
} }

View File

@@ -281,12 +281,3 @@ html.embedded {
.bootstrap-select, button.btn.dropdown-toggle.bs-placeholder.btn-light { .bootstrap-select, button.btn.dropdown-toggle.bs-placeholder.btn-light {
padding-right: 1rem !important; padding-right: 1rem !important;
} }
// New implementation of class dropped in Bootstrap 3
.dl-horizontal {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.7rem 0;
}
.dl-horizontal > dd, .dl-horizontal .markdown > p {
margin-bottom: 0 !important;
}

View File

@@ -12,8 +12,8 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
for person in Profile.objects.all(): for person in Profile.objects.all():
# Inactivate users that have not logged in for a year # Inactivate users that have not logged in for a year (or have never logged in)
if person.last_login is not None and (timezone.now() - person.last_login).days > 365: if person.last_login is None or (timezone.now() - person.last_login).days > 365:
person.is_active = False person.is_active = False
person.is_approved = False person.is_approved = False
person.save() person.save()

View File

@@ -167,11 +167,9 @@
<div class="col-lg-6"> <div class="col-lg-6">
<div class="card"> <div class="card">
<div class="card-header">Events</div> <div class="card-header">Events</div>
<div style="container-type: size; height: 30vh; overflow-y: scroll;">
{% with object.latest_events as events %} {% with object.latest_events as events %}
{% include 'partials/event_table.html' %} {% include 'partials/event_table.html' %}
{% endwith %} {% endwith %}
</div>
</div> </div>
</div> </div>
</div> </div>