Feat: Dogs page.

This commit is contained in:
2025-08-09 10:44:33 +01:00
parent d5e5e1a111
commit 77393d2057
46 changed files with 1718 additions and 640 deletions

View File

@@ -0,0 +1,45 @@
{% if is_blank_row %}
<tr class="{{ model.FLAG_ROW_NEW }} {{ model.FLAG_DOG }}" {{ model.ATTR_ID_DOG }}>
<td class="{{ model.FLAG_NAME }}">
<input type="text" class="{{ model.FLAG_NAME }}"
{{ model.ATTR_VALUE_CURRENT }} {{ model.ATTR_VALUE_PREVIOUS }} />
</td>
<td class="{{ model.FLAG_APPEARANCE }}">
<textarea class="{{ model.FLAG_APPEARANCE }}"
{{ model.ATTR_VALUE_CURRENT }}="" {{ model.ATTR_VALUE_PREVIOUS }}=""
></textarea>
</td>
<td class="{{ model.FLAG_MASS_KG }}">
<input type="number" min="0" step="0.001" class="{{ model.FLAG_MASS_KG }}"
{{ model.ATTR_VALUE_CURRENT }} {{ model.ATTR_VALUE_PREVIOUS }} />
</td>
{% include 'components/dog/_td_notes.html' %}
{% set active = True %}
{% include 'components/dog/_td_active.html' %}
</tr>
{% else %}
<tr class="{{ model.FLAG_DOG }}" {{ model.ATTR_ID_DOG }}="{{ dog.id_dog }}">
<td class="{{ model.FLAG_NAME }}">
<input type="text" class="{{ model.FLAG_NAME }}"
{{ model.ATTR_VALUE_CURRENT }}="{{ model.format_null_string_as_blank(dog.name)|escape }}"
{{ model.ATTR_VALUE_PREVIOUS }}="{{ model.format_null_string_as_blank(dog.name)|escape }}"
value="{{ model.format_null_string_as_blank(dog.name) }}" />
</td>
<td class="{{ model.FLAG_APPEARANCE }}">
<textarea class="{{ model.FLAG_APPEARANCE }}"
{{ model.ATTR_VALUE_CURRENT }}="{{ model.format_null_string_as_blank(dog.appearance)|escape }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ model.format_null_string_as_blank(dog.appearance)|escape }}"
>{{ model.format_null_string_as_blank(dog.appearance) }}</textarea>
</td>
<td class="{{ model.FLAG_MASS_KG }}">
<input type="number" min="0" step="0.001" class="{{ model.FLAG_MASS_KG }}"
{{ model.ATTR_VALUE_CURRENT }}="{{ dog.mass_kg }}"
{{ model.ATTR_VALUE_PREVIOUS }}="{{ dog.mass_kg }}"
value="{{ dog.mass_kg }}" />
</td>
{% set notes = dog.notes %}
{% include 'components/dog/_td_notes.html' %}
{% set active = dog.active %}
{% include 'components/dog/_td_active.html' %}
</tr>
{% endif %}

View File

@@ -30,6 +30,7 @@
var attrIdWeather = "{{ model.ATTR_ID_WEATHER }}";
var attrIdUser = "{{ model.ATTR_ID_USER }}";
var attrIdUserAuth0 = "{{ model.ATTR_ID_USER_AUTH0 }}";
var flagAppearance = "{{ model.FLAG_APPEARANCE }}";
var flagAssessment = "{{ model.FLAG_ASSESSMENT }}";
var flagAssessmentCommandModalityLink = "{{ model.FLAG_ASSESSMENT_COMMAND_MODALITY_LINK }}";
var flagAssessmentResponse = "{{ model.FLAG_ASSESSMENT_RESPONSE }}";
@@ -53,6 +54,7 @@
var flagLightingLevel = "{{ model.FLAG_LIGHTING_LEVEL }}";
var flagLocation = "{{ model.FLAG_LOCATION }}";
var flagLocationParent = "{{ model.FLAG_LOCATION_PARENT }}";
var flagMassKg = "{{ model.FLAG_MASS_KG }}";
var flagObedienceLevel = "{{ model.FLAG_OBEDIENCE_LEVEL }}";
var flagResponseQualityMetric = "{{ model.FLAG_RESPONSE_QUALITY_METRIC }}";
var flagRole = "{{ model.FLAG_ROLE }}";
@@ -67,6 +69,8 @@
var hashSaveDogCommandButtonLink = "{{ model.HASH_SAVE_DOG_COMMAND_BUTTON_LINK }}";
var hashSaveDogCommandCategory = "{{ model.HASH_SAVE_DOG_COMMAND_CATEGORY }}";
var hashSaveDogDogCommandLink = "{{ model.HASH_SAVE_DOG_DOG_COMMAND_LINK }}";
var hashSaveDogDogs = "{{ model.HASH_SAVE_DOG_DOGS }}";
var hashSaveDogLocation = "{{ model.HASH_SAVE_DOG_LOCATION }}";
var hashSaveDogUser = "{{ model.HASH_SAVE_DOG_USER }}";
var hashSaveUserCompany = "{{ model.HASH_SAVE_USER_COMPANY }}";
var hashSaveUserUser = "{{ model.HASH_SAVE_USER_USER }}";
</script>

