Compare commits

...

4 Commits

Author SHA1 Message Date
1c126796a9 Fix active users bug in enter/user templates
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 34s
2024-02-18 23:05:43 +01:00
26ad2c6881 Add drivers excluded from points to raceresult model 2024-02-18 23:03:23 +01:00
ddca2748b3 Fix issue in database utils
Create db when loading dynamic data + users no longer static
2024-02-18 23:03:07 +01:00
b8316cc236 Add basic raceresult entering template with DnD 2024-02-18 23:02:40 +01:00
6 changed files with 181 additions and 9 deletions

View File

@ -37,7 +37,6 @@ def reload_static_data(db):
Team.query.delete() Team.query.delete()
Driver.query.delete() Driver.query.delete()
Race.query.delete() Race.query.delete()
User.query.delete()
# Reload static data # Reload static data
for row in load_csv("static_data/teams.csv"): for row in load_csv("static_data/teams.csv"):
@ -46,8 +45,6 @@ def reload_static_data(db):
db.session.add(Driver().from_csv(row)) db.session.add(Driver().from_csv(row))
for row in load_csv("static_data/races.csv"): for row in load_csv("static_data/races.csv"):
db.session.add(Race().from_csv(row)) db.session.add(Race().from_csv(row))
for row in load_csv("static_data/users.csv"):
db.session.add(User().from_csv(row))
db.session.commit() db.session.commit()
@ -55,6 +52,8 @@ def reload_static_data(db):
def reload_dynamic_data(db): def reload_dynamic_data(db):
print("Initializing Database with Dynamic Values...") print("Initializing Database with Dynamic Values...")
db.create_all()
# Clear dynamic data # Clear dynamic data
User.query.delete() User.query.delete()
RaceResult.query.delete() RaceResult.query.delete()

View File

@ -83,13 +83,14 @@ class User(db.Model):
class RaceResult(db.Model): class RaceResult(db.Model):
__tablename__ = "raceresult" __tablename__ = "raceresult"
__csv_header__ = ["id", "race_id", "pxx_ids_json", "dnf_ids_json"] __csv_header__ = ["id", "race_id", "pxx_ids_json", "dnf_ids_json", "exclude_ids_json"]
def from_csv(self, row): def from_csv(self, row):
self.id = int(row[0]) self.id = int(row[0])
self.race_id = int(row[1]) self.race_id = int(row[1])
self.pxx_ids_json = str(row[2]) self.pxx_ids_json = str(row[2])
self.dnf_ids_json = str(row[3]) self.dnf_ids_json = str(row[3])
self.exclude_ids_json = str(row[4])
return self return self
def to_csv(self): def to_csv(self):
@ -97,13 +98,15 @@ class RaceResult(db.Model):
self.id, self.id,
self.race_id, self.race_id,
self.pxx_ids_json, self.pxx_ids_json,
self.dnf_ids_json self.dnf_ids_json,
self.exclude_ids_json
] ]
id: Mapped[int] = mapped_column(Integer, primary_key=True) id: Mapped[int] = mapped_column(Integer, primary_key=True)
race_id: Mapped[int] = mapped_column(ForeignKey("race.id")) race_id: Mapped[int] = mapped_column(ForeignKey("race.id"))
pxx_ids_json: Mapped[str] = mapped_column(String(1024)) pxx_ids_json: Mapped[str] = mapped_column(String(1024))
dnf_ids_json: Mapped[str] = mapped_column(String(1024)) dnf_ids_json: Mapped[str] = mapped_column(String(1024))
exclude_ids_json: Mapped[str] = mapped_column(String(1024))
@property @property
def pxx_ids(self) -> List[str]: def pxx_ids(self) -> List[str]:
@ -121,10 +124,19 @@ class RaceResult(db.Model):
def dnf_ids(self, new_dnf_ids: List[str]): def dnf_ids(self, new_dnf_ids: List[str]):
self.dnf_ids_json = json.dumps(new_dnf_ids) self.dnf_ids_json = json.dumps(new_dnf_ids)
@property
def exclude_ids(self) -> List[str]:
return json.loads(self.exclude_ids_json)
@exclude_ids.setter
def exclude_ids(self, new_exclude_ids: List[str]):
self.exclude_ids_json = json.dumps(new_exclude_ids)
# Relationships # Relationships
race: Mapped["Race"] = relationship("Race", foreign_keys=[race_id]) race: Mapped["Race"] = relationship("Race", foreign_keys=[race_id])
_pxxs = None _pxxs = None
_dnfs = None _dnfs = None
_excludes = None
@property @property
def pxxs(self) -> List[Driver]: def pxxs(self) -> List[Driver]:
@ -144,6 +156,15 @@ class RaceResult(db.Model):
return self._dnfs return self._dnfs
@property
def excludes(self) -> List[Driver]:
if self._excludes is None:
self._excludes = [
driver for driver in Driver.query.all() if driver.name in self.exclude_ids
]
return self._excludes
class RaceGuess(db.Model): class RaceGuess(db.Model):
__tablename__ = "raceguess" __tablename__ = "raceguess"

View File

