irie 0.0.50__py3-none-any.whl → 0.0.52__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 irie might be problematic. Click here for more details.

Files changed (36) hide show
  1. irie/apps/inventory/filters.py +11 -29
  2. irie/apps/inventory/models.py +3 -3
  3. irie/apps/inventory/views.py +12 -2
  4. irie/apps/prediction/admin.py +2 -1
  5. irie/apps/prediction/migrations/0004_sensorassignment.py +31 -0
  6. irie/apps/prediction/migrations/0005_remove_sensorassignment_offset_x_and_more.py +53 -0
  7. irie/apps/prediction/migrations/0006_remove_sensorassignment_show_x_and_more.py +25 -0
  8. irie/apps/prediction/models.py +22 -3
  9. irie/apps/prediction/runners/__init__.py +13 -3
  10. irie/apps/prediction/runners/opensees/__init__.py +114 -62
  11. irie/apps/prediction/runners/ssid.py +14 -13
  12. irie/apps/prediction/urls.py +12 -7
  13. irie/apps/prediction/views.py +80 -23
  14. irie/apps/static/assets/css/brace.css +5 -31
  15. irie/apps/static/assets/css/brace.css.map +1 -1
  16. irie/apps/static/assets/css/brace.min.css +2 -2
  17. irie/apps/templates/components/json-table.html +1 -0
  18. irie/apps/templates/includes/paginate.js +6 -0
  19. irie/apps/templates/includes/scripts.html +7 -20
  20. irie/apps/templates/inventory/asset-on-map.html +5 -5
  21. irie/apps/templates/inventory/sensor-upload.html +97 -262
  22. irie/apps/templates/networks/{networks.html → _networks.html} +0 -1
  23. irie/apps/templates/networks/networks.js +6 -4
  24. irie/apps/templates/prediction/asset-predictors.html +41 -47
  25. irie/apps/templates/prediction/{form-submission.html → create-mdof.html} +0 -21
  26. irie/apps/templates/prediction/new-runner.html +0 -20
  27. irie/apps/templates/prediction/predictor-profile.html +8 -134
  28. irie/apps/templates/prediction/viewer/veux-viewer.js +186 -0
  29. irie/apps/templates/prediction/xara-profile.html +221 -0
  30. irie/apps/templates/sensors/render-sensors.js +152 -0
  31. {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/METADATA +2 -3
  32. {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/RECORD +36 -29
  33. {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/WHEEL +1 -1
  34. /irie/apps/templates/prediction/{predictor-upload.html → create-model.html} +0 -0
  35. {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/entry_points.txt +0 -0
  36. {irie-0.0.50.dist-info → irie-0.0.52.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,9 @@
1
+ //===----------------------------------------------------------------------===#
2
+ //
3
+ // STAIRLab -- STructural Artificial Intelligence Laboratory
4
+ //
5
+ //===----------------------------------------------------------------------===#
6
+ //
1
7
  class TablePagination {
2
8
  constructor(tableId, paginationId, searchInputId, rowsPerPage = 9) {
3
9
  this.table = document.getElementById(tableId);
@@ -3,32 +3,19 @@
3
3
  <script src="{{ ASSETS_ROOT }}/vendor/@popperjs/core/dist/umd/popper.min.js"></script>
4
4
  <script src="{{ ASSETS_ROOT }}/vendor/bootstrap/dist/js/bootstrap.min.js"></script>
5
5
  <script>
6
- var win = navigator.platform.indexOf('Win') > -1;
7
- if (win && document.querySelector('#sidenav-scrollbar')) {
8
- var options = {
9
- damping: '0.5'
10
- }
11
- Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
12
- }
6
+ var win = navigator.platform.indexOf('Win') > -1;
7
+ if (win && document.querySelector('#sidenav-scrollbar')) {
8
+ var options = {
9
+ damping: '0.5'
10
+ }
11
+ Scrollbar.init(document.querySelector('#sidenav-scrollbar'), options);
12
+ }
13
13
  </script>
14
14
 
15
- {% comment %}
16
- <script src="{{ ASSETS_ROOT }}/vendor/onscreen/dist/on-screen.umd.min.js"></script>
17
- <script src="{{ ASSETS_ROOT }}/vendor/nouislider/distribute/nouislider.min.js"></script>
18
- <script src="{{ ASSETS_ROOT }}/vendor/vanillajs-datepicker/dist/js/datepicker.min.js"></script>
19
- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
20
- <script src="{{ ASSETS_ROOT }}/vendor/vanillajs-datepicker/dist/js/datepicker.min.js"></script>
21
- {% endcomment %}
22
-
23
15
  <script src="{{ ASSETS_ROOT }}/vendor/smooth-scroll/dist/smooth-scroll.polyfills.min.js"></script>
24
-
25
16
  <script src="{{ ASSETS_ROOT }}/vendor/sweetalert2/dist/sweetalert2.all.min.js"></script>
26
-
27
17
  <script src="{{ ASSETS_ROOT }}/vendor/notyf/notyf.min.js"></script>
28
18
 
29
- <!-- Simplebar -->
30
- <!-- <script src="{{ ASSETS_ROOT }}/vendor/simplebar/dist/simplebar.min.js"></script> -->
31
-
32
19
  <!-- Github buttons -->
33
20
  <script async defer src="https://buttons.github.io/buttons.js"></script>
34
21
 
@@ -13,12 +13,12 @@
13
13
  </style>
14
14
  {% if viewer == "three" %}
15
15
  <script type="importmap">
16
- {
17
- "imports": {
18
- "three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
19
- "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
20
- }
16
+ {
17
+ "imports": {
18
+ "three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
19
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
21
20
  }
21
+ }
22
22
  </script>
23
23
  {% else %}
24
24
  <script src="https://unpkg.com/babylonjs@5.42.2/babylon.js"></script>
@@ -46,149 +46,113 @@ input[type="number"]::-webkit-outer-spin-button {
46
46
 
47
47
 
48
48
  <div class="container">
49
- <div class="row align-right">
49
+ <div class="row align-right">
50
50
 
51
51
  <!-- Left Side: Sensor Form -->
52
- <div class="col-md-6" >
53
- <form method="post">
54
- {% csrf_token %}
55
-
56
- <fieldset class="mb-4">
57
- <legend>Sensor Group</legend>
58
- {{ group_form.as_p }}
59
- <div id="datum-info" class="mb-4 p-2 border rounded bg-light" style="display: none;">
60
- <strong>Datum Location (x;y;z):</strong> <span id="datum-location">_, _, _</span> <br>
61
- <strong>Datum Orientation (dx;dy;dz):</strong> <span id="datum-orientation">_, _, _</span>
62
- </div>
63
- </fieldset>
64
-
65
- <fieldset>
66
- <legend>Sensors</legend>
67
- {{ formset.management_form }}
68
- <div id="formset-container" class="container">
69
- {% for form in formset %}
70
- <div class="sensor-form mb-4">
71
- <div class="row mb-3">
72
- <div class="input-group">
73
- <span class="input-group-text col-md-2 text-dark border-dark">{{ form.name.label }}</span>
74
- <input id="{{form.name.html_name}}" type="text" name="{{form.name.html_name}}" class="form-control col-md-4 text-dark border-dark" required></input>
52
+ <div class="col-md-4" >
53
+ <form method="post">
54
+ {% csrf_token %}
55
+
56
+ <fieldset class="mb-4">
57
+ <legend>Sensor Group</legend>
58
+ {{ group_form.as_p }}
59
+ <div id="datum-info" class="mb-4 p-2 border rounded bg-light" style="display: none;">
60
+ <strong>Datum Location (x;y;z):</strong> <span id="datum-location">_, _, _</span> <br>
61
+ <strong>Datum Orientation (dx;dy;dz):</strong> <span id="datum-orientation">_, _, _</span>
62
+ </div>
63
+ </fieldset>
64
+
65
+ <fieldset>
66
+ <legend>Sensors</legend>
67
+ {{ formset.management_form }}
68
+ <div id="formset-container" class="container">
69
+ {% for form in formset %}
70
+ <div class="sensor-form mb-4">
71
+ <div class="row mb-3">
72
+ <div class="input-group">
73
+ <span class="input-group-text col-md-2 text-dark border-dark">{{ form.name.label }}</span>
74
+ <input id="{{form.name.html_name}}" type="text" name="{{form.name.html_name}}" class="form-control col-md-4 text-dark border-dark" required></input>
75
+ </div>
75
76
  </div>
77
+ <div class="row"><div class="col-md-12 d-flex align-items-center mb-3">
78
+ <div class="input-group">
79
+ <span class="input-group-text col-md-4 text-gray">{{ form.x.label }}</span>
80
+ <input id="{{form.x.html_name}}" type="number" step="any" name="{{form.x.html_name}}" class="form-control col-md-8 text-gray" required></input>
81
+ </div>
82
+ <div class="input-group">
83
+ <span class="input-group-text col-md-4 text-gray">{{ form.y.label }}</span>
84
+ <input id="{{form.y.html_name}}" type="number" step="any" name="{{form.y.html_name}}" class="form-control col-md-8 text-gray" required></input>
85
+ </div>
86
+ <div class="input-group">
87
+ <span class="input-group-text col-md-4 text-gray">{{ form.z.label }}</span>
88
+ <input id="{{form.z.html_name}}" type="number" step="any" name="{{form.z.html_name}}" class="form-control col-md-8 text-gray" required></input>
89
+ </div>
90
+ </div></div>
91
+ <div class="row"><div class="col-md-12 d-flex align-items-center mb-3">
92
+ <div class="input-group">
93
+ <span class="input-group-text col-md-5 text-gray">{{ form.dx.label }}</span>
94
+ <input id="{{form.dx.html_name}}" type="number" step="any" name="{{form.dx.html_name}}" class="form-control col-md-8 text-gray" required></input>
95
+ </div>
96
+ <div class="input-group">
97
+ <span class="input-group-text col-md-5 text-gray">{{ form.dy.label }}</span>
98
+ <input id="{{form.dy.html_name}}" type="number" step="any" name="{{form.dy.html_name}}" class="form-control col-md-8 text-gray" required></input>
99
+ </div>
100
+ <div class="input-group">
101
+ <span class="input-group-text col-md-5 text-gray">{{ form.dz.label }}</span>
102
+ <input id="{{form.dz.html_name}}" type="number" step="any" name="{{form.dz.html_name}}" class="form-control col-md-8 text-gray" required></input>
103
+ </div>
104
+ </div></div>
105
+
106
+ <button class="remove-form btn btn-danger btn-sm ml-2">Remove</button>
76
107
  </div>
77
- <div class="row"><div class="col-md-12 d-flex align-items-center mb-3">
78
- <div class="input-group">
79
- <span class="input-group-text col-md-4 text-gray">{{ form.x.label }}</span>
80
- <input id="{{form.x.html_name}}" type="number" step="any" name="{{form.x.html_name}}" class="form-control col-md-8 text-gray" required></input>
81
- </div>
82
- <div class="input-group">
83
- <span class="input-group-text col-md-4 text-gray">{{ form.y.label }}</span>
84
- <input id="{{form.y.html_name}}" type="number" step="any" name="{{form.y.html_name}}" class="form-control col-md-8 text-gray" required></input>
85
- </div>
86
- <div class="input-group">
87
- <span class="input-group-text col-md-4 text-gray">{{ form.z.label }}</span>
88
- <input id="{{form.z.html_name}}" type="number" step="any" name="{{form.z.html_name}}" class="form-control col-md-8 text-gray" required></input>
89
- </div>
90
- </div></div>
91
- <div class="row"><div class="col-md-12 d-flex align-items-center mb-3">
92
- <div class="input-group">
93
- <span class="input-group-text col-md-5 text-gray">{{ form.dx.label }}</span>
94
- <input id="{{form.dx.html_name}}" type="number" step="any" name="{{form.dx.html_name}}" class="form-control col-md-8 text-gray" required></input>
95
- </div>
96
- <div class="input-group">
97
- <span class="input-group-text col-md-5 text-gray">{{ form.dy.label }}</span>
98
- <input id="{{form.dy.html_name}}" type="number" step="any" name="{{form.dy.html_name}}" class="form-control col-md-8 text-gray" required></input>
99
- </div>
100
- <div class="input-group">
101
- <span class="input-group-text col-md-5 text-gray">{{ form.dz.label }}</span>
102
- <input id="{{form.dz.html_name}}" type="number" step="any" name="{{form.dz.html_name}}" class="form-control col-md-8 text-gray" required></input>
103
- </div>
104
- </div></div>
105
-
106
- <button class="remove-form btn btn-danger btn-sm ml-2">Remove</button>
107
- </div>
108
- {% endfor %}
109
- </div>
110
-
111
- <button id="add-form" class="btn btn-sm button btn-outline-primary mb-3">Add Sensor</button>
112
- </fieldset>
113
-
114
- <button type="button" id="plot-btn" class="btn btn-info btn-sm mb-3">Plot</button>
115
-
116
- <button type="submit" class="btn btn-sm button btn-success mb-3">Submit</button>
117
- </form>
118
- </div>
119
- <!-- Right Side: Asset Geometry -->
120
- <div class="col-md-6">
121
- <h4>Geometry</h4>
122
- {%if false %}
123
- {% if asset.cesmd %}
124
- <div id="sensors" class="card bg-white-100 border-1 rounded-0 shadow mb-3">
125
- <div class="card-body text-center p-2">
126
- <img src="{{ ASSETS_ROOT }}/inventory/ll{{ asset.cesmd|slice:"2:" }}.svg" class="img-fluid">
127
- </div>
128
- <div class="card-footer text-center">
129
- <span class="small">
130
- Source: <a rel="nofollow noreferrer" href="https://www.strongmotioncenter.org/cgi-bin/CESMD/stationhtml.pl?stationID={{asset.cesmd}}&network=CGS">CGS</a>
131
- </span>
132
- </div>
108
+ {% endfor %}
109
+ </div>
110
+ <button id="add-form" class="btn btn-sm button btn-outline-primary mb-3">Add Sensor</button>
111
+ </fieldset>
112
+
113
+ <button type="button" id="plot-btn" class="btn btn-info btn-sm mb-3">Plot</button>
114
+ <button type="submit" class="btn btn-sm button btn-success mb-3">Save</button>
115
+ </form>
133
116
  </div>
134
- {% endif %}
135
117
 
136
- <div id="rendering" class="card bg-white-100 border-1 rounded-0 shadow">
137
- <div class="card-body text-center">
138
- <model-viewer
139
- id="irie-viewer"
140
- alt="3D Model"
141
- {% if asset.rendering %}
142
- src="{{ asset.rendering }}"
143
- {% else %}
144
- src="{{ ASSETS_ROOT }}/inventory/empty.glb"
145
- {% endif %}
146
- camera-controls
147
- interaction-prompt="none"
148
- camera-orbit="0deg 75deg 2m"
149
- field-of-view="30deg"
150
- style="width: 100%; height: 300px; background-color: #f0f0f0;">
151
- </model-viewer>
152
- </div>
153
- <div class="card-footer text-center">
154
- Powered by <a href="https://veux.io/">veux</a>
155
- </div>
156
- </div>
157
- {% else %}
158
- {% if asset.cesmd %}
159
- <div id="sensors" class="card bg-white-100 border-1 rounded-0 shadow mb-3">
160
- <div class="card-body text-center p-2">
161
- <img src="{{ ASSETS_ROOT }}/inventory/ll{{ asset.cesmd|slice:"2:" }}.svg" class="img-fluid">
162
- </div>
163
- <div class="card-footer text-center">
164
- <span class="small">
165
- Source: <a rel="nofollow noreferrer" href="https://www.strongmotioncenter.org/cgi-bin/CESMD/stationhtml.pl?stationID={{asset.cesmd}}&network=CGS">CGS</a>
166
- </span>
118
+ <!-- Right Side: Asset Geometry -->
119
+ <div class="col-md-8">
120
+ <h4>Geometry</h4>
121
+ <div id="rendering" class="card bg-white-100 border-1 rounded-0 shadow">
122
+ {% if renderings %}
123
+ <div class="card-header d-sm-flex flex-row align-items-center flex-0">
124
+ <select id="id_rendering" class="form-select form-select-sm mb-3" name="rendering">
125
+ {% for rendering in renderings %}
126
+ <option value="{{ rendering.glb }}">{{ rendering.name }}</option>
127
+ {% endfor %}
128
+ </select>
129
+ </div>
130
+ {% endif %}
131
+ <div class="card-body text-center" style="background-color: #f0f0f0;">
132
+ <div id="veux-container"
133
+ style="width: 100%; height: 300px; background-color: #f0f0f0; margin: 0 auto;">
134
+ </div>
135
+ </div>
136
+ <div class="card-footer text-center">
137
+ Powered by <a href="https://veux.io/">veux</a>
138
+ </div>
167
139
  </div>
168
- </div>
169
- {% endif %}
170
140
 
171
- <div id="rendering" class="card bg-white-100 border-1 rounded-0 shadow">
172
- <div class="card-body text-center" style="background-color: #f0f0f0;">
173
- <!-- Our Three.js container -->
174
- <div id="veux-container"
175
- style="width: 100%; height: 300px; background-color: #f0f0f0; margin: 0 auto;">
141
+ {% if asset.cesmd %}
142
+ <div id="sensors" class="card bg-white-100 border-1 rounded-0 shadow mb-3">
143
+ <div class="card-body text-center p-2">
144
+ <img src="{{ ASSETS_ROOT }}/inventory/ll{{ asset.cesmd|slice:"2:" }}.svg" class="img-fluid">
145
+ </div>
146
+ <div class="card-footer text-center">
147
+ <span class="small">
148
+ Source: <a rel="nofollow noreferrer" href="https://www.strongmotioncenter.org/cgi-bin/CESMD/stationhtml.pl?stationID={{asset.cesmd}}&network=CGS">CGS</a>
149
+ </span>
176
150
  </div>
177
151
  </div>
178
- <div class="card-footer text-center">
179
- Powered by <a href="https://veux.io/">veux</a>
180
- </div>
152
+ {% endif %}
181
153
  </div>
182
- {% endif %}
154
+ </div>
183
155
  </div>
184
-
185
- </div>
186
- </div>
187
- <!--
188
- <div id="plot-container" style="display: none;">
189
- <h3>3D Sensor Plot</h3>
190
- <div id="sensor-plot"></div>
191
- </div> -->
192
156
  {%endblock content %}
193
157
 
194
158
 
@@ -266,44 +230,7 @@ document.addEventListener("DOMContentLoaded", () => {
266
230
  });
267
231
  </script>
268
232
  <script type="module">
269
-
270
- import * as THREE from 'three';
271
- import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
272
- import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
273
-
274
- function createArrow(origin, direction, length, color, headLength, headWidth, shaftRadius) {
275
- const dir = direction.clone().normalize();
276
-
277
- const shaftLength = length - headLength;
278
-
279
- const arrowGroup = new THREE.Group();
280
-
281
- const shaftGeometry = new THREE.CylinderGeometry(shaftRadius, shaftRadius, shaftLength, 16);
282
- const shaftMaterial = new THREE.MeshStandardMaterial({ color: color });
283
- const shaftMesh = new THREE.Mesh(shaftGeometry, shaftMaterial);
284
-
285
- // CylinderGeometry is oriented along the Y-axis.
286
- // Rotate it so it aligns with the group's local +Y (arrow "up").
287
- // Then rotate the entire group to match `dir`.
288
- shaftMesh.position.y = shaftLength / 2; // move it so its base starts at y=0
289
- arrowGroup.add(shaftMesh);
290
-
291
- const headGeometry = new THREE.ConeGeometry(shaftRadius * 2, headLength, 16);
292
- const headMaterial = new THREE.MeshStandardMaterial({ color: color });
293
- const headMesh = new THREE.Mesh(headGeometry, headMaterial);
294
-
295
- headMesh.position.y = shaftLength + headLength / 2;
296
- arrowGroup.add(headMesh);
297
-
298
- arrowGroup.position.copy(origin);
299
-
300
- // 5) Rotate the entire group so that +Y in local space points along `dir`
301
- const up = new THREE.Vector3(0, 1, 0);
302
- const quaternion = new THREE.Quaternion().setFromUnitVectors(up, dir);
303
- arrowGroup.quaternion.copy(quaternion);
304
-
305
- return arrowGroup;
306
- }
233
+ {% include "sensors/render-sensors.js" %}
307
234
 
308
235
  document.addEventListener('DOMContentLoaded', () => {
309
236
  const container = document.getElementById("veux-container");
@@ -314,100 +241,8 @@ document.addEventListener('DOMContentLoaded', () => {
314
241
  const modelPath = "";
315
242
  {% endif %}
316
243
 
317
- // 1) SETUP SCENE
318
- const scene = new THREE.Scene();
319
- scene.background = new THREE.Color(0xf0f0f0);
320
-
321
- // 2) SETUP RENDERER
322
- const renderer = new THREE.WebGLRenderer({ antialias: true });
323
- renderer.setPixelRatio(window.devicePixelRatio);
324
- renderer.setSize(container.clientWidth, container.clientHeight);
325
- // renderer.outputEncoding = THREE.sRGBEncoding;
326
- container.appendChild(renderer.domElement);
327
-
328
- // 3) SETUP CAMERA
329
- const camera = new THREE.PerspectiveCamera(
330
- 30, // fov
331
- container.clientWidth / container.clientHeight, // aspect
332
- 0.1, // near
333
- 1000 // far
334
- );
335
- // Position: "0deg 75deg 2m" => we can interpret as an angle from horizontal
336
- // Place the camera a bit above and away from the origin.
337
- camera.position.set(0, 2, 2);
338
- camera.lookAt(0, 0, 0);
339
-
340
- // 4) ORBIT CONTROLS
341
- const controls = new OrbitControls(camera, renderer.domElement);
342
- controls.enableDamping = true;
343
- controls.dampingFactor = 0.05;
344
- controls.target.set(0, 0, 0);
345
-
346
- // 5) LIGHTING (basic environment)
347
- const ambientLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.2);
348
- scene.add(ambientLight);
349
-
350
- const globalLight = new THREE.AmbientLight(0xffffff, 0.4);
351
- scene.add(globalLight);
352
-
353
- const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
354
- directionalLight.position.set(5, 10, 7.5);
355
- scene.add(directionalLight);
356
-
357
- // 6) LOAD THE GLB MODEL (if asset.rendering is not empty)
358
- if (modelPath) {
359
- const loader = new GLTFLoader();
360
- loader.load(modelPath, (gltf) => {
361
- const model = gltf.scene;
362
- scene.add(model);
363
-
364
- // Compute bounding box
365
- const box = new THREE.Box3().setFromObject(model);
366
- const size = box.getSize(new THREE.Vector3()).length();
367
- const center = box.getCenter(new THREE.Vector3());
368
-
369
- // Adjust camera clipping
370
- camera.near = size / 100;
371
- camera.far = size * 100;
372
- camera.updateProjectionMatrix();
373
-
374
- // Move camera so the model is nicely framed
375
- camera.position.copy(center);
376
- // Move the camera out some distance (play with the multiplier)
377
- camera.position.x += size;
378
- camera.position.y += size;
379
- camera.position.z += size;
380
- camera.lookAt(center);
381
-
382
-
383
- controls.target.copy(center);
384
- controls.update();
385
- },
386
- undefined,
387
- (error) => {
388
- console.error('Error loading GLB:', error);
389
- });
390
-
391
- } else {
392
- const axesHelper = new THREE.AxesHelper(1);
393
- scene.add(axesHelper);
394
- }
244
+ const scene = createSensorRenderer(container, modelPath);
395
245
 
396
- // 7) HANDLE WINDOW RESIZE
397
- window.addEventListener('resize', onWindowResize, false);
398
- function onWindowResize() {
399
- camera.aspect = container.clientWidth / container.clientHeight;
400
- camera.updateProjectionMatrix();
401
- renderer.setSize(container.clientWidth, container.clientHeight);
402
- }
403
-
404
- // 8) ANIMATE LOOP
405
- function animate() {
406
- requestAnimationFrame(animate);
407
- controls.update();
408
- renderer.render(scene, camera);
409
- }
410
- animate();
411
246
 
412
247
  const arrowObjects = [];
413
248
 
@@ -33,7 +33,6 @@
33
33
  width: 150px;
34
34
  text-align: right;
35
35
  }
36
-
37
36
  .styled-input {
38
37
  flex: 1;
39
38
  }
@@ -4,9 +4,11 @@
4
4
  //
5
5
  //===----------------------------------------------------------------------===//
6
6
  //
7
+ // IRiE
8
+ //
7
9
  let initializedTabs = [];
8
10
 
9
- function loadContent(tab, formData) {
11
+ function fetchAndUpdateTab(tab, formData) {
10
12
 
11
13
  const contentDiv = document.getElementById(`${tab}-content`);
12
14
 
@@ -118,7 +120,7 @@ function addCorridorTab(corr) {
118
120
  const form = document.getElementById("tab1-form");
119
121
  let formData = new FormData(form);
120
122
  formData.append('corridor_input', corr);
121
- loadContent(selectedTab, formData);
123
+ fetchAndUpdateTab(selectedTab, formData);
122
124
  return tabLink;
123
125
  }
124
126
 
@@ -211,7 +213,7 @@ function handleCorridorUpdate(event) {
211
213
 
212
214
  // Create a URLSearchParams object from the form data
213
215
  // and fetch the data for the selected tab
214
- loadContent(tab, formData);
216
+ fetchAndUpdateTab(tab, formData);
215
217
  }
216
218
 
217
219
 
@@ -219,7 +221,7 @@ function handleCorridorUpdate(event) {
219
221
  document.addEventListener('DOMContentLoaded', function () {
220
222
  initializedTabs.push('tab1');
221
223
 
222
- loadContent('tab1', new FormData(document.getElementById("tab1-form")));
224
+ fetchAndUpdateTab('tab1', new FormData(document.getElementById("tab1-form")));
223
225
 
224
226
  const tabs = document.querySelectorAll('.tab-link');
225
227
 
@@ -6,9 +6,7 @@
6
6
  ===----------------------------------------------------------------------===#
7
7
 
8
8
  Claudio Perez, Summer 2023
9
-
10
9
  -->
11
- {# TODO: Accordion table? #}
12
10
 
13
11
  {% extends "layouts/base.html" %}
14
12
  {% load predictor %}
@@ -20,64 +18,60 @@ Claudio Perez, Summer 2023
20
18
  }
21
19
  </style>
22
20
  {% endblock %}
21
+
23
22
  {% block content %}
24
- <h1><code>{{ asset.calid }}</code> Predictors</h1>
23
+ <div class="col-10 mb-4 d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center py-4">
24
+ <div class="d-block mb-4 mb-md-0">
25
+ <nav aria-label="breadcrumb" class="d-none d-md-inline-block">
26
+ <ol class="breadcrumb breadcrumb-dark breadcrumb-transparent">
27
+ <li class="breadcrumb-item">
28
+ <a href="{% url 'dashboard' %}">
29
+ <svg class="icon icon-xxs" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path></svg>
30
+ </a>
31
+ </li>
32
+ <li class="breadcrumb-item" aria-current="page"><a href="{% url 'asset_table' %}">Inventory</a></li>
33
+ <li class="breadcrumb-item"><a href="{% url 'asset_profile' asset.calid %}"><code>{{ asset.calid }}</code></a></li>
34
+ <li class="breadcrumb-item active">Predictors</li>
35
+ </ol>
36
+ </nav>
37
+ <h1><code>{{ asset.calid }}</code> Predictors</h1>
38
+ </div>
39
+ </div>
40
+
25
41
  <div class="py-4 align-right">
26
- <a role="button" class="button btn btn-outline-white btn-gray-600 text-white"
42
+ <a role="button" class="button btn btn-outline-primary"
27
43
  href="/inventory/{{ asset.calid }}" class="me-1">Back to Structure</a>
28
44
 
29
45
  {% for runner in runners %}
46
+ {% if runner.name.lower == 'systemidrunner' %}
30
47
  {% include 'prediction/new-runner.html' with runner=runner form=form %}
48
+ {% endif %}
31
49
  {% endfor %}
32
50
 
33
- {% if False %}
34
51
  <a role="button" class="button btn btn-outline-primary" disabled
35
- href="/inventory/{{ asset.calid }}/predictors/new/" class="me-1">New (Link)</a>
36
- {% endif %}
37
- </div>
38
- {% if False %}
39
- <pre id="get-params"></pre>
40
- {% endif %}
52
+ href="/inventory/{{ asset.calid }}/predictors/create/model/" class="me-1">New Model</a>
41
53
 
54
+ </div>
42
55
  <div class="col-10">
43
- <div class="card">
44
- <div class="card-body">
45
- <div class="accordion accordion-flush" id="accordionFlush">
46
- {% for predictor in asset.predictors.values %}
47
- <div class="accordion-item">
48
- <button class="btn {%if predictor.active %}btn-outline-success{%else%}btn-outline-dark{%endif%}" type="button">Active</button>
49
-
50
- <button class="btn" type="button"
51
- data-bs-toggle="collapse"
52
- data-bs-target="#flush-collapse{{forloop.counter}}"
53
- aria-expanded="false" aria-controls="flush-collapse{{forloop.counter}}">
54
- Details</button>
55
- &nbsp;
56
- <h6 class="accordion-header" style="display:inline" id="flush-heading{{forloop.counter}}">
57
- <a href="./{{predictor.id}}" >
58
- {{predictor.name}}
59
- </a>
60
- </h6>
61
- (<code>{{ predictor.platform }}</code>)
62
- {% if False %}
63
- <button class="accordion-button btn collapsed" type="button"
64
- data-bs-toggle="collapse"
65
- data-bs-target="#flush-collapse{{forloop.counter}}"
66
- aria-expanded="false" aria-controls="flush-collapse{{forloop.counter}}">
67
- </button>
68
- {% endif %}
69
- <div id="flush-collapse{{forloop.counter}}" class="accordion-collapse collapse"
70
- style="color:black"
71
- aria-labelledby="flush-heading{{forloop.counter}}"
72
- data-bs-parent="#accordionFlushExample">
73
- <div class="table-responsive">
74
- {{ predictor|display_predictor }}
75
- </div>
76
- </div>
77
- </div>
78
- {% endfor %}
56
+
57
+ <div class="row row-cols-1 row-cols-md-2 g-4">
58
+ {% for predictor in asset.predictors.values %}
59
+ <div class="col">
60
+ <div class="card">
61
+ <div class="card-header d-sm-flex flex-row align-items-center flex-0">
62
+ <h6 class="accordion-header" style="display:inline" id="{{forloop.counter}}">
63
+ <a href="./{{predictor.id}}" >
64
+ {{predictor.name}}
65
+ </a> (<code>{{ predictor.platform }}</code>)
66
+ </h6>
67
+ </div>
68
+
69
+ <div class="card-footer">
70
+ <button class="btn {%if predictor.active %}btn-outline-success{%else%}btn-outline-dark{%endif%}" type="button">Active</button>
71
+ </div>
79
72
  </div>
80
73
  </div>
74
+ {% endfor %}
81
75
  </div>
82
76
  </div>
83
77