View File

@@ -93,6 +93,7 @@
var flagNavDogLocations = "{{ model.FLAG_NAV_DOG_LOCATIONS }}";
var flagNavUserAccount = "{{ model.FLAG_NAV_USER_ACCOUNT }}";
var flagNavUserAccounts = "{{ model.FLAG_NAV_USER_ACCOUNTS }}";
var flagNavUserCompany = "{{ model.FLAG_NAV_USER_COMPANY }}";
var flagNavUserLogin = "{{ model.FLAG_NAV_USER_LOGIN }}";
var flagNavUserLogout = "{{ model.FLAG_NAV_USER_LOGOUT }}";
var flagNotes = "{{ model.FLAG_NOTES }}";
@@ -146,6 +147,7 @@
var hashPagePrivacyPolicy = "{{ model.HASH_PAGE_PRIVACY_POLICY }}";
var hashPageUserAccount = "{{ model.HASH_PAGE_USER_ACCOUNT }}";
var hashPageUserAccounts = "{{ model.HASH_PAGE_USER_ACCOUNTS }}";
var hashPageUserCompany = "{{ model.HASH_PAGE_USER_COMPANY }}";
var hashPageUserLogin = "{{ model.HASH_PAGE_USER_LOGIN }}";
var hashPageUserLogout = "{{ model.HASH_PAGE_USER_LOGOUT }}";
var idButtonApplyFilters = "#{{ model.ID_BUTTON_APPLY_FILTERS }}";

View File

