Feat(SQL, UI): 1. Perfected architecture for modular Search functionality across heirarchical Get Many and Calc Stored Procedures that allows text search filtering on different fields as well as by record Id with control over how the filters are applied. \n 2. Updated User Calc and Get Many Stored Procedures with new Search functionality. \n 3. Improved styles on Dog Command Link page.

This commit is contained in:
2025-07-05 23:17:07 +01:00
parent 0d1e644e6c
commit 8cb8508dcd
51 changed files with 4161 additions and 1292 deletions

View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"
fill="{{ colour }}"
class="{{ model.FLAG_ICON }} {{ model.FLAG_CHECKBOX }} {{ class_name }}"
>
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
<path d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/>
</svg>

After

Width:  |  Height:  |  Size: 604 B

View File

@@ -1,15 +1,2 @@
{% if not is_blank_row %}
<div
class="{{ model.FLAG_COMMAND }}"
{{ model.ATTR_VALUE_CURRENT }}="{{ command.id_command }}"
{{ model.ATTR_VALUE_PREVIOUS }}="{{ command.id_command }}"
>{{ command.name }}</div>
{% else %}
<select class="{{ model.FLAG_COMMAND }}" {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0">
{% include 'components/common/inputs/_option_blank.html' %}
{% for command in model.filter_commands %}
<option value="{{ command.id_command }}">{{ command.name }}</option>
{% endfor %}
</select>
{% endif %}
<div class="{{ model.FLAG_COMMAND }}" >{% if not is_blank_row %}{{ command.name }}{% endif %}</div>

View File

@@ -0,0 +1,2 @@
<div class="{{ model.FLAG_COMMAND_CATEGORY }}" >{% if not is_blank_row %}{{ command_category.name }}{% endif %}</div>

View File

@@ -1,15 +1,2 @@
{% if not is_blank_row %}
<div
class="{{ model.FLAG_DOG }}"
{{ model.ATTR_VALUE_CURRENT }}="{{ dog.id_dog }}"
{{ model.ATTR_VALUE_PREVIOUS }}="{{ dog.id_dog }}"
>{{ dog.name }}</div>
{% else %}
<select class="{{ model.FLAG_DOG }}" {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0">
{% include 'components/common/inputs/_option_blank.html' %}
{% for dog in model.filter_dogs %}
<option value="{{ dog.id_dog }}">{{ dog.name }}</option>
{% endfor %}
</select>
{% endif %}
<div class="{{ model.FLAG_DOG }}" >{% if not is_blank_row %}{{ dog.name }}{% endif %}</div>

View File

@@ -4,6 +4,9 @@
<td class="{{ model.FLAG_DOG }}" {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0">
{% include 'components/dog/_preview_DDL_dog.html' %}
</td>
<td class="{{ model.FLAG_COMMAND_CATEGORY }}" {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0">
{% include 'components/dog/_preview_DDL_command_category.html' %}
</td>
<td class="{{ model.FLAG_COMMAND }}" {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0">
{% include 'components/dog/_preview_DDL_command.html' %}
</td>
@@ -19,11 +22,15 @@
{% else %}
<tr class="{{ model.FLAG_DOG_COMMAND_LINK }}" {{ model.ATTR_ID_DOG_COMMAND_LINK }}="{{ link.id_link }}">
{% set dog = link.dog %}
<td class="{{ model.FLAG_DOG }}" {{ model.ATTR_VALUE_CURRENT }}="{{ link.id_dog }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ link.id_dog }}">
<td class="{{ model.FLAG_DOG }}" {{ model.ATTR_VALUE_CURRENT }}="{{ dog.id_dog }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ dog.id_dog }}">
{% include 'components/dog/_preview_DDL_dog.html' %}
</td>
{% set command_category = link.command.command_category %}
<td class="{{ model.FLAG_COMMAND_CATEGORY }}" {{ model.ATTR_VALUE_CURRENT }}="{{ command_category.id_command_category }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ command_category.id_command_category }}">
{% include 'components/dog/_preview_DDL_command_category.html' %}
</td>
{% set command = link.command %}
<td class="{{ model.FLAG_COMMAND }}" {{ model.ATTR_VALUE_CURRENT }}="{{ link.id_command }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ link.id_command }}">
<td class="{{ model.FLAG_COMMAND }}" {{ model.ATTR_VALUE_CURRENT }}="{{ command.id_command }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ command.id_command }}">
{% include 'components/dog/_preview_DDL_command.html' %}
</td>
<td class="{{ model.FLAG_HAND_SIGNAL_DESCRIPTION}}" {{ model.ATTR_VALUE_CURRENT }}="{{ link.hand_signal_description }}" {{ model.ATTR_VALUE_PREVIOUS }}="{{ link.hand_signal_description }}">

View File

@@ -0,0 +1,21 @@
<div class="{{ model.FLAG_COMMAND }}" >{% if not is_blank_row %}{{ command.name }}{% endif %}</div>
{#
{ % if not is_blank_row % }
<div
class="{{ model.FLAG_COMMAND }}"
{#
{{ model.ATTR_VALUE_CURRENT }}="{ { command.id_command } }"
{{ model.ATTR_VALUE_PREVIOUS }}="{ { command.id_command } }"
#}
>{ { command.name } }</div>
{ % else % }
<select class="{{ model.FLAG_COMMAND }}"> {# {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0" #}
{ % include 'components/common/inputs/_option_blank.html' % }
{ % for command in model.filter_commands % }
<option value="{ { command.id_command } }">{ { command.name } }</option>
{ % endfor % }
</select>
{ % endif % }
#}

View File

@@ -0,0 +1,21 @@
<div class="{{ model.FLAG_COMMAND_CATEGORY }}" >{% if not is_blank_row %}{{ command_category.name }}{% endif %}</div>
{#
{ % if not is_blank_row % }
<div
class="{{ model.FLAG_COMMAND_CATEGORY }}"
{#
{{ model.ATTR_VALUE_CURRENT }}="{ { command_category.id_command_category } }"
{{ model.ATTR_VALUE_PREVIOUS }}="{ { command_category.id_command_category } }"
#}
>{ { command_category.name } }</div>
{ % else % }
<select class="{{ model.FLAG_COMMAND_CATEGORY }}"> {# {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0" #}
{ % include 'components/common/inputs/_option_blank.html' % }
{ % for command_category in model.filter_command_categorys % }
<option value="{ { command_category.id_command_category } }">{ { command_category.name } }</option>
{ % endfor % }
</select>
{ % endif % }
#}

View File

@@ -0,0 +1,21 @@
<div class="{{ model.FLAG_DOG }}" >{% if not is_blank_row %}{{ dog.name }}{% endif %}</div>
{#
{ % if not is_blank_row % }
<div
class="{{ model.FLAG_DOG }}"
{#
{{ model.ATTR_VALUE_CURRENT }}="{ { dog.id_dog } }"
{{ model.ATTR_VALUE_PREVIOUS }}="{ { dog.id_dog } }"
#}
>{ { dog.name } }</div>
{ % else % }
<select class="{{ model.FLAG_DOG }}"> {# {{ model.ATTR_VALUE_CURRENT }}="0" {{ model.ATTR_VALUE_PREVIOUS }}="0" #}
{ % include 'components/common/inputs/_option_blank.html' % }
{ % for dog in model.filter_dogs % }
<option value="{ { dog.id_dog } }">{ { dog.name } }</option>
{ % endfor % }
</select>
{ % endif % }
#}

View File

@@ -39,6 +39,7 @@
var attrIdAccessLevel = "{{ model.ATTR_ID_ACCESS_LEVEL }}";
var attrIdCurrency = "{{ model.ATTR_ID_CURRENCY }}";
var attrIdCommand = "{{ model.ATTR_ID_COMMAND }}";
var attrIdCommandCategory = "{{ model.ATTR_ID_COMMAND_CATEGORY }}";
var attrIdDog = "{{ model.ATTR_ID_DOG }}";
var attrIdDogCommandLink = "{{ model.ATTR_ID_DOG_COMMAND_LINK }}";
var attrTextCollapsed = "{{ model.ATTR_TEXT_COLLAPSED }}";
@@ -65,6 +66,7 @@
var flagAccessLevel = "{{ model.FLAG_ACCESS_LEVEL }}";
var flagAccessLevelRequired = "{{ model.FLAG_ACCESS_LEVEL_REQUIRED }}";
var flagActive = "{{ model.FLAG_ACTIVE }}";
var flagActiveOnly = "{{ model.FLAG_ACTIVE_ONLY }}";
var flagAdd = "{{ model.FLAG_ADD }}";
var flagAddress = "{{ model.FLAG_ADDRESS }}";
var flagAddressLine1 = "{{ model.FLAG_ADDRESS_LINE_1 }}";
@@ -74,16 +76,18 @@
var flagCallback = "{{ model.FLAG_CALLBACK }}";
var flagCancel = "{{ model.FLAG_CANCEL }}";
var flagCard = "{{ model.FLAG_CARD }}";
var flagCheckbox = "{{ model.FLAG_CHECKBOX }}";
var flagCity = "{{ model.FLAG_CITY }}";
var flagCloseTemporaryElement = "{{ model.FLAG_CLOSE_TEMPORARY_ELEMENT }}";
var flagCode = "{{ model.FLAG_CODE }}";
var flagCollapsed = "{{ model.FLAG_COLLAPSED }}";
var flagCollapsible = "{{ model.FLAG_COLLAPSIBLE }}";
var flagColumn = "{{ model.FLAG_COLUMN }}";
var flagCommand = "{{ model.FLAG_COMMAND }}";
var flagCommandCategory = "{{ model.FLAG_COMMAND_CATEGORY }}";
var flagComment = "{{ model.FLAG_COMMENT }}";
// var flagContactUs = "{{ model.FLAG_CONTACT_US }}";
var flagContainer = "{{ model.FLAG_CONTAINER }}";
var flagContainerCheckbox = "{{ model.FLAG_CONTAINER_CHECKBOX }}";
var flagContainerInput = "{{ model.FLAG_CONTAINER_INPUT }}";
var flagCounty = "{{ model.FLAG_COUNTY }}";
var flagCsrfToken = "{{ model.FLAG_CSRF_TOKEN }}";
@@ -94,6 +98,7 @@
var flagDialog = "{{ model.FLAG_DIALOG }}";
var flagDirty = "{{ model.FLAG_DIRTY }}";
var flagDisplayOrder = "{{ model.FLAG_DISPLAY_ORDER }}";
var flagDog = "{{ model.FLAG_DOG }}";
var flagDragging = "dragging";
var flagDragOver = "drag-over";
var flagEdit = "{{ model.FLAG_EDIT }}";
@@ -107,6 +112,7 @@
var flagFormFilters = "{{ model.FLAG_FORM_FILTERS }}";
var flagImageLogo = "{{ model.FLAG_IMAGE_LOGO }}";
var flagInitialised = "{{ model.FLAG_INITIALISED }}";
var flagIsChecked = "{{ model.FLAG_IS_CHECKED }}";
// var flagItems = "{{ model.FLAG_ITEMS }}";
// var flagKeyPrimary = "{{ model.FLAG_KEY_PRIMARY }}";
var flagLeftHandStub = "{{ model.FLAG_LEFT_HAND_STUB }}";
@@ -143,6 +149,7 @@
var flagRows = "{{ model.FLAG_ROWS }}";
var flagSave = "{{ model.FLAG_SAVE }}";
var flagScrollable = "{{ model.FLAG_SCROLLABLE }}";
var flagSearch = "{{ model.FLAG_SEARCH }}";
var flagSlider = "{{ model.FLAG_SLIDER }}";
var flagStatus = "{{ model.FLAG_STATUS }}";
var flagSubmit = "{{ model.FLAG_SUBMIT }}";

View File

@@ -7,6 +7,13 @@
{{ 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.ATTR_ID_DOG }}">
{{ model.form_filters.id_dog.label }}
{{ model.form_filters.id_dog() }}
@@ -14,6 +21,13 @@
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.ATTR_ID_COMMAND_CATEGORY }}">
{{ model.form_filters.id_command_category.label }}
{{ model.form_filters.id_command_category() }}
{% for error in model.form_filters.id_command_category.errors %}
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.ATTR_ID_COMMAND }}">
{{ model.form_filters.id_command.label }}
{{ model.form_filters.id_command() }}
@@ -21,12 +35,14 @@
<p class="error">{{ error }}</p>
{% endfor %}
</div>
<div class="{{ model.FLAG_CONTAINER_INPUT }} {{ model.FLAG_COLUMN }} {{ model.FLAG_FILTER }} {{ model.FLAG_ACTIVE }}">
<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>
@@ -38,6 +54,7 @@
<thead>
<tr class="{{ model.FLAG_DOG_COMMAND_LINK }}">
<th class="{{ model.FLAG_DOG }}">Dog</th>
<th class="{{ model.FLAG_COMMAND_CATEGORY }}">Command Category</th>
<th class="{{ model.FLAG_COMMAND }}">Command</th>
<th class="{{ model.FLAG_HAND_SIGNAL_DESCRIPTION }}">Hand Signal</th>
<th class="{{ model.FLAG_NOTES }}">Notes</th>
@@ -64,6 +81,7 @@
<script src="{{ url_for('routes_dog.scripts_section_dog') }}"></script>
<script>
var filterCommandCategories = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_command_categories) | tojson | safe }};
var filterCommands = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_commands) | tojson | safe }};
var filterDogCommandLinks = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_dog_command_links) | tojson | safe }};
var filterDogs = {{ model.convert_list_objects_to_dict_json_by_attribute_key_default(model.filter_dogs) | tojson | safe }};