Fix tags, may have increased load on database while only using one query to fetch workout, topsets, and all tags
This commit is contained in:
4
app.py
4
app.py
@@ -376,8 +376,8 @@ def get_workout_note(person_id, workout_id):
|
|||||||
@ app.route("/person/<int:person_id>/workout/<int:workout_id>/tag/add", methods=['POST'])
|
@ app.route("/person/<int:person_id>/workout/<int:workout_id>/tag/add", methods=['POST'])
|
||||||
def add_tag_to_workout(person_id, workout_id):
|
def add_tag_to_workout(person_id, workout_id):
|
||||||
tags_id = [int(i) for i in request.form.getlist('tag_id')]
|
tags_id = [int(i) for i in request.form.getlist('tag_id')]
|
||||||
workout_tags = db.add_tag_for_workout(workout_id, tags_id)
|
tags = db.add_tag_for_workout(workout_id, tags_id)
|
||||||
return render_template('partials/workout_tags_list.html', workout_tags=workout_tags)
|
return render_template('partials/workout_tags_list.html', tags=tags)
|
||||||
|
|
||||||
|
|
||||||
@ app.route("/person/<int:person_id>/workout/<int:workout_id>/tag/new", methods=['POST'])
|
@ app.route("/person/<int:person_id>/workout/<int:workout_id>/tag/new", methods=['POST'])
|
||||||
|
|||||||
15
db.py
15
db.py
@@ -342,7 +342,8 @@ class DataBase():
|
|||||||
note, person_id, workout_id], commit=True)
|
note, person_id, workout_id], commit=True)
|
||||||
|
|
||||||
def add_tag_for_workout(self, workout_id, tags_id):
|
def add_tag_for_workout(self, workout_id, tags_id):
|
||||||
# First, delete tags that are not in the new selection
|
# If tags_id is not empty, delete tags that are not in the new selection
|
||||||
|
if tags_id:
|
||||||
self.execute(
|
self.execute(
|
||||||
"""
|
"""
|
||||||
DELETE FROM workout_tag
|
DELETE FROM workout_tag
|
||||||
@@ -350,6 +351,15 @@ class DataBase():
|
|||||||
""",
|
""",
|
||||||
[workout_id, tuple(tags_id)], commit=True
|
[workout_id, tuple(tags_id)], commit=True
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
# If tags_id is empty, delete all tags for this workout
|
||||||
|
self.execute(
|
||||||
|
"""
|
||||||
|
DELETE FROM workout_tag
|
||||||
|
WHERE workout_id = %s
|
||||||
|
""",
|
||||||
|
[workout_id], commit=True
|
||||||
|
)
|
||||||
|
|
||||||
# Then, attempt to insert the new tags
|
# Then, attempt to insert the new tags
|
||||||
for tag_id in tags_id:
|
for tag_id in tags_id:
|
||||||
@@ -368,7 +378,8 @@ class DataBase():
|
|||||||
T.tag_id AS "tag_id",
|
T.tag_id AS "tag_id",
|
||||||
T.person_id AS "person_id",
|
T.person_id AS "person_id",
|
||||||
T.name AS "tag_name",
|
T.name AS "tag_name",
|
||||||
T.filter AS "tag_filter"
|
T.filter AS "tag_filter",
|
||||||
|
TRUE AS "is_selected"
|
||||||
FROM Workout_Tag WT
|
FROM Workout_Tag WT
|
||||||
LEFT JOIN Tag T ON WT.tag_id=T.tag_id
|
LEFT JOIN Tag T ON WT.tag_id=T.tag_id
|
||||||
WHERE WT.workout_id=%s""", [workout_id])
|
WHERE WT.workout_id=%s""", [workout_id])
|
||||||
|
|||||||
@@ -18,17 +18,19 @@ class Workout:
|
|||||||
t.repetitions,
|
t.repetitions,
|
||||||
t.weight,
|
t.weight,
|
||||||
tag.tag_id,
|
tag.tag_id,
|
||||||
tag.name AS tag_name
|
tag.name AS tag_name,
|
||||||
|
tag.filter as tag_filter,
|
||||||
|
CASE WHEN wt.workout_id IS NOT NULL THEN TRUE ELSE FALSE END AS is_selected
|
||||||
FROM
|
FROM
|
||||||
workout w
|
workout w
|
||||||
JOIN
|
LEFT JOIN
|
||||||
topset t ON w.workout_id = t.workout_id
|
topset t ON w.workout_id = t.workout_id
|
||||||
JOIN
|
LEFT JOIN
|
||||||
exercise e ON t.exercise_id = e.exercise_id
|
exercise e ON t.exercise_id = e.exercise_id
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
workout_tag wt ON w.workout_id = wt.workout_id
|
workout_tag wt ON w.workout_id = wt.workout_id
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
tag ON wt.tag_id = tag.tag_id
|
tag ON TRUE -- Join to get all tags
|
||||||
WHERE
|
WHERE
|
||||||
w.person_id = %s
|
w.person_id = %s
|
||||||
AND w.workout_id = %s;
|
AND w.workout_id = %s;
|
||||||
@@ -38,8 +40,6 @@ class Workout:
|
|||||||
if not data:
|
if not data:
|
||||||
return {"error": "Workout not found"}, 404
|
return {"error": "Workout not found"}, 404
|
||||||
|
|
||||||
exercises = self.execute("SELECT exercise_id, name FROM exercise;")
|
|
||||||
|
|
||||||
# Initialize workout dictionary
|
# Initialize workout dictionary
|
||||||
workout_data = {
|
workout_data = {
|
||||||
"workout_id": data[0]["workout_id"],
|
"workout_id": data[0]["workout_id"],
|
||||||
@@ -48,7 +48,6 @@ class Workout:
|
|||||||
"note": data[0]["note"],
|
"note": data[0]["note"],
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"top_sets": [],
|
"top_sets": [],
|
||||||
"exercises": exercises
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Initialize helpers for tracking unique tags and topsets
|
# Initialize helpers for tracking unique tags and topsets
|
||||||
@@ -57,15 +56,21 @@ class Workout:
|
|||||||
|
|
||||||
# Process each row and add tags and topsets to workout_data
|
# Process each row and add tags and topsets to workout_data
|
||||||
for row in data:
|
for row in data:
|
||||||
# Add unique tags
|
# Add all unique tags with is_selected property
|
||||||
tag_id = row["tag_id"]
|
tag_id = row["tag_id"]
|
||||||
if tag_id and tag_id not in tag_set:
|
if tag_id and tag_id not in tag_set:
|
||||||
workout_data["tags"].append({"tag_id": tag_id, "tag_name": row["tag_name"]})
|
workout_data["tags"].append({
|
||||||
|
"tag_id": tag_id,
|
||||||
|
"tag_name": row["tag_name"],
|
||||||
|
"tag_filter": row["tag_filter"],
|
||||||
|
"person_id": person_id,
|
||||||
|
"is_selected": row["is_selected"]
|
||||||
|
})
|
||||||
tag_set.add(tag_id)
|
tag_set.add(tag_id)
|
||||||
|
|
||||||
# Add unique topsets based on topset_id
|
# Add unique topsets based on topset_id
|
||||||
topset_id = row["topset_id"]
|
topset_id = row["topset_id"]
|
||||||
if topset_id not in topsets_seen:
|
if topset_id and topset_id not in topsets_seen:
|
||||||
workout_data["top_sets"].append({
|
workout_data["top_sets"].append({
|
||||||
"topset_id": topset_id,
|
"topset_id": topset_id,
|
||||||
"exercise_id": row["exercise_id"],
|
"exercise_id": row["exercise_id"],
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div id="tag-wrapper-w-{{ workout_id }}">
|
<div id="tag-wrapper-w-{{ workout_id }}">
|
||||||
{{ render_partial('partials/workout_tags_list.html', workout_tags=workout_tags)
|
{{ render_partial('partials/workout_tags_list.html', tags=tags)}}
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
<span id="tag-form-show-w-{{ workout_id }}" class="cursor-pointer" _="on click
|
<span id="tag-form-show-w-{{ workout_id }}" class="cursor-pointer" _="on click
|
||||||
remove .hidden from #tag-form-w-{{ workout_id }}
|
remove .hidden from #tag-form-w-{{ workout_id }}
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="tag-form-w-{{ workout_id }}" class="hidden pt-2 pb-3 animate-fadeIn">
|
<div id="tag-form-w-{{ workout_id }}" class="hidden pt-2 pb-3">
|
||||||
|
|
||||||
<span class="text-base font-normal text-gray-500">Add tag to workout</span>
|
<span class="text-base font-normal text-gray-500">Add tag to workout</span>
|
||||||
|
|
||||||
@@ -46,10 +45,10 @@
|
|||||||
placeholder: 'Select tags',
|
placeholder: 'Select tags',
|
||||||
})
|
})
|
||||||
end">
|
end">
|
||||||
{% for p in person_tags %}
|
{% for tag in tags %}
|
||||||
<option value="{{ p.tag_id }}" {% if p.tag_id in selected_workout_tag_ids %}selected{% endif %}>
|
<option value="{{ tag.tag_id }}" {% if tag.is_selected %}selected{% endif %}>
|
||||||
{{
|
{{
|
||||||
p.tag_name
|
tag.tag_name
|
||||||
}}</option>
|
}}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
{% for tag in workout_tags %}
|
{% for tag in tags %}
|
||||||
|
{% if tag.is_selected %}
|
||||||
<span
|
<span
|
||||||
class="text-xs font-semibold inline-block py-1 px-2 uppercase rounded text-pink-600 bg-pink-200 uppercase last:mr-0 mr-1 max-h-fit cursor-pointer"
|
class="text-xs font-semibold inline-block py-1 px-2 uppercase rounded text-pink-600 bg-pink-200 uppercase last:mr-0 mr-1 max-h-fit cursor-pointer"
|
||||||
hx-get="{{ url_for('goto_tag') }}" hx-vals='{"filter": "{{ tag.tag_filter }}", "person_id": "{{ tag.person_id }}"}'
|
hx-get="{{ url_for('goto_tag') }}" hx-vals='{"filter": "{{ tag.tag_filter }}", "person_id": "{{ tag.person_id }}"}'
|
||||||
hx-target="#container" hx-push-url="true" _='on click trigger closeModalWithoutRefresh'>{{
|
hx-target="#container" hx-push-url="true">{{
|
||||||
tag.tag_name }}
|
tag.tag_name }}
|
||||||
</span>
|
</span>
|
||||||
|
{% endif %}
|
||||||
{% endfor%}
|
{% endfor%}
|
||||||
@@ -13,10 +13,8 @@
|
|||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<h3 class="text-xl font-bold text-gray-900">{{ person_name }}</h3>
|
<h3 class="text-xl font-bold text-gray-900">{{ person_name }}</h3>
|
||||||
|
|
||||||
{{ render_partial('partials/workout_tags.html', person_id=person_id,
|
{{ render_partial('partials/workout_tags.html', person_id=person_id, workout_id=workout_id,
|
||||||
workout_id=workout_id,
|
tags=tags) }}
|
||||||
person_tags=person_tags, workout_tags=workout_tags,
|
|
||||||
selected_workout_tag_ids=selected_workout_tag_ids) }}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user