@@ -0,0 +1,73 @@
{% extends 'layouts/layout_dog.html' %}
{% block page_body %}
<link rel="stylesheet" href="{{ url_for('static', filename='dist/css/dog_dogs.bundle.css') }}">
<form id="{{ model.ID_FORM_FILTERS }}" class="{{ model.FLAG_FILTER }} {{ model.FLAG_ROW }} {{ model.FLAG_CARD }}">
{{ model.form_filters.hidden_tag() }}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.FLAG_SEARCH }}">
{{ model.form_filters.search.label }}
{{ model.form_filters.search() }}
{% for error in model.form_filters.search.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.FLAG_ACTIVE_ONLY }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ model.form_filters.active_only.data }}">
{{ model.form_filters.active_only.label }}
{{ model.form_filters.active_only() }}
{% for error in model.form_filters.active_only.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
{% set class_name = model.FLAG_FILTER + ' ' + model.FLAG_ACTIVE_ONLY + ' ' + model.FLAG_CHECKBOX %}
{% include 'components/common/buttons/_icon_checkbox.html' %}
</div>
</div>
</div>
{% set block_id = 'buttons_table_default' %}
{% include 'components/common/buttons/_buttons_save_cancel.html' %}
</form>
<table id="{{ model.ID_TABLE_MAIN }}" class="{{ model.FLAG_TABLE_MAIN }} {{ model.FLAG_ROW }} {{ model.FLAG_CARD }} {{ model.FLAG_DOG }}">
<thead>
<tr class="{{ model.FLAG_DOG }}">
<th class="{{ model.FLAG_NAME }}">Name</th>
<th class="{{ model.FLAG_APPEARANCE }}">Appearance</th>
<th class="{{ model.FLAG_MASS_KG }}">Mass (kg)</th>
<th class="{{ model.FLAG_NOTES }}">Notes</th>
<th class="{{ model.FLAG_ACTIVE }}">
{% set class_name = model.FLAG_ACTIVE %}
{% set attribute_text = '' %}
{% include 'components/common/buttons/_icon_add.html' %}
</th>
</tr>
</thead>
<tbody>
{% set is_blank_row = False %}
{% for dog in model.dogs %}
{% include 'components/dog/_row_dog.html' %}
{% endfor %}
{% set is_blank_row = True %}
{% include 'components/dog/_row_dog.html' %}
</tbody>
</table>
{% include 'components/common/temporary/_overlay_confirm.html' %}
{% include 'components/common/temporary/_overlay_error.html' %}
<div id="{{ model.ID_CONTAINER_TEMPLATE_ELEMENTS }}">
<!-- Active column -->
<!-- Delete -->
{% set class_name = '' %}
{% include 'components/common/buttons/_icon_trash.html' %}
<!-- Undelete -->
{% set class_name = model.FLAG_ACTIVE %}
{% set attribute_text = '' %}
{% include 'components/common/buttons/_icon_add.html' %}
</div>
<script>
</script>
{% endblock %}

View File

@@ -7,17 +7,15 @@
<div class="{{ model.FLAG_CARD }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<h2 class="home-hero-title">Dog Training!</h2>
<!-- <h2 class="home-hero-title">Dog Training!</h2> -->
{% if not model.user.get_is_logged_in() %}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a class="{{ model.FLAG_NAV_USER_LOGIN }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Login</a>
</div>
{% elif True or model.user.can_admin_dog %}
{#
{% else %}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_DOGS }}" class="{{ model.FLAG_NAV_DOG_DOGS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Dogs</a>
</div>
#}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_COMMAND_CATEGORIES }}" class="{{ model.FLAG_NAV_DOG_COMMAND_CATEGORIES }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Command Categories</a>
</div>
@@ -42,26 +40,22 @@
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_ASSESSMENTS }}" class="{{ model.FLAG_NAV_DOG_ASSESSMENTS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Assessments</a>
</div>
{#
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_DISTRACTIONS }}" class="{{ model.FLAG_NAV_DOG_DISTRACTIONS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Distractions</a>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_ASSESSMENT_COMMAND_MODALITY_LINKS }}" class="{{ model.FLAG_NAV_DOG_ASSESSMENT_COMMAND_MODALITY_LINKS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Assessment Command Modality Links</a>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_ASSESSMENT_RESPONSES}}" class="{{ model.FLAG_NAV_DOG_ASSESSMENT_RESPONSES }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Assessment Responses</a>
</div>
#}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_DOG_CALENDAR_ENTRIES }}" class="{{ model.FLAG_NAV_DOG_CALENDAR_ENTRIES }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Overdue Bills</a>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_USER_ACCOUNT }}" class="{{ model.FLAG_NAV_USER_ACCOUNT }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">User Account</a>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_USER_ACCOUNTS }}" class="{{ model.FLAG_NAV_USER_ACCOUNTS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">User Accounts</a>
</div>
{% if model.user.can_admin_user %}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_USER_ACCOUNTS }}" class="{{ model.FLAG_NAV_USER_ACCOUNTS }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">User Accounts</a>
</div>
{% endif %}
{% if model.user.can_edit_company %}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<a href="{{ model.HASH_PAGE_USER_COMPANY }}" class="{{ model.FLAG_NAV_USER_COMPANY }} {{ model.FLAG_BUTTON }} {{ model.FLAG_BUTTON_PRIMARY }}">Company</a>
</div>
{% endif %}
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,84 @@
{% extends 'layouts/layout_dog.html' %}
{% block page_body %}
<link rel="stylesheet" href="{{ url_for('static', filename='dist/css/user_company.bundle.css') }}">
{% set company = model.companies[0] %}
<form id="{{ model.ID_FORM_FILTERS }}" class="{{ model.FLAG_FILTER }} {{ model.FLAG_ROW }} {{ model.FLAG_CARD }}">
{{ model.form_filters.hidden_tag() }}
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.FLAG_SEARCH }}">
{{ model.form_filters.search.label }}
{{ model.form_filters.search() }}
{% for error in model.form_filters.search.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.FLAG_ACTIVE_ONLY }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ model.form_filters.active_only.data }}">
{{ model.form_filters.active_only.label }}
{{ model.form_filters.active_only() }}
{% for error in model.form_filters.active_only.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
{% set class_name = model.FLAG_FILTER + ' ' + model.FLAG_ACTIVE_ONLY + ' ' + model.FLAG_CHECKBOX %}
{% include 'components/common/buttons/_icon_checkbox.html' %}
</div>
</div>
</div>
</form>
<div class="{{ model.FLAG_SAVE }} {{ model.FLAG_CANCEL }} {{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }}">
{% set block_id = 'button_save' %}
{% include 'components/common/buttons/_buttons_save_cancel.html' %}
</div>
</div>
<div class="{{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }}">
{% set block_id = 'button_cancel' %}
{% include 'components/common/buttons/_buttons_save_cancel.html' %}
</div>
</div>
</div>
</div>
<div class="{{ model.FLAG_USER }} {{ model.FLAG_CARD }} {{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}" {{ model.ATTR_ID_COMPANY }}="{{ company.id_company }}">
<div class="{{ model.FLAG_CONTAINER }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }}">
<label for="{{ model.FLAG_NAME }}">Name</label>
<input type="text" id="{{ model.FLAG_NAME }}" name="{{ model.FLAG_NAME }}" value="{{ company.name }}" />
</div>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }}">
<label for="{{ model.FLAG_WEBSITE }}">Website</label>
<textarea id="{{ model.FLAG_WEBSITE }}" name="{{ model.FLAG_WEBSITE }}" rows="4"
{{ model.ATTR_VALUE_PREVIOUS }}="{{ model.format_null_string_as_blank(company.website)|escape }}" {{ model.ATTR_VALUE_CURRENT }}="{{ model.format_null_string_as_blank(company.website)|escape }}"
>{{ model.format_null_string_as_blank(company.website) }}</textarea>
</div>
</div>
</div>
</div>
{% include 'components/common/temporary/_overlay_confirm.html' %}
{% include 'components/common/temporary/_overlay_error.html' %}
<div id="{{ model.ID_CONTAINER_TEMPLATE_ELEMENTS }}">
<!-- Active column -->
<!-- Delete -->
{% set class_name = '' %}
{% include 'components/common/buttons/_icon_trash.html' %}
<!-- Undelete -->
{% set class_name = model.FLAG_ACTIVE %}
{% set attribute_text = '' %}
{% include 'components/common/buttons/_icon_add.html' %}
</div>
<script>
</script>
{% endblock %}

