Switch to using hyperscript to initialise tailwind elements(select) and graphs(Plotly), this removes script tags and ids
This commit is contained in:
5
app.py
5
app.py
@@ -439,6 +439,11 @@ def get_first_element_from_list_with_matching_attribute(list, attribute, value):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@app.template_filter('replace_double_quote_strings_with_single_quote')
|
||||||
|
def replace_double_quote_strings_with_single_quote(str):
|
||||||
|
return str.replace('"', "'")
|
||||||
|
|
||||||
|
|
||||||
@ app.context_processor
|
@ app.context_processor
|
||||||
def my_utility_processor():
|
def my_utility_processor():
|
||||||
|
|
||||||
|
|||||||
@@ -41,16 +41,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mr-4">
|
<div class="mr-4">
|
||||||
<select id="workout-view-picker" data-te-select-init data-te-select-size="lg" name="view"
|
<select data-te-select-init data-te-select-size="lg" name="view"
|
||||||
hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
|
hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
|
||||||
hx-vals='{"date": "{{ selected_date }}"}' hx-push-url="true">
|
hx-vals='{"date": "{{ selected_date }}"}' hx-push-url="true" _="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue('{{ selected_view | safe }}')
|
||||||
|
end">
|
||||||
<option value="month" {% if selected_view=='month' %}selected{% endif %}>Month</option>
|
<option value="month" {% if selected_view=='month' %}selected{% endif %}>Month</option>
|
||||||
<option value="year" {% if selected_view=='year' %}selected{% endif %}>Year</option>
|
<option value="year" {% if selected_view=='year' %}selected{% endif %}>Year</option>
|
||||||
<option value="all">All</option>
|
<option value="all">All</option>
|
||||||
</select>
|
</select>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#workout-view-picker")).setValue("{{ selected_view | safe }}"));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
<select class="bg-gray-50 border border-gray-300 hidden" data-te-select-filter="true"
|
<select class="bg-gray-50 border border-gray-300 hidden" data-te-select-filter="true"
|
||||||
data-te-select-init="" data-te-select-size="lg" hx-get="{{ url_for('dashboard') }}"
|
data-te-select-init="" data-te-select-size="lg" hx-get="{{ url_for('dashboard') }}"
|
||||||
hx-include="[name='min_date'],[name='max_date'],[name='exercise_id']" hx-push-url="true"
|
hx-include="[name='min_date'],[name='max_date'],[name='exercise_id']" hx-push-url="true"
|
||||||
hx-target="#container" id="dashboard-people-multi-select" multiple="" name="person_id">
|
hx-target="#container" multiple="" name="person_id" _="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue({{ selected_person_ids | list_to_string | safe}})
|
||||||
|
end">
|
||||||
{% for p in people %}
|
{% for p in people %}
|
||||||
<option value="{{ p['PersonId'] }}">{{
|
<option value="{{ p['PersonId'] }}">{{
|
||||||
p['Name']
|
p['Name']
|
||||||
@@ -22,7 +24,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#dashboard-people-multi-select")).setValue({{ selected_person_ids | list_to_string | safe}}))</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full lg:w-1/4 sm:w-full px-3 mb-6 md:mb-0">
|
<div class="w-full lg:w-1/4 sm:w-full px-3 mb-6 md:mb-0">
|
||||||
@@ -34,7 +35,9 @@
|
|||||||
<select class="bg-gray-50 border border-gray-300 hidden" data-te-select-filter="true"
|
<select class="bg-gray-50 border border-gray-300 hidden" data-te-select-filter="true"
|
||||||
data-te-select-init="" data-te-select-size="lg" hx-get="{{ url_for('dashboard') }}"
|
data-te-select-init="" data-te-select-size="lg" hx-get="{{ url_for('dashboard') }}"
|
||||||
hx-include="[name='min_date'],[name='max_date'],[name='person_id']" hx-push-url="true"
|
hx-include="[name='min_date'],[name='max_date'],[name='person_id']" hx-push-url="true"
|
||||||
hx-target="#container" id="dashboard-exercise-multi-select" multiple="" name="exercise_id">
|
hx-target="#container" multiple="" name="exercise_id" _="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue({{ selected_exercise_ids | list_to_string | safe}})
|
||||||
|
end">
|
||||||
{% for e in exercises %}
|
{% for e in exercises %}
|
||||||
<option value="{{ e['ExerciseId'] }}">{{
|
<option value="{{ e['ExerciseId'] }}">{{
|
||||||
e['Name']
|
e['Name']
|
||||||
@@ -43,7 +46,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script> window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#dashboard-exercise-multi-select")).setValue({{ selected_exercise_ids | list_to_string | safe}}))</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full lg:w-1/4 sm:w-full px-3 mb-6 md:mb-0"><label
|
<div class="w-full lg:w-1/4 sm:w-full px-3 mb-6 md:mb-0"><label
|
||||||
@@ -126,17 +128,15 @@
|
|||||||
<div class="shadow overflow-hidden sm:rounded-lg">
|
<div class="shadow overflow-hidden sm:rounded-lg">
|
||||||
<h4 class="text-l font-semibold text-blue-400 mb-2 text-center">{{ e['ExerciseName'] }}</h4>
|
<h4 class="text-l font-semibold text-blue-400 mb-2 text-center">{{ e['ExerciseName'] }}</h4>
|
||||||
{% if e['RepMaxes']|length > 1 %}
|
{% if e['RepMaxes']|length > 1 %}
|
||||||
<div id="person-{{ p['PersonId'] }}-exercise-{{ e['ExerciseId'] }}"
|
<div class="w-full mt-2 aspect-video" _="init js(me)
|
||||||
class="w-full mt-2 aspect-video"></div>
|
Plotly.newPlot(me, [{
|
||||||
<script>
|
x: {{ e['EstimatedOneRepMaxProgressions']['StartDates'] | replace_double_quote_strings_with_single_quote | safe }},
|
||||||
window.addEventListener('DOMContentLoaded', _ => Plotly.newPlot(document.getElementById("person-{{ p['PersonId'] }}-exercise-{{ e['ExerciseId'] }}"), [{
|
y: {{ e['EstimatedOneRepMaxProgressions']['Estimated1RMs'] | replace_double_quote_strings_with_single_quote | safe }},
|
||||||
x: {{ e['EstimatedOneRepMaxProgressions']['StartDates'] | replace('"', "'") | safe }},
|
text: {{ e['EstimatedOneRepMaxProgressions']['TopSets'] | replace_double_quote_strings_with_single_quote | safe }},
|
||||||
y: {{ e['EstimatedOneRepMaxProgressions']['Estimated1RMs'] | replace('"', "'") | safe }},
|
name: '{{ p['PersonName'] }} - {{ e['ExerciseName'] }}' , hovertemplate }], layout,
|
||||||
text: {{ e['EstimatedOneRepMaxProgressions']['TopSets'] | replace('"', "'") | safe }},
|
config)
|
||||||
name: "{{ p['PersonName'] }} - {{ e['ExerciseName'] }}",
|
end">
|
||||||
hovertemplate
|
</div>
|
||||||
}], layout, config));
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<table class="min-w-full divide-y divide-gray-200">
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
|
|||||||
@@ -8,9 +8,11 @@
|
|||||||
}}</span>
|
}}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<select id="topset-exercise-select-{{ topset_id }}" data-te-select-init data-te-select-filter="true"
|
<select data-te-select-init data-te-select-filter="true" data-te-select-size="lg" name="exercise_id"
|
||||||
data-te-select-size="lg" name="exercise_id"
|
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
|
||||||
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500">
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue('{{ exercise_id }}')
|
||||||
|
end">
|
||||||
{% for exercise in exercises|default([], true) %}
|
{% for exercise in exercises|default([], true) %}
|
||||||
<option value="{{ exercise['ExerciseId'] }}">{{
|
<option value="{{ exercise['ExerciseId'] }}">{{
|
||||||
exercise['Name']
|
exercise['Name']
|
||||||
@@ -18,9 +20,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#topset-exercise-select-{{ topset_id }}")).setValue("{{ exercise_id }}"));
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="p-4 whitespace-nowrap text-sm font-semibold text-gray-900">
|
<td class="p-4 whitespace-nowrap text-sm font-semibold text-gray-900">
|
||||||
|
|||||||
@@ -113,9 +113,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<select id="workout-exercise-select-{{ workout['WorkoutId'] }}" data-te-select-init
|
<select data-te-select-init data-te-select-filter="true" data-te-select-size="lg"
|
||||||
data-te-select-filter="true" data-te-select-size="lg" name="exercise_id"
|
name="exercise_id"
|
||||||
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500">
|
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
|
||||||
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me)
|
||||||
|
end">
|
||||||
{% for e in workout['Exercises'] %}
|
{% for e in workout['Exercises'] %}
|
||||||
<option value="{{ e['ExerciseId'] }}">{{
|
<option value="{{ e['ExerciseId'] }}">{{
|
||||||
e['Name']
|
e['Name']
|
||||||
@@ -123,9 +126,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#workout-exercise-select-{{ workout['WorkoutId'] }}")));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,14 @@
|
|||||||
</label>
|
</label>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<select id="workout-tag-select-{{ workout_id }}" data-te-select-init data-te-select-filter="true"
|
<select data-te-select-init data-te-select-filter="true" data-te-select-size="lg" multiple
|
||||||
data-te-select-size="lg" multiple name="tag_id"
|
name="tag_id"
|
||||||
hx-post="{{ url_for('add_tag_to_workout', person_id=person_id, workout_id=workout_id) }}"
|
hx-post="{{ url_for('add_tag_to_workout', person_id=person_id, workout_id=workout_id) }}"
|
||||||
hx-target="#tag-wrapper-w-{{ workout_id }}"
|
hx-target="#tag-wrapper-w-{{ workout_id }}"
|
||||||
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500">
|
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
|
||||||
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue({{ selected_workout_tag_ids | list_to_string | safe }})
|
||||||
|
end">
|
||||||
{% for p in person_tags %}
|
{% for p in person_tags %}
|
||||||
<option value="{{ p.tag_id }}">{{
|
<option value="{{ p.tag_id }}">{{
|
||||||
p.tag_name
|
p.tag_name
|
||||||
@@ -47,9 +50,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#workout-tag-select-{{ workout_id }}")).setValue({{ selected_workout_tag_ids| list_to_string | safe }}));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<select id="workout-view-picker" data-te-select-init
|
<select data-te-select-init
|
||||||
data-te-select-size="lg" name="view"
|
data-te-select-size="lg" name="view"
|
||||||
hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
|
hx-get="{{ url_for('get_calendar', person_id=person['PersonId']) }}" hx-target="#container"
|
||||||
hx-push-url="true">
|
hx-push-url="true"
|
||||||
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue('all')
|
||||||
|
end">
|
||||||
<option value="month">Month</option>
|
<option value="month">Month</option>
|
||||||
<option value="year">Year</option>
|
<option value="year">Year</option>
|
||||||
<option value="all" selected>All</option>
|
<option value="all" selected>All</option>
|
||||||
</select>
|
</select>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#workout-view-picker")).setValue("all"));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,11 +43,14 @@
|
|||||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
||||||
Exercises
|
Exercises
|
||||||
</label>
|
</label>
|
||||||
<select id="multiSelection" data-te-select-init data-te-select-filter="true"
|
<select data-te-select-init data-te-select-filter="true"
|
||||||
data-te-select-size="lg" name="exercise_id" class="bg-gray-50 border border-gray-300 " multiple
|
data-te-select-size="lg" name="exercise_id" class="bg-gray-50 border border-gray-300 " multiple
|
||||||
hx-get="{{ url_for('get_person', person_id=person['PersonId']) }}"
|
hx-get="{{ url_for('get_person', person_id=person['PersonId']) }}"
|
||||||
hx-include="[name='exercise_id'],[name='min_date'],[name='max_date'],[name='graph_axis']"
|
hx-include="[name='exercise_id'],[name='min_date'],[name='max_date'],[name='graph_axis']"
|
||||||
hx-target="#container" hx-push-url="true">
|
hx-target="#container" hx-push-url="true"
|
||||||
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue({{ selected_exercise_ids| list_to_string | safe }})
|
||||||
|
end">
|
||||||
{% for e in person['Exercises'] %}
|
{% for e in person['Exercises'] %}
|
||||||
<option value="{{ e['ExerciseId'] }}">{{
|
<option value="{{ e['ExerciseId'] }}">{{
|
||||||
e['ExerciseName']
|
e['ExerciseName']
|
||||||
@@ -55,9 +58,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#multiSelection")).setValue({{ selected_exercise_ids| list_to_string | safe }}));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full md:w-1/4 px-3 mb-6 md:mb-0">
|
<div class="w-full md:w-1/4 px-3 mb-6 md:mb-0">
|
||||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
||||||
@@ -106,19 +106,19 @@
|
|||||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-city">
|
||||||
Graph Axis
|
Graph Axis
|
||||||
</label>
|
</label>
|
||||||
<select id="graph-axis-multiselect" data-te-select-init data-te-select-filter="true"
|
<select data-te-select-init data-te-select-filter="true"
|
||||||
data-te-select-size="lg" name="graph_axis" class="bg-gray-50 border border-gray-300 " multiple
|
data-te-select-size="lg" name="graph_axis" class="bg-gray-50 border border-gray-300 " multiple
|
||||||
hx-get="{{ url_for('get_person', person_id=person['PersonId']) }}"
|
hx-get="{{ url_for('get_person', person_id=person['PersonId']) }}"
|
||||||
hx-include="[name='exercise_id'],[name='min_date'],[name='max_date'],[name='graph_axis']"
|
hx-include="[name='exercise_id'],[name='min_date'],[name='max_date'],[name='graph_axis']"
|
||||||
hx-target="#container" hx-push-url="true">
|
hx-target="#container" hx-push-url="true"
|
||||||
|
_="init js(me)
|
||||||
|
te.Select.getOrCreateInstance(me).setValue({{ graph_axis | safe }})
|
||||||
|
end">
|
||||||
<option value="repetitions">Repetitions</option>
|
<option value="repetitions">Repetitions</option>
|
||||||
<option value="weight">Weigh</option>
|
<option value="weight">Weigh</option>
|
||||||
<option value="estimated1rm">Estimated 1RM</option>
|
<option value="estimated1rm">Estimated 1RM</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
window.addEventListener('DOMContentLoaded', _ => te.Select.getOrCreateInstance(document.querySelector("#graph-axis-multiselect")).setValue({{ graph_axis | safe }}));
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user