@ -0,0 +1,78 @@
// https://codepen.io/retrofuturistic/pen/DJWYBv
let dragSrcEl = null;
function handleDragStart(e) {
// Target (this) element is the source node.
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.outerHTML);
this.classList.add('dragElem');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault(); // Necessary. Allows us to drop.
}
this.classList.add('over');
e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
return false;
}
function handleDragEnter(e) {
// this / e.target is the current hover target.
}
function handleDragLeave(e) {
this.classList.remove('over'); // this / e.target is previous target element.
}
function handleDrop(e) {
// this/e.target is current target element.
if (e.stopPropagation) {
e.stopPropagation(); // Stops some browsers from redirecting.
}
// Don't do anything if dropping the same column we're dragging.
if (dragSrcEl != this) {
// Set the source column's HTML to the HTML of the column we dropped on.
//alert(this.outerHTML);
//dragSrcEl.innerHTML = this.innerHTML;
//this.innerHTML = e.dataTransfer.getData('text/html');
this.parentNode.removeChild(dragSrcEl);
let dropHTML = e.dataTransfer.getData('text/html');
this.insertAdjacentHTML('beforebegin', dropHTML);
let dropElem = this.previousSibling;
addDnDHandlers(dropElem);
}
this.classList.remove('over');
return false;
}
function handleDragEnd(e) {
// this/e.target is the source node.
this.classList.remove('over');
/*[].forEach.call(cols, function (col) {
col.classList.remove('over');
});*/
}
function addDnDHandlers(elem) {
elem.addEventListener('dragstart', handleDragStart, false);
elem.addEventListener('dragenter', handleDragEnter, false)
elem.addEventListener('dragover', handleDragOver, false);
elem.addEventListener('dragleave', handleDragLeave, false);
elem.addEventListener('drop', handleDrop, false);
elem.addEventListener('dragend', handleDragEnd, false);
}
const cols = document.querySelectorAll('#columns .column');
[].forEach.call(cols, addDnDHandlers);

View File

@ -0,0 +1,21 @@
/* https://codepen.io/retrofuturistic/pen/DJWYBv */
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
/* Required to make elements draggable in old WebKit */
-khtml-user-drag: element;
-webkit-user-drag: element;
}
.column {
cursor: move;
}
.column.over {
//border: 2px dashed #000;
border-top: 2px solid blue;
}

52
templates/enter.jinja Normal file
View File

@ -0,0 +1,52 @@
{% extends 'base.jinja' %}
{% set active_page = "/enter" %}
{% set active_user = none %}
{% block title %}Formula 10 - Race Result{% endblock title %}
{% block head_extra %}
<link href="../static/style/draggable.css" rel="stylesheet">
<script src="../static/script/draggable.js" defer></script>
{% endblock head_extra %}
{% block body %}
<div class="card shadow-sm" style="width: 450px;">
<div class="card-body">
<h5 class="card-title">{{ race.grandprix }}</h5>
<form action="/enterresult" method="post">
<ul id="columns" class="list-group list-group-flush">
{% for driver in drivers %}
<li class="list-group-item column p-1" draggable="true">
{{ driver.name }}
<div class="d-inline-block float-end">
{# Driver DNFed #}
<div class="form-check form-check-reverse d-inline-block">
<input type="checkbox" class="form-check-input" value="{{ driver.name }}"
id="dnf-{{ driver.name }}" name="dnf-drivers">
<label for="dnf-{{ driver.name }}" class="form-check-label text-muted">DNF</label>
</div>
{# Driver Excluded #}
<div class="form-check form-check-reverse d-inline-block mx-2">
<input type="checkbox" class="form-check-input" value="{{ driver.name }}"
id="exclude-{{ driver.name }}" name="exclude-drivers">
<label for="exclude-{{ driver.name }}" class="form-check-label text-muted">Exclude</label>
</div>
</div>
{# Standing order #}
<input type="hidden" name="pxxdrivers" value="{{ driver.name }}"></li>
{% endfor %}
</ul>
<input type="submit" class="btn btn-danger mt-2" value="Save">
</form>
</div>
</div>
{% endblock body %}

View File

@ -1,12 +1,13 @@
{% extends 'base.jinja' %} {% extends 'base.jinja' %}
{% set active_page = "/users" %} {% set active_page = "/users" %}
{% set active_user = none %}
{% block title %}Formula 10 - Users{% endblock title %} {% block title %}Formula 10 - Users{% endblock title %}
{% block body %} {% block body %}
<div class="card"> <div class="card shadow-sm">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Add User</h5> <h5 class="card-title">Add User</h5>
@ -25,7 +26,7 @@
</div> </div>
{% if users | length > 0 %} {% if users | length > 0 %}
<div class="card mt-2"> <div class="card mt-2 shadow-sm">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Registered Users</h5> <h5 class="card-title">Registered Users</h5>
@ -37,7 +38,7 @@
</div> </div>
</div> </div>
<div class="card mt-2"> <div class="card mt-2 shadow-sm">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Delete user</h5> <h5 class="card-title">Delete user</h5>
@ -67,7 +68,7 @@
</div> </div>
{% endif %} {% endif %}
<div class="card mt-2 border-danger"> <div class="card mt-2 border-danger shadow-sm">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Functions that should not be public</h5> <h5 class="card-title">Functions that should not be public</h5>
<h6 class="card-subtitle mb-2">(Fuck you if you click this without knowing what it does)</h6> <h6 class="card-subtitle mb-2">(Fuck you if you click this without knowing what it does)</h6>