View File

@@ -37,24 +37,41 @@
</div>
</form>
<div class="{{ model.FLAG_SAVE }} {{ model.FLAG_CANCEL }} {{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }}">
{% set block_id = 'button_save' %}
{% include 'components/common/buttons/_buttons_save_cancel.html' %}
</div>
</div>
<div class="{{ model.FLAG_COLUMN }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }}">
{% set block_id = 'button_cancel' %}
{% include 'components/common/buttons/_buttons_save_cancel.html' %}
</div>
</div>
</div>
</div>
<div class="{{ model.FLAG_USER }} {{ model.FLAG_CARD }} {{ model.FLAG_CONTAINER }} {{ model.FLAG_COLUMN }}" {{ model.ATTR_ID_USER }}="{{ user.id_user }}">
<div class="{{ model.FLAG_CONTAINER }}">
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }}">
<label for="{{ model.FLAG_FIRSTNAME }}">Firstname</label>
<input type="text" id="{{ model.FLAG_FIRSTNAME }}" name="{{ model.FLAG_FIRSTNAME }}" value="{{ user.firstname }}" />
<input type="text" id="{{ model.FLAG_FIRSTNAME }}" name="{{ model.FLAG_FIRSTNAME }}" value="{{ user.firstname|escape }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ user.firstname|escape }}" />
</div>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }}">
<label for="{{ model.FLAG_SURNAME }}">Surname</label>
<input type="text" id="{{ model.FLAG_SURNAME }}" name="{{ model.FLAG_SURNAME }}" value="{{ user.surname }}" />
<input type="text" id="{{ model.FLAG_SURNAME }}" name="{{ model.FLAG_SURNAME }}" value="{{ user.surname|escape }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ user.surname|escape }}" />
</div>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }}">
<label for="{{ model.FLAG_EMAIL }}">Email</label>
<input type="email" id="{{ model.FLAG_EMAIL }}" name="{{ model.FLAG_EMAIL }}" value="{{ user.email }}" />
<input type="email" id="{{ model.FLAG_EMAIL }}" name="{{ model.FLAG_EMAIL }}" value="{{ user.email|escape }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ user.email|escape }}" />
</div>
</div>
<div class="{{ model.FLAG_CONTAINER }} {{ model.FLAG_ROW }}">
@@ -94,14 +111,10 @@
</div>
<script>
{#
var assessments = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.assessments) | tojson | safe }};
var filterLightingLevels = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_lighting_levels) | tojson | safe }};
var filterLocations = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_locations) | tojson | safe }};
var filterUserHandlers = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_user_handlers) | tojson | safe }};
var filterWeathers = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_weathers) | tojson | safe }};
var flagTemperatureCelcius = "{{ model.FLAG_TEMPERATURE_CELCIUS }}";
var flagUserHandler = "{{ model.FLAG_USER_HANDLER }}";
#}
var company = {{ model.user.company.to_json() | tojson | safe }};
var flagCanAdminDog = "{{ model.FLAG_CAN_ADMIN_DOG }}";
var flagCanAdminUser = "{{ model.FLAG_CAN_ADMIN_USER }}";
var flagIsEmailVerified = "{{ model.FLAG_IS_EMAIL_VERIFIED }}";
var flagIsSuperUser = "{{ model.FLAG_IS_SUPER_USER }}";
</script>
{% endblock %}