Kea2-python 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Kea2-python might be problematic. Click here for more details.
- kea2/bug_report_generator.py +103 -75
- kea2/keaUtils.py +11 -6
- kea2/report_merger.py +29 -16
- kea2/templates/bug_report_template.html +746 -408
- kea2/templates/merged_bug_report_template.html +1082 -380
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/METADATA +74 -8
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/RECORD +11 -11
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/WHEEL +0 -0
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/entry_points.txt +0 -0
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/licenses/LICENSE +0 -0
- {kea2_python-0.3.1.dist-info → kea2_python-0.3.3.dist-info}/top_level.txt +0 -0
|
@@ -211,35 +211,39 @@
|
|
|
211
211
|
text-align: left !important;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
/* Enhanced Error Details styling */
|
|
215
|
-
.table-custom
|
|
214
|
+
/* Enhanced Error Details styling for Property Statistics */
|
|
215
|
+
.table-custom tr.collapse {
|
|
216
216
|
position: relative;
|
|
217
217
|
z-index: 10;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
.table-custom td
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
.table-custom tr.collapse td {
|
|
221
|
+
border-top: none;
|
|
222
|
+
padding-top: 0;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
.table-custom
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
225
|
+
.table-custom tr.collapse .bg-light {
|
|
226
|
+
max-width: none;
|
|
227
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
228
|
+
border: 1px solid #e9ecef;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
.table-custom
|
|
232
|
-
max-height:
|
|
231
|
+
.table-custom tr.collapse pre {
|
|
232
|
+
max-height: 300px;
|
|
233
233
|
overflow-y: auto;
|
|
234
|
-
font-size: 0.
|
|
234
|
+
font-size: 0.85rem;
|
|
235
235
|
line-height: 1.4;
|
|
236
|
+
background-color: #f8f9fa;
|
|
237
|
+
border: 1px solid #e9ecef;
|
|
238
|
+
border-radius: 4px;
|
|
239
|
+
padding: 0.75rem;
|
|
236
240
|
}
|
|
237
241
|
|
|
238
|
-
.table-custom
|
|
242
|
+
.table-custom tr.collapse details {
|
|
239
243
|
margin-top: 0.5rem;
|
|
240
244
|
}
|
|
241
245
|
|
|
242
|
-
.table-custom
|
|
246
|
+
.table-custom tr.collapse summary {
|
|
243
247
|
cursor: pointer;
|
|
244
248
|
margin-bottom: 0.5rem;
|
|
245
249
|
}
|
|
@@ -553,6 +557,25 @@
|
|
|
553
557
|
transform: scale(1.2);
|
|
554
558
|
text-shadow: 0 0 5px rgba(0,0,0,0.6);
|
|
555
559
|
}
|
|
560
|
+
|
|
561
|
+
/* Specific column widths for property violations table */
|
|
562
|
+
.table-violations th:nth-child(1), .table-violations td:nth-child(1) { /* Index */
|
|
563
|
+
width: 10%;
|
|
564
|
+
min-width: 60px;
|
|
565
|
+
text-align: center;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.table-violations th:nth-child(2), .table-violations td:nth-child(2) { /* Property Name */
|
|
569
|
+
width: 40%;
|
|
570
|
+
min-width: 200px;
|
|
571
|
+
text-align: left;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.table-violations th:nth-child(3), .table-violations td:nth-child(3) { /* Interaction Scenario Pages */
|
|
575
|
+
width: 50%;
|
|
576
|
+
min-width: 150px;
|
|
577
|
+
text-align: center;
|
|
578
|
+
}
|
|
556
579
|
|
|
557
580
|
@media (max-width: 768px) {
|
|
558
581
|
.container {
|
|
@@ -820,6 +843,117 @@
|
|
|
820
843
|
border-color: #d1d5db;
|
|
821
844
|
}
|
|
822
845
|
|
|
846
|
+
/* Property search container with outline */
|
|
847
|
+
.property-search-container {
|
|
848
|
+
position: relative;
|
|
849
|
+
display: flex;
|
|
850
|
+
align-items: center;
|
|
851
|
+
border: 1px solid #d1d5db;
|
|
852
|
+
border-radius: 6px;
|
|
853
|
+
background-color: #f8f9fa;
|
|
854
|
+
transition: all 0.2s ease;
|
|
855
|
+
overflow: hidden;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.property-search-container:hover {
|
|
859
|
+
border-color: #9ca3af;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
.property-search-container:focus-within {
|
|
863
|
+
border-color: #3b82f6;
|
|
864
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
|
|
865
|
+
background-color: #ffffff;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/* Simple search input styling for Property Statistics */
|
|
869
|
+
.property-stats-search-simple {
|
|
870
|
+
border: none !important;
|
|
871
|
+
box-shadow: none !important;
|
|
872
|
+
background-color: transparent !important;
|
|
873
|
+
border-radius: 0 !important;
|
|
874
|
+
padding: 8px 12px !important;
|
|
875
|
+
font-size: 14px;
|
|
876
|
+
flex: 1;
|
|
877
|
+
outline: none;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
.property-stats-search-simple:focus {
|
|
881
|
+
background-color: transparent !important;
|
|
882
|
+
box-shadow: none !important;
|
|
883
|
+
border: none !important;
|
|
884
|
+
outline: none;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
.property-stats-search-simple::placeholder {
|
|
888
|
+
color: #9ca3af;
|
|
889
|
+
font-style: italic;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/* Search icon button */
|
|
893
|
+
.property-search-icon-btn {
|
|
894
|
+
background: none;
|
|
895
|
+
border: none;
|
|
896
|
+
padding: 8px 12px;
|
|
897
|
+
color: #6b7280;
|
|
898
|
+
cursor: pointer;
|
|
899
|
+
display: flex;
|
|
900
|
+
align-items: center;
|
|
901
|
+
justify-content: center;
|
|
902
|
+
transition: color 0.2s ease;
|
|
903
|
+
border-left: 1px solid #e5e7eb;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.property-search-icon-btn:hover {
|
|
907
|
+
color: #3b82f6;
|
|
908
|
+
background-color: rgba(59, 130, 246, 0.05);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.property-search-icon-btn:active {
|
|
912
|
+
color: #1d4ed8;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/* Activities Coverage table styling */
|
|
916
|
+
.table-activities thead {
|
|
917
|
+
background-color: #007bff !important;
|
|
918
|
+
color: white;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.table-activities .sort-icon {
|
|
922
|
+
color: #ffffff !important;
|
|
923
|
+
text-shadow: 0 0 3px rgba(0,0,0,0.4);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
.table-activities .sort-icon:hover {
|
|
927
|
+
opacity: 1;
|
|
928
|
+
transform: scale(1.2);
|
|
929
|
+
text-shadow: 0 0 5px rgba(0,0,0,0.6);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.table-activities .activities-sort-icon {
|
|
933
|
+
color: #ffffff !important;
|
|
934
|
+
text-shadow: 0 0 3px rgba(0,0,0,0.4);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
.table-activities .activities-sort-icon:hover {
|
|
938
|
+
opacity: 1;
|
|
939
|
+
transform: scale(1.2);
|
|
940
|
+
text-shadow: 0 0 5px rgba(0,0,0,0.6);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/* Column widths for activities table */
|
|
944
|
+
.table-activities th:nth-child(1), .table-activities td:nth-child(1) { /* Activity Name */
|
|
945
|
+
width: 70%;
|
|
946
|
+
min-width: 300px;
|
|
947
|
+
text-align: left;
|
|
948
|
+
padding-left: 180px;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
.table-activities th:nth-child(2), .table-activities td:nth-child(2) { /* Visit Count */
|
|
952
|
+
width: 30%;
|
|
953
|
+
min-width: 150px;
|
|
954
|
+
text-align: center;
|
|
955
|
+
}
|
|
956
|
+
|
|
823
957
|
/* Modern Activity Item Styling */
|
|
824
958
|
.activity-item {
|
|
825
959
|
background: #ffffff;
|
|
@@ -1109,254 +1243,97 @@
|
|
|
1109
1243
|
</div>
|
|
1110
1244
|
</div>
|
|
1111
1245
|
|
|
1112
|
-
<!--
|
|
1246
|
+
<!-- Activities Coverage -->
|
|
1113
1247
|
<div class="section-block">
|
|
1114
1248
|
<h2 class="section-title">Activities Coverage</h2>
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
<
|
|
1249
|
+
|
|
1250
|
+
<!-- Search Controls for Activities -->
|
|
1251
|
+
<div class="mb-4">
|
|
1252
|
+
<div class="d-flex align-items-center">
|
|
1253
|
+
<div style="width: 33%;">
|
|
1254
|
+
<div class="property-search-container">
|
|
1255
|
+
<input type="text" class="form-control property-search-input property-stats-search-simple"
|
|
1256
|
+
id="activities-search"
|
|
1257
|
+
placeholder="Search activities by name..."
|
|
1258
|
+
data-target="activities-container"
|
|
1259
|
+
data-item-class="activity-row"
|
|
1260
|
+
data-pagination="activities-pagination"
|
|
1261
|
+
data-page-size="activities-page-size">
|
|
1262
|
+
<button class="property-search-icon-btn" type="button" id="activities-search-btn">
|
|
1263
|
+
<i class="bi bi-search"></i>
|
|
1264
|
+
</button>
|
|
1265
|
+
</div>
|
|
1121
1266
|
</div>
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
<div class="alert alert-info mb-3" style="border-left: 4px solid #17a2b8; background-color: #f8f9fa;">
|
|
1125
|
-
<small class="text-muted">
|
|
1126
|
-
<i class="bi bi-info-circle me-1"></i>
|
|
1127
|
-
<strong>Visit Count Explanation:</strong>
|
|
1128
|
-
The number after the <i class="bi bi-eye"></i> icon indicates how many times each Activity was visited during testing.
|
|
1129
|
-
</small>
|
|
1267
|
+
<div class="ms-3">
|
|
1268
|
+
<small class="text-muted search-results-count" id="activities-search-results"></small>
|
|
1130
1269
|
</div>
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
<ul class="nav nav-tabs mb-3" id="activitiesTabs" role="tablist">
|
|
1134
|
-
<li class="nav-item" role="presentation">
|
|
1135
|
-
<button class="nav-link active" id="tested-tab" data-bs-toggle="tab"
|
|
1136
|
-
data-bs-target="#tested-activities" type="button" role="tab"
|
|
1137
|
-
aria-controls="tested-activities" aria-selected="true">
|
|
1138
|
-
<i class="bi bi-check-circle"></i> Tested Activities ({{ tested_activities|length }})
|
|
1139
|
-
</button>
|
|
1140
|
-
</li>
|
|
1141
|
-
<li class="nav-item" role="presentation">
|
|
1142
|
-
<button class="nav-link" id="all-tab" data-bs-toggle="tab"
|
|
1143
|
-
data-bs-target="#all-activities" type="button" role="tab"
|
|
1144
|
-
aria-controls="all-activities" aria-selected="false">
|
|
1145
|
-
<i class="bi bi-app"></i> All Activities ({{ total_activities|length }})
|
|
1146
|
-
</button>
|
|
1147
|
-
</li>
|
|
1148
|
-
</ul>
|
|
1149
|
-
|
|
1150
|
-
<!-- Tab Content -->
|
|
1151
|
-
<div class="tab-content" id="activitiesTabContent">
|
|
1152
|
-
<!-- Tested Activities Tab -->
|
|
1153
|
-
<div class="tab-pane fade show active" id="tested-activities" role="tabpanel"
|
|
1154
|
-
aria-labelledby="tested-tab">
|
|
1155
|
-
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
1156
|
-
<h5 class="mb-0 text-success">
|
|
1157
|
-
<i class="bi bi-check-circle-fill"></i> Tested Activities
|
|
1158
|
-
</h5>
|
|
1159
|
-
<span class="badge bg-success" style="font-size: 1.0em; font-weight: 500;">{{ tested_activities|length }} / {{ total_activities_count }}</span>
|
|
1160
|
-
</div>
|
|
1161
|
-
|
|
1162
|
-
<!-- Combined Search and Sort Controls for Tested Activities -->
|
|
1163
|
-
<div class="search-sort-controls-modern mb-4">
|
|
1164
|
-
<div class="d-flex align-items-center gap-4">
|
|
1165
|
-
<!-- Search Section -->
|
|
1166
|
-
<div class="search-section d-flex align-items-center" style="width: 600px; flex-shrink: 0;">
|
|
1167
|
-
<div class="search-icon-wrapper me-3">
|
|
1168
|
-
<i class="bi bi-search"></i>
|
|
1169
|
-
</div>
|
|
1170
|
-
<div class="flex-grow-1">
|
|
1171
|
-
<div class="input-group">
|
|
1172
|
-
<input type="text" class="form-control activity-search-input"
|
|
1173
|
-
id="tested-activity-search"
|
|
1174
|
-
placeholder="Search activities..."
|
|
1175
|
-
data-target="tested-activities-container"
|
|
1176
|
-
data-item-class="tested-activity"
|
|
1177
|
-
data-pagination="tested-pagination"
|
|
1178
|
-
data-page-size="tested-page-size">
|
|
1179
|
-
<button class="btn search-btn" type="button"
|
|
1180
|
-
data-target="tested-activity-search">
|
|
1181
|
-
<i class="bi bi-search"></i>
|
|
1182
|
-
</button>
|
|
1183
|
-
<button class="btn btn-outline-secondary search-clear-btn" type="button"
|
|
1184
|
-
data-target="tested-activity-search">
|
|
1185
|
-
<i class="bi bi-x-lg"></i>
|
|
1186
|
-
</button>
|
|
1187
|
-
</div>
|
|
1188
|
-
<small class="text-muted search-results-count" id="tested-search-results"></small>
|
|
1189
|
-
</div>
|
|
1190
|
-
</div>
|
|
1270
|
+
</div>
|
|
1271
|
+
</div>
|
|
1191
1272
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
<div class="activities-container">
|
|
1210
|
-
<div class="activity-list">
|
|
1211
|
-
{% if tested_activities|length > 0 %}
|
|
1212
|
-
<div id="tested-activities-container">
|
|
1213
|
-
{% for activity in tested_activities %}
|
|
1214
|
-
<div class="activity-item tested-activity" data-page="1">
|
|
1215
|
-
<div class="activity-content">
|
|
1216
|
-
<i class="bi bi-check-circle-fill text-success me-2"></i>
|
|
1217
|
-
<span class="activity-name">{{ activity }}</span>
|
|
1218
|
-
</div>
|
|
1219
|
-
{% if activity in activity_count_history %}
|
|
1220
|
-
<span class="badge bg-info text-white traversal-badge">
|
|
1221
|
-
<i class="bi bi-eye"></i> {{ activity_count_history[activity] }} times
|
|
1222
|
-
</span>
|
|
1223
|
-
{% endif %}
|
|
1224
|
-
</div>
|
|
1225
|
-
{% endfor %}
|
|
1226
|
-
</div>
|
|
1273
|
+
<div class="table-responsive">
|
|
1274
|
+
<table class="table table-custom table-activities">
|
|
1275
|
+
<thead>
|
|
1276
|
+
<tr>
|
|
1277
|
+
<th>Activity Name <span class="badge bg-primary ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ tested_activities_count }}/{{ total_activities_count }}</span></th>
|
|
1278
|
+
<th>Visit Count <i class="bi bi-arrow-down-up text-muted sort-icon activities-sort-icon" id="visit-count-sort" data-column="visit-count" data-order="none" style="cursor: pointer;"></i></th>
|
|
1279
|
+
</tr>
|
|
1280
|
+
</thead>
|
|
1281
|
+
<tbody id="activities-container">
|
|
1282
|
+
{% if total_activities|length > 0 %}
|
|
1283
|
+
{% for activity in total_activities %}
|
|
1284
|
+
<tr class="activity-row" data-page="1"
|
|
1285
|
+
data-activity-name="{{ activity }}"
|
|
1286
|
+
data-visit-count="{{ activity_count_history[activity] if activity in activity_count_history else 0 }}">
|
|
1287
|
+
<td>
|
|
1288
|
+
{% if activity in tested_activities %}
|
|
1289
|
+
<i class="bi bi-check-circle-fill text-success me-2"></i>
|
|
1227
1290
|
{% else %}
|
|
1228
|
-
<
|
|
1229
|
-
No tested activities detected
|
|
1230
|
-
</div>
|
|
1291
|
+
<i class="bi bi-dash-circle text-secondary me-2"></i>
|
|
1231
1292
|
{% endif %}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
<
|
|
1235
|
-
|
|
1236
|
-
<
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
<option value="10" selected>10</option>
|
|
1240
|
-
<option value="20">20</option>
|
|
1241
|
-
<option value="50">50</option>
|
|
1242
|
-
<option value="100">100</option>
|
|
1243
|
-
</select>
|
|
1244
|
-
</div>
|
|
1245
|
-
<nav aria-label="Tested Activities Pagination">
|
|
1246
|
-
<ul class="pagination pagination-sm mb-0" id="tested-pagination">
|
|
1247
|
-
<!-- Pagination will be generated by JavaScript -->
|
|
1248
|
-
</ul>
|
|
1249
|
-
</nav>
|
|
1250
|
-
</div>
|
|
1251
|
-
</div>
|
|
1252
|
-
</div>
|
|
1253
|
-
|
|
1254
|
-
<!-- All Activities Tab -->
|
|
1255
|
-
<div class="tab-pane fade" id="all-activities" role="tabpanel"
|
|
1256
|
-
aria-labelledby="all-tab">
|
|
1257
|
-
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
1258
|
-
<h5 class="mb-0 text-primary">
|
|
1259
|
-
<i class="bi bi-app"></i> All Activities Overview
|
|
1260
|
-
</h5>
|
|
1261
|
-
<span class="badge bg-primary" style="font-size: 1.0em; font-weight: 500;">Total: {{ total_activities|length }}</span>
|
|
1262
|
-
</div>
|
|
1263
|
-
|
|
1264
|
-
<!-- Combined Search and Sort Controls for All Activities -->
|
|
1265
|
-
<div class="search-sort-controls-modern mb-4">
|
|
1266
|
-
<div class="d-flex align-items-center gap-4">
|
|
1267
|
-
<!-- Search Section -->
|
|
1268
|
-
<div class="search-section d-flex align-items-center" style="width: 600px; flex-shrink: 0;">
|
|
1269
|
-
<div class="search-icon-wrapper me-3">
|
|
1270
|
-
<i class="bi bi-search"></i>
|
|
1271
|
-
</div>
|
|
1272
|
-
<div class="flex-grow-1">
|
|
1273
|
-
<div class="input-group">
|
|
1274
|
-
<input type="text" class="form-control activity-search-input"
|
|
1275
|
-
id="all-activity-search"
|
|
1276
|
-
placeholder="Search activities..."
|
|
1277
|
-
data-target="all-activities-container"
|
|
1278
|
-
data-item-class="all-activity"
|
|
1279
|
-
data-pagination="all-pagination"
|
|
1280
|
-
data-page-size="all-page-size">
|
|
1281
|
-
<button class="btn search-btn" type="button"
|
|
1282
|
-
data-target="all-activity-search">
|
|
1283
|
-
<i class="bi bi-search"></i>
|
|
1284
|
-
</button>
|
|
1285
|
-
<button class="btn btn-outline-secondary search-clear-btn" type="button"
|
|
1286
|
-
data-target="all-activity-search">
|
|
1287
|
-
<i class="bi bi-x-lg"></i>
|
|
1288
|
-
</button>
|
|
1289
|
-
</div>
|
|
1290
|
-
<small class="text-muted search-results-count" id="all-search-results"></small>
|
|
1291
|
-
</div>
|
|
1292
|
-
</div>
|
|
1293
|
-
|
|
1294
|
-
<!-- Sort Section -->
|
|
1295
|
-
<div class="sort-section d-flex align-items-center gap-3" style="margin-left: auto;">
|
|
1296
|
-
<div class="sort-label d-flex align-items-center gap-2">
|
|
1297
|
-
<i class="bi bi-funnel-fill text-muted"></i>
|
|
1298
|
-
<span class="text-muted fw-medium">Sort:</span>
|
|
1299
|
-
</div>
|
|
1300
|
-
<button type="button" class="btn-sort-modern activity-sort-btn" data-sort="traversal" data-order="desc">
|
|
1301
|
-
<div class="btn-content">
|
|
1302
|
-
<i class="bi bi-eye btn-icon"></i>
|
|
1303
|
-
<span class="btn-text">Visit Count</span>
|
|
1304
|
-
<i class="bi bi-arrow-down sort-icon btn-arrow"></i>
|
|
1305
|
-
</div>
|
|
1306
|
-
</button>
|
|
1307
|
-
</div>
|
|
1308
|
-
</div>
|
|
1309
|
-
</div>
|
|
1310
|
-
|
|
1311
|
-
<div class="activities-container">
|
|
1312
|
-
<div class="activity-list">
|
|
1313
|
-
{% if total_activities|length > 0 %}
|
|
1314
|
-
<div id="all-activities-container">
|
|
1315
|
-
{% for activity in total_activities %}
|
|
1316
|
-
<div class="activity-item all-activity" data-page="1">
|
|
1317
|
-
<div class="activity-content">
|
|
1318
|
-
{% if activity in tested_activities %}
|
|
1319
|
-
<i class="bi bi-check-circle-fill text-success me-2"></i>
|
|
1320
|
-
{% else %}
|
|
1321
|
-
<i class="bi bi-dash-circle text-secondary me-2"></i>
|
|
1322
|
-
{% endif %}
|
|
1323
|
-
<span class="activity-name">{{ activity }}</span>
|
|
1324
|
-
</div>
|
|
1325
|
-
{% if activity in activity_count_history %}
|
|
1326
|
-
<span class="badge bg-info text-white traversal-badge">
|
|
1327
|
-
<i class="bi bi-eye"></i> {{ activity_count_history[activity] }} times
|
|
1328
|
-
</span>
|
|
1329
|
-
{% endif %}
|
|
1330
|
-
</div>
|
|
1331
|
-
{% endfor %}
|
|
1332
|
-
</div>
|
|
1293
|
+
<span class="activity-name">{{ activity }}</span>
|
|
1294
|
+
</td>
|
|
1295
|
+
<td>
|
|
1296
|
+
{% if activity in activity_count_history %}
|
|
1297
|
+
<span class="badge bg-info text-white">
|
|
1298
|
+
<i class="bi bi-eye"></i> {{ activity_count_history[activity] }} times
|
|
1299
|
+
</span>
|
|
1333
1300
|
{% else %}
|
|
1334
|
-
<
|
|
1335
|
-
|
|
1336
|
-
</
|
|
1301
|
+
<span class="badge bg-secondary text-white">
|
|
1302
|
+
<i class="bi bi-dash"></i> 0 times
|
|
1303
|
+
</span>
|
|
1337
1304
|
{% endif %}
|
|
1338
|
-
</
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
<option value="20">20</option>
|
|
1347
|
-
<option value="50">50</option>
|
|
1348
|
-
<option value="100">100</option>
|
|
1349
|
-
</select>
|
|
1305
|
+
</td>
|
|
1306
|
+
</tr>
|
|
1307
|
+
{% endfor %}
|
|
1308
|
+
{% else %}
|
|
1309
|
+
<tr>
|
|
1310
|
+
<td colspan="2" class="text-center">
|
|
1311
|
+
<div class="alert alert-warning mb-0">
|
|
1312
|
+
No activities information available
|
|
1350
1313
|
</div>
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1314
|
+
</td>
|
|
1315
|
+
</tr>
|
|
1316
|
+
{% endif %}
|
|
1317
|
+
</tbody>
|
|
1318
|
+
</table>
|
|
1319
|
+
|
|
1320
|
+
<!-- Pagination for Activities -->
|
|
1321
|
+
<div class="d-flex justify-content-between align-items-center mt-3">
|
|
1322
|
+
<div class="d-flex align-items-center">
|
|
1323
|
+
<label for="activities-page-size" class="form-label me-2 mb-0">Show:</label>
|
|
1324
|
+
<select class="form-select form-select-sm" id="activities-page-size" style="width: auto;">
|
|
1325
|
+
<option value="5">5</option>
|
|
1326
|
+
<option value="10" selected>10</option>
|
|
1327
|
+
<option value="20">20</option>
|
|
1328
|
+
<option value="50">50</option>
|
|
1329
|
+
<option value="100">100</option>
|
|
1330
|
+
</select>
|
|
1359
1331
|
</div>
|
|
1332
|
+
<nav aria-label="Activities Pagination">
|
|
1333
|
+
<ul class="pagination pagination-sm mb-0" id="activities-pagination">
|
|
1334
|
+
<!-- Pagination will be generated by JavaScript -->
|
|
1335
|
+
</ul>
|
|
1336
|
+
</nav>
|
|
1360
1337
|
</div>
|
|
1361
1338
|
</div>
|
|
1362
1339
|
</div>
|
|
@@ -1518,6 +1495,7 @@
|
|
|
1518
1495
|
|
|
1519
1496
|
<!-- Property Violations List -->
|
|
1520
1497
|
{% if take_screenshots %}
|
|
1498
|
+
{% if property_violations %}
|
|
1521
1499
|
<div class="section-block">
|
|
1522
1500
|
<h2 class="section-title">Property Violations</h2>
|
|
1523
1501
|
<div class="table-responsive">
|
|
@@ -1526,9 +1504,7 @@
|
|
|
1526
1504
|
<tr>
|
|
1527
1505
|
<th>Index</th>
|
|
1528
1506
|
<th>Property Name</th>
|
|
1529
|
-
<th>Precondition Page</th>
|
|
1530
1507
|
<th>Interaction Scenario Pages</th>
|
|
1531
|
-
<th>Postcondition Page</th>
|
|
1532
1508
|
</tr>
|
|
1533
1509
|
</thead>
|
|
1534
1510
|
<tbody id="property-violations-container">
|
|
@@ -1536,14 +1512,12 @@
|
|
|
1536
1512
|
<tr class="property-violation-row" data-page="1">
|
|
1537
1513
|
<td>{{ violation.index }}</td>
|
|
1538
1514
|
<td><span class="badge bg-light text-dark badge-custom">{{ violation.property_name }}</span></td>
|
|
1539
|
-
<td><a href="#{{ violation.precondition_page }}" class="link-button">{{ violation.precondition_page }}</a></td>
|
|
1540
1515
|
<td><a href="#{{ violation.interaction_pages[0] }}" class="link-button">{{ violation.interaction_pages[0] }} ~ {{ violation.interaction_pages[1] }}</a></td>
|
|
1541
|
-
<td><a href="#{{ violation.postcondition_page }}" class="link-button">{{ violation.postcondition_page }}</a></td>
|
|
1542
1516
|
</tr>
|
|
1543
1517
|
{% endfor %}
|
|
1544
1518
|
</tbody>
|
|
1545
1519
|
</table>
|
|
1546
|
-
|
|
1520
|
+
|
|
1547
1521
|
<!-- Pagination for Property Violations -->
|
|
1548
1522
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
|
1549
1523
|
<div class="d-flex align-items-center">
|
|
@@ -1564,6 +1538,14 @@
|
|
|
1564
1538
|
</div>
|
|
1565
1539
|
</div>
|
|
1566
1540
|
</div>
|
|
1541
|
+
{% else %}
|
|
1542
|
+
<div class="section-block">
|
|
1543
|
+
<h2 class="section-title">Property Violations</h2>
|
|
1544
|
+
<div class="alert alert-info text-center">
|
|
1545
|
+
<i class="bi bi-info-circle"></i> No property violations detected in this test session.
|
|
1546
|
+
</div>
|
|
1547
|
+
</div>
|
|
1548
|
+
{% endif %}
|
|
1567
1549
|
{% endif %}
|
|
1568
1550
|
|
|
1569
1551
|
<!-- Property Checking Statistics -->
|
|
@@ -1571,29 +1553,23 @@
|
|
|
1571
1553
|
<h2 class="section-title">Property Checking Statistics</h2>
|
|
1572
1554
|
|
|
1573
1555
|
<!-- Search Controls for Property Statistics -->
|
|
1574
|
-
<div class="
|
|
1556
|
+
<div class="mb-4">
|
|
1575
1557
|
<div class="d-flex align-items-center">
|
|
1576
|
-
<div
|
|
1577
|
-
<
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
<input type="text" class="form-control property-search-input"
|
|
1582
|
-
id="property-stats-search"
|
|
1583
|
-
placeholder="Search properties by name..."
|
|
1558
|
+
<div style="width: 33%;">
|
|
1559
|
+
<div class="property-search-container">
|
|
1560
|
+
<input type="text" class="form-control property-search-input property-stats-search-simple"
|
|
1561
|
+
id="property-stats-search"
|
|
1562
|
+
placeholder="Search properties by name..."
|
|
1584
1563
|
data-target="property-stats-container"
|
|
1585
1564
|
data-item-class="property-stat-row"
|
|
1586
1565
|
data-pagination="stats-pagination"
|
|
1587
1566
|
data-page-size="stats-page-size">
|
|
1588
|
-
<button class="
|
|
1589
|
-
data-target="property-stats-search">
|
|
1567
|
+
<button class="property-search-icon-btn" type="button" id="property-search-btn">
|
|
1590
1568
|
<i class="bi bi-search"></i>
|
|
1591
1569
|
</button>
|
|
1592
|
-
<button class="btn btn-outline-secondary search-clear-btn" type="button"
|
|
1593
|
-
data-target="property-stats-search">
|
|
1594
|
-
<i class="bi bi-x-lg"></i>
|
|
1595
|
-
</button>
|
|
1596
1570
|
</div>
|
|
1571
|
+
</div>
|
|
1572
|
+
<div class="ms-3">
|
|
1597
1573
|
<small class="text-muted search-results-count" id="property-search-results"></small>
|
|
1598
1574
|
</div>
|
|
1599
1575
|
</div>
|
|
@@ -1604,11 +1580,11 @@
|
|
|
1604
1580
|
<thead>
|
|
1605
1581
|
<tr>
|
|
1606
1582
|
<th>Index</th>
|
|
1607
|
-
<th>Property Name</th>
|
|
1608
|
-
<th>Precondition Satisfied</th>
|
|
1609
|
-
<th>Executed</th>
|
|
1610
|
-
<th>Fails <i class="bi bi-arrow-down-up text-muted sort-icon" id="fails-sort" data-column="fails" data-order="none" style="cursor: pointer;"></i></th>
|
|
1611
|
-
<th>Errors <i class="bi bi-arrow-down-up text-muted sort-icon" id="errors-sort" data-column="errors" data-order="none" style="cursor: pointer;"></i></th>
|
|
1583
|
+
<th>Property Name <span class="badge bg-primary ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ property_stats_summary.total_properties }}</span></th>
|
|
1584
|
+
<th>Precondition Satisfied <span class="badge bg-success ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ property_stats_summary.total_precond_satisfied }}</span></th>
|
|
1585
|
+
<th>Executed <span class="badge bg-info ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ property_stats_summary.total_executed }}</span></th>
|
|
1586
|
+
<th>Fails <span class="badge bg-danger ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ property_stats_summary.total_fails }}</span> <i class="bi bi-arrow-down-up text-muted sort-icon" id="fails-sort" data-column="fails" data-order="none" style="cursor: pointer;"></i></th>
|
|
1587
|
+
<th>Errors <span class="badge bg-warning ms-2" style="font-size: 0.9rem; font-weight: 600;">{{ property_stats_summary.total_errors }}</span> <i class="bi bi-arrow-down-up text-muted sort-icon" id="errors-sort" data-column="errors" data-order="none" style="cursor: pointer;"></i></th>
|
|
1612
1588
|
<th>Error Details</th>
|
|
1613
1589
|
</tr>
|
|
1614
1590
|
</thead>
|
|
@@ -1633,127 +1609,140 @@
|
|
|
1633
1609
|
{% set property_index = loop.index %}
|
|
1634
1610
|
{% if error_list|length == 1 %}
|
|
1635
1611
|
<!-- Single error - simple display -->
|
|
1636
|
-
<button class="btn btn-sm btn-outline-danger" type="button" data-bs-toggle="collapse"
|
|
1637
|
-
data-bs-target="#single-error-detail-{{ property_index }}" aria-expanded="false"
|
|
1612
|
+
<button class="btn btn-sm btn-outline-danger" type="button" data-bs-toggle="collapse"
|
|
1613
|
+
data-bs-target="#single-error-detail-{{ property_index }}" aria-expanded="false"
|
|
1638
1614
|
aria-controls="single-error-detail-{{ property_index }}">
|
|
1639
1615
|
<i class="bi bi-exclamation-triangle"></i> View Error
|
|
1640
1616
|
</button>
|
|
1641
|
-
<div class="collapse mt-2" id="single-error-detail-{{ property_index }}">
|
|
1642
|
-
<div class="card card-body bg-light">
|
|
1643
|
-
<div class="mb-2">
|
|
1644
|
-
<span class="badge bg-{{ 'danger' if error_list[0].state == 'fail' else 'warning' }}">
|
|
1645
|
-
{{ error_list[0].state|upper }}
|
|
1646
|
-
</span>
|
|
1647
|
-
{% if error_list[0].occurrence_count > 1 %}
|
|
1648
|
-
<span class="badge bg-info ms-2">
|
|
1649
|
-
Occurred {{ error_list[0].occurrence_count }} times
|
|
1650
|
-
</span>
|
|
1651
|
-
{% endif %}
|
|
1652
|
-
{% if error_list[0].startStepsCountList is defined and error_list[0].startStepsCountList|length > 0 %}
|
|
1653
|
-
<span class="badge bg-secondary ms-2">
|
|
1654
|
-
<i class="bi bi-step-forward"></i> Monkey Steps: {{ error_list[0].startStepsCountList|join(', ') }}
|
|
1655
|
-
</span>
|
|
1656
|
-
{% endif %}
|
|
1657
|
-
</div>
|
|
1658
|
-
{% if error_list[0].short_description %}
|
|
1659
|
-
<div class="mb-2">
|
|
1660
|
-
<strong>Error:</strong> <code>{{ error_list[0].short_description }}</code>
|
|
1661
|
-
</div>
|
|
1662
|
-
{% endif %}
|
|
1663
|
-
<details>
|
|
1664
|
-
<summary class="btn btn-sm btn-outline-secondary mb-2">Show Full Traceback</summary>
|
|
1665
|
-
<pre class="text-danger mb-0" style="font-size: 0.85rem; white-space: pre-wrap;">{{ error_list[0].traceback }}</pre>
|
|
1666
|
-
</details>
|
|
1667
|
-
</div>
|
|
1668
|
-
</div>
|
|
1669
1617
|
{% else %}
|
|
1670
1618
|
<!-- Multiple errors - tabbed display -->
|
|
1671
|
-
<button class="btn btn-sm btn-outline-danger" type="button" data-bs-toggle="collapse"
|
|
1672
|
-
data-bs-target="#multi-error-detail-{{ property_index }}" aria-expanded="false"
|
|
1619
|
+
<button class="btn btn-sm btn-outline-danger" type="button" data-bs-toggle="collapse"
|
|
1620
|
+
data-bs-target="#multi-error-detail-{{ property_index }}" aria-expanded="false"
|
|
1673
1621
|
aria-controls="multi-error-detail-{{ property_index }}">
|
|
1674
1622
|
<i class="bi bi-exclamation-triangle"></i> View {{ error_list|length }} Errors
|
|
1675
1623
|
</button>
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1624
|
+
{% endif %}
|
|
1625
|
+
{% else %}
|
|
1626
|
+
<span class="text-muted">-</span>
|
|
1627
|
+
{% endif %}
|
|
1628
|
+
</td>
|
|
1629
|
+
</tr>
|
|
1630
|
+
{% if (test_result.fail|default(0) > 0 or test_result.error|default(0) > 0) and property_name in property_error_details %}
|
|
1631
|
+
{% set error_list = property_error_details[property_name] %}
|
|
1632
|
+
{% set property_index = loop.index %}
|
|
1633
|
+
{% if error_list|length == 1 %}
|
|
1634
|
+
<!-- Single error detail row -->
|
|
1635
|
+
<tr class="collapse" id="single-error-detail-{{ property_index }}">
|
|
1636
|
+
<td colspan="7">
|
|
1637
|
+
<div class="bg-light p-3 rounded">
|
|
1638
|
+
<div class="mb-2">
|
|
1639
|
+
<span class="badge bg-{{ 'danger' if error_list[0].state == 'fail' else 'warning' }}">
|
|
1640
|
+
{{ error_list[0].state|upper }}
|
|
1641
|
+
</span>
|
|
1642
|
+
{% if error_list[0].occurrence_count > 1 %}
|
|
1643
|
+
<span class="badge bg-info ms-2">
|
|
1644
|
+
Occurred {{ error_list[0].occurrence_count }} times
|
|
1645
|
+
</span>
|
|
1646
|
+
{% endif %}
|
|
1647
|
+
{% if error_list[0].startStepsCountList is defined and error_list[0].startStepsCountList|length > 0 %}
|
|
1648
|
+
<span class="badge bg-secondary ms-2">
|
|
1649
|
+
<i class="bi bi-step-forward"></i> Monkey Steps: {{ error_list[0].startStepsCountList|join(', ') }}
|
|
1650
|
+
</span>
|
|
1651
|
+
{% endif %}
|
|
1652
|
+
</div>
|
|
1653
|
+
{% if error_list[0].short_description %}
|
|
1654
|
+
<div class="mb-2">
|
|
1655
|
+
<strong>Error:</strong> <code>{{ error_list[0].short_description }}</code>
|
|
1692
1656
|
</div>
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
<
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
</li>
|
|
1711
|
-
{% endfor %}
|
|
1712
|
-
</ul>
|
|
1713
|
-
|
|
1714
|
-
<!-- Error content -->
|
|
1715
|
-
<div class="tab-content" id="multi-error-content-{{ property_index }}">
|
|
1657
|
+
{% endif %}
|
|
1658
|
+
<details>
|
|
1659
|
+
<summary class="btn btn-sm btn-outline-secondary mb-2">Show Full Traceback</summary>
|
|
1660
|
+
<pre class="text-danger mb-0 text-start" style="font-size: 0.85rem; white-space: pre-wrap; text-align: left;">{{ error_list[0].traceback }}</pre>
|
|
1661
|
+
</details>
|
|
1662
|
+
</div>
|
|
1663
|
+
</td>
|
|
1664
|
+
</tr>
|
|
1665
|
+
{% else %}
|
|
1666
|
+
<!-- Multiple errors detail row -->
|
|
1667
|
+
<tr class="collapse" id="multi-error-detail-{{ property_index }}">
|
|
1668
|
+
<td colspan="7">
|
|
1669
|
+
<div class="bg-light p-3 rounded">
|
|
1670
|
+
<!-- Error summary -->
|
|
1671
|
+
<div class="mb-3">
|
|
1672
|
+
<h6 class="text-danger">Multiple Errors Detected</h6>
|
|
1673
|
+
<div class="d-flex flex-wrap gap-1">
|
|
1716
1674
|
{% for error in error_list %}
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
aria-labelledby="multi-error-tab-{{ property_index }}-{{ loop.index }}">
|
|
1721
|
-
<div class="mb-2">
|
|
1722
|
-
<span class="badge bg-{{ 'danger' if error.state == 'fail' else 'warning' }}">
|
|
1723
|
-
{{ error.state|upper }} #{{ loop.index }}
|
|
1724
|
-
</span>
|
|
1725
|
-
<small class="text-muted ms-2">Error {{ loop.index }} of {{ loop.length }}</small>
|
|
1726
|
-
{% if error.occurrence_count > 1 %}
|
|
1727
|
-
<span class="badge bg-info ms-2">
|
|
1728
|
-
{{ error.occurrence_count }} occurrences
|
|
1729
|
-
</span>
|
|
1730
|
-
{% endif %}
|
|
1675
|
+
<span class="badge bg-{{ 'danger' if error.state == 'fail' else 'warning' }}">
|
|
1676
|
+
{{ error.state|upper }} #{{ loop.index }}
|
|
1677
|
+
{% if error.occurrence_count > 1 %} ({{ error.occurrence_count }}x){% endif %}
|
|
1731
1678
|
{% if error.startStepsCountList is defined and error.startStepsCountList|length > 0 %}
|
|
1732
|
-
|
|
1733
|
-
<i class="bi bi-step-forward"></i> Monkey Steps: {{ error.startStepsCountList|join(', ') }}
|
|
1734
|
-
</span>
|
|
1679
|
+
@{% if error.startStepsCountList|length == 1 %}{{ error.startStepsCountList[0] }}{% else %}{{ error.startStepsCountList[0] }}-{{ error.startStepsCountList[-1] }}{% endif %}
|
|
1735
1680
|
{% endif %}
|
|
1736
|
-
</
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1681
|
+
</span>
|
|
1682
|
+
{% endfor %}
|
|
1683
|
+
</div>
|
|
1684
|
+
</div>
|
|
1685
|
+
|
|
1686
|
+
<!-- Error tabs -->
|
|
1687
|
+
<ul class="nav nav-pills nav-fill mb-3" id="multi-error-tabs-{{ property_index }}" role="tablist">
|
|
1688
|
+
{% for error in error_list %}
|
|
1689
|
+
<li class="nav-item" role="presentation">
|
|
1690
|
+
<button class="nav-link {{ 'active' if loop.first else '' }} btn-sm"
|
|
1691
|
+
id="multi-error-tab-{{ property_index }}-{{ loop.index }}"
|
|
1692
|
+
data-bs-toggle="pill"
|
|
1693
|
+
data-bs-target="#multi-error-content-{{ property_index }}-{{ loop.index }}"
|
|
1694
|
+
type="button" role="tab"
|
|
1695
|
+
aria-controls="multi-error-content-{{ property_index }}-{{ loop.index }}"
|
|
1696
|
+
aria-selected="{{ 'true' if loop.first else 'false' }}">
|
|
1697
|
+
<span class="badge bg-{{ 'danger' if error.state == 'fail' else 'warning' }} me-1">
|
|
1698
|
+
{{ error.state|upper }}
|
|
1699
|
+
</span>
|
|
1700
|
+
#{{ loop.index }}
|
|
1701
|
+
</button>
|
|
1702
|
+
</li>
|
|
1703
|
+
{% endfor %}
|
|
1704
|
+
</ul>
|
|
1705
|
+
|
|
1706
|
+
<!-- Error content -->
|
|
1707
|
+
<div class="tab-content" id="multi-error-content-{{ property_index }}">
|
|
1708
|
+
{% for error in error_list %}
|
|
1709
|
+
<div class="tab-pane fade {{ 'show active' if loop.first else '' }}"
|
|
1710
|
+
id="multi-error-content-{{ property_index }}-{{ loop.index }}"
|
|
1711
|
+
role="tabpanel"
|
|
1712
|
+
aria-labelledby="multi-error-tab-{{ property_index }}-{{ loop.index }}">
|
|
1713
|
+
<div class="mb-2">
|
|
1714
|
+
<span class="badge bg-{{ 'danger' if error.state == 'fail' else 'warning' }}">
|
|
1715
|
+
{{ error.state|upper }} #{{ loop.index }}
|
|
1716
|
+
</span>
|
|
1717
|
+
<small class="text-muted ms-2">Error {{ loop.index }} of {{ loop.length }}</small>
|
|
1718
|
+
{% if error.occurrence_count > 1 %}
|
|
1719
|
+
<span class="badge bg-info ms-2">
|
|
1720
|
+
{{ error.occurrence_count }} occurrences
|
|
1721
|
+
</span>
|
|
1722
|
+
{% endif %}
|
|
1723
|
+
{% if error.startStepsCountList is defined and error.startStepsCountList|length > 0 %}
|
|
1724
|
+
<span class="badge bg-secondary ms-2">
|
|
1725
|
+
<i class="bi bi-step-forward"></i> Monkey Steps: {{ error.startStepsCountList|join(', ') }}
|
|
1726
|
+
</span>
|
|
1741
1727
|
{% endif %}
|
|
1742
|
-
<details>
|
|
1743
|
-
<summary class="btn btn-sm btn-outline-secondary mb-2">Show Full Traceback</summary>
|
|
1744
|
-
<pre class="text-danger mb-0" style="font-size: 0.85rem; white-space: pre-wrap;">{{ error.traceback }}</pre>
|
|
1745
|
-
</details>
|
|
1746
1728
|
</div>
|
|
1747
|
-
{%
|
|
1729
|
+
{% if error.short_description %}
|
|
1730
|
+
<div class="mb-2">
|
|
1731
|
+
<strong>Error:</strong> <code>{{ error.short_description }}</code>
|
|
1732
|
+
</div>
|
|
1733
|
+
{% endif %}
|
|
1734
|
+
<details>
|
|
1735
|
+
<summary class="btn btn-sm btn-outline-secondary mb-2">Show Full Traceback</summary>
|
|
1736
|
+
<pre class="text-danger mb-0 text-start" style="font-size: 0.85rem; white-space: pre-wrap; text-align: left;">{{ error.traceback }}</pre>
|
|
1737
|
+
</details>
|
|
1748
1738
|
</div>
|
|
1739
|
+
{% endfor %}
|
|
1749
1740
|
</div>
|
|
1750
1741
|
</div>
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
</td>
|
|
1756
|
-
</tr>
|
|
1742
|
+
</td>
|
|
1743
|
+
</tr>
|
|
1744
|
+
{% endif %}
|
|
1745
|
+
{% endif %}
|
|
1757
1746
|
{% endfor %}
|
|
1758
1747
|
</tbody>
|
|
1759
1748
|
</table>
|
|
@@ -2097,16 +2086,18 @@
|
|
|
2097
2086
|
// Initialize crash events functionality
|
|
2098
2087
|
initCrashAnalysis();
|
|
2099
2088
|
|
|
2100
|
-
// Initialize pagination for Activities
|
|
2101
|
-
initPagination('
|
|
2102
|
-
|
|
2103
|
-
|
|
2089
|
+
// Initialize pagination for Activities table
|
|
2090
|
+
initPagination('activities-container', 'activity-row', 'activities-pagination', 'activities-page-size');
|
|
2091
|
+
|
|
2104
2092
|
// Initialize activity sorting
|
|
2105
|
-
|
|
2106
|
-
|
|
2093
|
+
initActivitiesSorting();
|
|
2094
|
+
|
|
2107
2095
|
// Initialize activity searching
|
|
2108
|
-
|
|
2109
|
-
|
|
2096
|
+
initActivitiesSearching();
|
|
2097
|
+
|
|
2098
|
+
// Initialize activities page size selector
|
|
2099
|
+
initActivitiesPageSize();
|
|
2100
|
+
|
|
2110
2101
|
// Initialize property statistics searching
|
|
2111
2102
|
initPropertySearching();
|
|
2112
2103
|
|
|
@@ -2188,16 +2179,17 @@
|
|
|
2188
2179
|
}
|
|
2189
2180
|
}
|
|
2190
2181
|
|
|
2191
|
-
// Simplified sorting function for Fails and Errors columns
|
|
2182
|
+
// Simplified sorting function for Fails and Errors columns (Property Checking Statistics only)
|
|
2192
2183
|
function initSorting() {
|
|
2193
|
-
|
|
2194
|
-
|
|
2184
|
+
// Only select sort icons that are NOT activities sort icons
|
|
2185
|
+
const sortIcons = document.querySelectorAll('.sort-icon:not(.activities-sort-icon)');
|
|
2186
|
+
|
|
2195
2187
|
sortIcons.forEach(function(icon) {
|
|
2196
2188
|
icon.addEventListener('click', function() {
|
|
2197
2189
|
const column = this.dataset.column;
|
|
2198
2190
|
const currentOrder = this.dataset.order;
|
|
2199
|
-
|
|
2200
|
-
// Reset all other sort icons
|
|
2191
|
+
|
|
2192
|
+
// Reset all other property sort icons (not activities)
|
|
2201
2193
|
sortIcons.forEach(function(otherIcon) {
|
|
2202
2194
|
if (otherIcon !== icon) {
|
|
2203
2195
|
otherIcon.dataset.order = 'none';
|
|
@@ -2205,7 +2197,7 @@
|
|
|
2205
2197
|
otherIcon.style.color = '#6c757d';
|
|
2206
2198
|
}
|
|
2207
2199
|
});
|
|
2208
|
-
|
|
2200
|
+
|
|
2209
2201
|
// Toggle current sort order
|
|
2210
2202
|
let newOrder;
|
|
2211
2203
|
if (currentOrder === 'none' || currentOrder === 'desc') {
|
|
@@ -2217,7 +2209,7 @@
|
|
|
2217
2209
|
this.className = 'bi bi-arrow-down sort-icon active desc';
|
|
2218
2210
|
this.style.color = '#dc3545';
|
|
2219
2211
|
}
|
|
2220
|
-
|
|
2212
|
+
|
|
2221
2213
|
this.dataset.order = newOrder;
|
|
2222
2214
|
sortTable(column, newOrder);
|
|
2223
2215
|
});
|
|
@@ -2922,12 +2914,11 @@
|
|
|
2922
2914
|
// Property statistics searching function
|
|
2923
2915
|
function initPropertySearching() {
|
|
2924
2916
|
const searchInput = document.getElementById('property-stats-search');
|
|
2925
|
-
const searchButton = document.
|
|
2926
|
-
|
|
2927
|
-
|
|
2917
|
+
const searchButton = document.getElementById('property-search-btn');
|
|
2918
|
+
|
|
2928
2919
|
if (!searchInput) return;
|
|
2929
|
-
|
|
2930
|
-
// Search on Enter key
|
|
2920
|
+
|
|
2921
|
+
// Search on Enter key and clear on Escape
|
|
2931
2922
|
searchInput.addEventListener('keydown', function(e) {
|
|
2932
2923
|
if (e.key === 'Enter') {
|
|
2933
2924
|
e.preventDefault();
|
|
@@ -2936,7 +2927,7 @@
|
|
|
2936
2927
|
clearPropertySearch(this);
|
|
2937
2928
|
}
|
|
2938
2929
|
});
|
|
2939
|
-
|
|
2930
|
+
|
|
2940
2931
|
// Search button functionality
|
|
2941
2932
|
if (searchButton) {
|
|
2942
2933
|
searchButton.addEventListener('click', function() {
|
|
@@ -2944,13 +2935,6 @@
|
|
|
2944
2935
|
});
|
|
2945
2936
|
}
|
|
2946
2937
|
|
|
2947
|
-
// Clear button functionality
|
|
2948
|
-
if (clearButton) {
|
|
2949
|
-
clearButton.addEventListener('click', function() {
|
|
2950
|
-
clearPropertySearch(searchInput);
|
|
2951
|
-
});
|
|
2952
|
-
}
|
|
2953
|
-
|
|
2954
2938
|
function performPropertySearch(searchInput) {
|
|
2955
2939
|
const searchTerm = searchInput.value.toLowerCase().trim();
|
|
2956
2940
|
const container = document.getElementById('property-stats-container');
|
|
@@ -3164,6 +3148,360 @@
|
|
|
3164
3148
|
const currentItemsPerPage = pageSizeSelect ? parseInt(pageSizeSelect.value) : 10;
|
|
3165
3149
|
goToPage(1, containerId, itemClass, currentItemsPerPage, paginationId);
|
|
3166
3150
|
}
|
|
3151
|
+
|
|
3152
|
+
// Activities table searching function
|
|
3153
|
+
function initActivitiesSearching() {
|
|
3154
|
+
const searchInput = document.getElementById('activities-search');
|
|
3155
|
+
const searchButton = document.getElementById('activities-search-btn');
|
|
3156
|
+
|
|
3157
|
+
if (!searchInput) return;
|
|
3158
|
+
|
|
3159
|
+
// Search on Enter key and clear on Escape
|
|
3160
|
+
searchInput.addEventListener('keydown', function(e) {
|
|
3161
|
+
if (e.key === 'Enter') {
|
|
3162
|
+
e.preventDefault();
|
|
3163
|
+
performActivitiesSearch(this);
|
|
3164
|
+
} else if (e.key === 'Escape') {
|
|
3165
|
+
clearActivitiesSearch(this);
|
|
3166
|
+
}
|
|
3167
|
+
});
|
|
3168
|
+
|
|
3169
|
+
// Search button functionality
|
|
3170
|
+
if (searchButton) {
|
|
3171
|
+
searchButton.addEventListener('click', function() {
|
|
3172
|
+
performActivitiesSearch(searchInput);
|
|
3173
|
+
});
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
function performActivitiesSearch(searchInput) {
|
|
3177
|
+
const searchTerm = searchInput.value.toLowerCase().trim();
|
|
3178
|
+
const container = document.getElementById('activities-container');
|
|
3179
|
+
const rows = container.querySelectorAll('.activity-row');
|
|
3180
|
+
const resultsCount = document.getElementById('activities-search-results');
|
|
3181
|
+
|
|
3182
|
+
let visibleCount = 0;
|
|
3183
|
+
|
|
3184
|
+
rows.forEach(function(row) {
|
|
3185
|
+
const activityName = row.querySelector('.activity-name').textContent.toLowerCase();
|
|
3186
|
+
|
|
3187
|
+
// If no search term, show all rows
|
|
3188
|
+
if (!searchTerm) {
|
|
3189
|
+
row.removeAttribute('data-search-visible');
|
|
3190
|
+
visibleCount++;
|
|
3191
|
+
} else {
|
|
3192
|
+
const matches = activityName.includes(searchTerm);
|
|
3193
|
+
if (matches) {
|
|
3194
|
+
row.setAttribute('data-search-visible', 'true');
|
|
3195
|
+
visibleCount++;
|
|
3196
|
+
} else {
|
|
3197
|
+
row.setAttribute('data-search-visible', 'false');
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
});
|
|
3201
|
+
|
|
3202
|
+
console.log('Search performed:', {searchTerm, visibleCount, totalRows: rows.length});
|
|
3203
|
+
|
|
3204
|
+
// Update results count
|
|
3205
|
+
if (resultsCount) {
|
|
3206
|
+
if (searchTerm) {
|
|
3207
|
+
resultsCount.textContent = `Found ${visibleCount} of ${rows.length} activities`;
|
|
3208
|
+
} else {
|
|
3209
|
+
resultsCount.textContent = '';
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
// Immediately show/hide rows based on search before pagination update
|
|
3214
|
+
rows.forEach(function(row) {
|
|
3215
|
+
const searchVisible = row.getAttribute('data-search-visible');
|
|
3216
|
+
if (searchVisible === null || searchVisible === 'true') {
|
|
3217
|
+
row.style.display = '';
|
|
3218
|
+
} else {
|
|
3219
|
+
row.style.display = 'none';
|
|
3220
|
+
}
|
|
3221
|
+
});
|
|
3222
|
+
|
|
3223
|
+
console.log('Rows visibility updated, calling pagination update...');
|
|
3224
|
+
|
|
3225
|
+
// Update pagination after search
|
|
3226
|
+
updateActivitiesPagination();
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
function clearActivitiesSearch(searchInput) {
|
|
3230
|
+
searchInput.value = '';
|
|
3231
|
+
performActivitiesSearch(searchInput);
|
|
3232
|
+
searchInput.focus();
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
|
|
3236
|
+
// Initialize Activities page size selector
|
|
3237
|
+
function initActivitiesPageSize() {
|
|
3238
|
+
const pageSizeSelect = document.getElementById('activities-page-size');
|
|
3239
|
+
|
|
3240
|
+
if (!pageSizeSelect) return;
|
|
3241
|
+
|
|
3242
|
+
// Remove existing event listener to prevent duplicate bindings
|
|
3243
|
+
if (!pageSizeSelect.hasAttribute('data-activities-listener-bound')) {
|
|
3244
|
+
pageSizeSelect.addEventListener('change', function() {
|
|
3245
|
+
console.log('Activities page size changed to:', this.value);
|
|
3246
|
+
updateActivitiesPagination();
|
|
3247
|
+
});
|
|
3248
|
+
// Mark as having listener bound
|
|
3249
|
+
pageSizeSelect.setAttribute('data-activities-listener-bound', 'true');
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
// Activities table sorting function
|
|
3254
|
+
function initActivitiesSorting() {
|
|
3255
|
+
const sortIcon = document.getElementById('visit-count-sort');
|
|
3256
|
+
|
|
3257
|
+
if (!sortIcon) return;
|
|
3258
|
+
|
|
3259
|
+
sortIcon.addEventListener('click', function(e) {
|
|
3260
|
+
e.preventDefault();
|
|
3261
|
+
e.stopPropagation();
|
|
3262
|
+
|
|
3263
|
+
console.log('Sort icon clicked, current order:', this.dataset.order);
|
|
3264
|
+
|
|
3265
|
+
const currentOrder = this.dataset.order || 'none';
|
|
3266
|
+
const container = document.getElementById('activities-container');
|
|
3267
|
+
const rows = Array.from(container.querySelectorAll('.activity-row'));
|
|
3268
|
+
|
|
3269
|
+
console.log('Found rows:', rows.length);
|
|
3270
|
+
|
|
3271
|
+
// Reset only activities sort icons (not property stats sort icons)
|
|
3272
|
+
document.querySelectorAll('.activities-sort-icon').forEach(icon => {
|
|
3273
|
+
if (icon !== this) {
|
|
3274
|
+
icon.className = 'bi bi-arrow-down-up text-muted sort-icon activities-sort-icon';
|
|
3275
|
+
icon.dataset.order = 'none';
|
|
3276
|
+
}
|
|
3277
|
+
});
|
|
3278
|
+
|
|
3279
|
+
let newOrder;
|
|
3280
|
+
if (currentOrder === 'none' || currentOrder === 'desc') {
|
|
3281
|
+
newOrder = 'asc';
|
|
3282
|
+
this.className = 'bi bi-arrow-up text-primary sort-icon activities-sort-icon';
|
|
3283
|
+
} else {
|
|
3284
|
+
newOrder = 'desc';
|
|
3285
|
+
this.className = 'bi bi-arrow-down text-primary sort-icon activities-sort-icon';
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
this.dataset.order = newOrder;
|
|
3289
|
+
console.log('New order set to:', newOrder);
|
|
3290
|
+
|
|
3291
|
+
// Sort rows
|
|
3292
|
+
rows.sort((a, b) => {
|
|
3293
|
+
const aCount = parseInt(a.dataset.visitCount) || 0;
|
|
3294
|
+
const bCount = parseInt(b.dataset.visitCount) || 0;
|
|
3295
|
+
|
|
3296
|
+
if (newOrder === 'asc') {
|
|
3297
|
+
return aCount - bCount;
|
|
3298
|
+
} else {
|
|
3299
|
+
return bCount - aCount;
|
|
3300
|
+
}
|
|
3301
|
+
});
|
|
3302
|
+
|
|
3303
|
+
// Clear container and re-append sorted rows
|
|
3304
|
+
container.innerHTML = '';
|
|
3305
|
+
rows.forEach(row => container.appendChild(row));
|
|
3306
|
+
|
|
3307
|
+
console.log('Sorting completed');
|
|
3308
|
+
|
|
3309
|
+
// Properly update pagination after sorting
|
|
3310
|
+
updateActivitiesPagination();
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
// Function to update Activities pagination after sorting
|
|
3315
|
+
function updateActivitiesPagination() {
|
|
3316
|
+
const container = document.getElementById('activities-container');
|
|
3317
|
+
const pageSizeSelect = document.getElementById('activities-page-size');
|
|
3318
|
+
const paginationElement = document.getElementById('activities-pagination');
|
|
3319
|
+
|
|
3320
|
+
if (!container || !paginationElement) return;
|
|
3321
|
+
|
|
3322
|
+
const allRows = Array.from(container.querySelectorAll('.activity-row'));
|
|
3323
|
+
const itemsPerPage = pageSizeSelect ? parseInt(pageSizeSelect.value) : 10;
|
|
3324
|
+
|
|
3325
|
+
// Filter visible rows (considering search)
|
|
3326
|
+
const visibleRows = allRows.filter(row => {
|
|
3327
|
+
const searchVisible = row.getAttribute('data-search-visible');
|
|
3328
|
+
return searchVisible === null || searchVisible === 'true';
|
|
3329
|
+
});
|
|
3330
|
+
|
|
3331
|
+
const totalItems = visibleRows.length;
|
|
3332
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / itemsPerPage));
|
|
3333
|
+
|
|
3334
|
+
console.log('Updating pagination:', {totalItems, itemsPerPage, totalPages});
|
|
3335
|
+
|
|
3336
|
+
// Clear pagination
|
|
3337
|
+
paginationElement.innerHTML = '';
|
|
3338
|
+
|
|
3339
|
+
// Find pagination container
|
|
3340
|
+
const paginationContainer = paginationElement.closest('.d-flex');
|
|
3341
|
+
|
|
3342
|
+
// Don't show pagination if there's only one page or no items
|
|
3343
|
+
if (totalPages <= 1) {
|
|
3344
|
+
if (paginationContainer) {
|
|
3345
|
+
paginationContainer.style.display = 'none';
|
|
3346
|
+
}
|
|
3347
|
+
// Show visible rows and hide invisible rows
|
|
3348
|
+
allRows.forEach(row => {
|
|
3349
|
+
const searchVisible = row.getAttribute('data-search-visible');
|
|
3350
|
+
if (searchVisible === null || searchVisible === 'true') {
|
|
3351
|
+
row.style.display = '';
|
|
3352
|
+
} else {
|
|
3353
|
+
row.style.display = 'none';
|
|
3354
|
+
}
|
|
3355
|
+
});
|
|
3356
|
+
return;
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
// Show the pagination container when needed
|
|
3360
|
+
if (paginationContainer) {
|
|
3361
|
+
paginationContainer.style.display = '';
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
// Create Previous button
|
|
3365
|
+
const prevLi = document.createElement('li');
|
|
3366
|
+
prevLi.className = 'page-item';
|
|
3367
|
+
prevLi.id = 'activities-prev-page';
|
|
3368
|
+
|
|
3369
|
+
const prevA = document.createElement('a');
|
|
3370
|
+
prevA.className = 'page-link';
|
|
3371
|
+
prevA.href = '#';
|
|
3372
|
+
prevA.innerHTML = '«';
|
|
3373
|
+
prevA.addEventListener('click', function(e) {
|
|
3374
|
+
e.preventDefault();
|
|
3375
|
+
const currentPage = getCurrentActivitiesPage();
|
|
3376
|
+
if (currentPage > 1) {
|
|
3377
|
+
goToActivitiesPage(currentPage - 1, totalPages, itemsPerPage);
|
|
3378
|
+
}
|
|
3379
|
+
});
|
|
3380
|
+
|
|
3381
|
+
prevLi.appendChild(prevA);
|
|
3382
|
+
paginationElement.appendChild(prevLi);
|
|
3383
|
+
|
|
3384
|
+
// Create page number buttons
|
|
3385
|
+
for (let i = 1; i <= totalPages; i++) {
|
|
3386
|
+
const li = document.createElement('li');
|
|
3387
|
+
li.className = `page-item ${i === 1 ? 'active' : ''}`;
|
|
3388
|
+
li.setAttribute('data-page', i);
|
|
3389
|
+
|
|
3390
|
+
const a = document.createElement('a');
|
|
3391
|
+
a.className = 'page-link';
|
|
3392
|
+
a.href = '#';
|
|
3393
|
+
a.textContent = i;
|
|
3394
|
+
a.addEventListener('click', function(e) {
|
|
3395
|
+
e.preventDefault();
|
|
3396
|
+
goToActivitiesPage(i, totalPages, itemsPerPage);
|
|
3397
|
+
});
|
|
3398
|
+
|
|
3399
|
+
li.appendChild(a);
|
|
3400
|
+
paginationElement.appendChild(li);
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
// Create Next button
|
|
3404
|
+
const nextLi = document.createElement('li');
|
|
3405
|
+
nextLi.className = 'page-item';
|
|
3406
|
+
nextLi.id = 'activities-next-page';
|
|
3407
|
+
|
|
3408
|
+
const nextA = document.createElement('a');
|
|
3409
|
+
nextA.className = 'page-link';
|
|
3410
|
+
nextA.href = '#';
|
|
3411
|
+
nextA.innerHTML = '»';
|
|
3412
|
+
nextA.addEventListener('click', function(e) {
|
|
3413
|
+
e.preventDefault();
|
|
3414
|
+
const currentPage = getCurrentActivitiesPage();
|
|
3415
|
+
if (currentPage < totalPages) {
|
|
3416
|
+
goToActivitiesPage(currentPage + 1, totalPages, itemsPerPage);
|
|
3417
|
+
}
|
|
3418
|
+
});
|
|
3419
|
+
|
|
3420
|
+
nextLi.appendChild(nextA);
|
|
3421
|
+
paginationElement.appendChild(nextLi);
|
|
3422
|
+
|
|
3423
|
+
// Show first page and update navigation buttons
|
|
3424
|
+
goToActivitiesPage(1, totalPages, itemsPerPage);
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
// Function to navigate to specific page in Activities table
|
|
3428
|
+
function goToActivitiesPage(pageNumber, totalPages, itemsPerPage) {
|
|
3429
|
+
const container = document.getElementById('activities-container');
|
|
3430
|
+
const paginationElement = document.getElementById('activities-pagination');
|
|
3431
|
+
|
|
3432
|
+
if (!container) return;
|
|
3433
|
+
|
|
3434
|
+
const allRows = Array.from(container.querySelectorAll('.activity-row'));
|
|
3435
|
+
|
|
3436
|
+
// Filter visible rows (considering search)
|
|
3437
|
+
const visibleRows = allRows.filter(row => {
|
|
3438
|
+
const searchVisible = row.getAttribute('data-search-visible');
|
|
3439
|
+
return searchVisible === null || searchVisible === 'true';
|
|
3440
|
+
});
|
|
3441
|
+
|
|
3442
|
+
const startIndex = (pageNumber - 1) * itemsPerPage;
|
|
3443
|
+
const endIndex = startIndex + itemsPerPage;
|
|
3444
|
+
|
|
3445
|
+
console.log('Going to page:', {pageNumber, startIndex, endIndex, totalVisible: visibleRows.length});
|
|
3446
|
+
|
|
3447
|
+
// Hide all rows first
|
|
3448
|
+
allRows.forEach(row => {
|
|
3449
|
+
row.style.display = 'none';
|
|
3450
|
+
});
|
|
3451
|
+
|
|
3452
|
+
// Show rows for current page
|
|
3453
|
+
visibleRows.forEach((row, index) => {
|
|
3454
|
+
if (index >= startIndex && index < endIndex) {
|
|
3455
|
+
row.style.display = '';
|
|
3456
|
+
}
|
|
3457
|
+
});
|
|
3458
|
+
|
|
3459
|
+
// Update pagination active state
|
|
3460
|
+
if (paginationElement) {
|
|
3461
|
+
// Update page number buttons
|
|
3462
|
+
const pageItems = paginationElement.querySelectorAll('.page-item[data-page]');
|
|
3463
|
+
pageItems.forEach((item) => {
|
|
3464
|
+
const page = parseInt(item.getAttribute('data-page'));
|
|
3465
|
+
if (page === pageNumber) {
|
|
3466
|
+
item.classList.add('active');
|
|
3467
|
+
} else {
|
|
3468
|
+
item.classList.remove('active');
|
|
3469
|
+
}
|
|
3470
|
+
});
|
|
3471
|
+
|
|
3472
|
+
// Update Previous button state
|
|
3473
|
+
const prevButton = paginationElement.querySelector('#activities-prev-page');
|
|
3474
|
+
if (prevButton) {
|
|
3475
|
+
if (pageNumber <= 1) {
|
|
3476
|
+
prevButton.classList.add('disabled');
|
|
3477
|
+
} else {
|
|
3478
|
+
prevButton.classList.remove('disabled');
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
// Update Next button state
|
|
3483
|
+
const nextButton = paginationElement.querySelector('#activities-next-page');
|
|
3484
|
+
if (nextButton) {
|
|
3485
|
+
if (pageNumber >= totalPages) {
|
|
3486
|
+
nextButton.classList.add('disabled');
|
|
3487
|
+
} else {
|
|
3488
|
+
nextButton.classList.remove('disabled');
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3494
|
+
// Function to get current active page in Activities pagination
|
|
3495
|
+
function getCurrentActivitiesPage() {
|
|
3496
|
+
const paginationElement = document.getElementById('activities-pagination');
|
|
3497
|
+
if (!paginationElement) return 1;
|
|
3498
|
+
|
|
3499
|
+
const activeItem = paginationElement.querySelector('.page-item.active[data-page]');
|
|
3500
|
+
if (activeItem) {
|
|
3501
|
+
return parseInt(activeItem.getAttribute('data-page'));
|
|
3502
|
+
}
|
|
3503
|
+
return 1;
|
|
3504
|
+
}
|
|
3167
3505
|
</script>
|
|
3168
3506
|
</body>
|
|
3169
3507
|
</html>
|