hlsv 1.0.0 → 2.0.0

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -3
  3. data/README.md +36 -29
  4. data/lib/hlsv/analysis_registry.rb +47 -0
  5. data/lib/hlsv/analysis_runner.rb +193 -0
  6. data/lib/hlsv/config_manager.rb +125 -0
  7. data/lib/hlsv/html2word.rb +18 -18
  8. data/lib/hlsv/path_guard.rb +32 -0
  9. data/lib/hlsv/sdtm_validation/dataset.rb +169 -0
  10. data/lib/hlsv/sdtm_validation/define.rb +142 -0
  11. data/lib/hlsv/sdtm_validation/report.rb +357 -0
  12. data/lib/hlsv/sdtm_validation.rb +390 -0
  13. data/lib/hlsv/url_helper.rb +28 -0
  14. data/lib/hlsv/version.rb +1 -1
  15. data/lib/hlsv/web_app.rb +264 -418
  16. data/lib/hlsv.rb +12 -5
  17. data/public/css/accessibility/accessibility.css +33 -0
  18. data/public/css/base/layout.css +33 -0
  19. data/public/css/base/reset.css +23 -0
  20. data/public/css/base/typography.css +31 -0
  21. data/public/css/components/buttons.css +142 -0
  22. data/public/css/components/file-tree.css +107 -0
  23. data/public/css/components/footer.css +43 -0
  24. data/public/css/components/forms.css +56 -0
  25. data/public/css/components/header.css +52 -0
  26. data/public/css/components/status.css +56 -0
  27. data/public/css/features/csv-table.css +204 -0
  28. data/public/css/features/file-browser.css +208 -0
  29. data/public/css/responsive/responsive.css +133 -0
  30. data/public/css/styles.css +25 -0
  31. data/public/css/styles_csv.css +23 -0
  32. data/public/favicon.ico +0 -0
  33. data/public/js/analysis.js +201 -0
  34. data/public/js/app.js +63 -0
  35. data/public/js/browser.js +172 -0
  36. data/public/js/config.js +214 -0
  37. data/public/js/results.js +240 -0
  38. data/public/js/utils.js +57 -0
  39. data/views/csv_view.erb +11 -12
  40. data/views/index.erb +70 -19
  41. data/views/{report_template.erb → report.erb} +203 -188
  42. metadata +39 -41
  43. data/lib/hlsv/find_keys.rb +0 -979
  44. data/lib/hlsv/mon_script.rb +0 -169
  45. data/public/app.js +0 -569
  46. data/public/styles.css +0 -586
  47. data/public/styles_csv.css +0 -448
@@ -1,448 +0,0 @@
1
- /*
2
- Copyright (c) 2026 AdClin
3
- Licensed under the GNU Affero General Public License v3.0 or later.
4
- See the LICENSE file for details.
5
- */
6
-
7
- /* styles_csv.css - Enhanced CSV view styling with branding */
8
-
9
- /* ===========================
10
- BASE STYLES
11
- =========================== */
12
- body {
13
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
14
- margin: 0;
15
- padding: 20px;
16
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
17
- min-height: 100vh;
18
- }
19
-
20
- /* ===========================
21
- CSV HEADER WITH BRANDING
22
- =========================== */
23
- .csv-header {
24
- display: flex;
25
- justify-content: space-between;
26
- align-items: center;
27
- background: white;
28
- padding: 25px;
29
- border-radius: 8px;
30
- margin-bottom: 20px;
31
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
32
- }
33
-
34
- .csv-header h1 {
35
- margin: 0;
36
- padding: 0;
37
- border: none;
38
- color: #2c3e50;
39
- font-size: 1.8em;
40
- }
41
-
42
- .company-branding {
43
- display: flex;
44
- align-items: center;
45
- }
46
-
47
- .company-link {
48
- display: flex;
49
- align-items: center;
50
- gap: 12px;
51
- text-decoration: none;
52
- transition: all 0.3s ease;
53
- }
54
-
55
- .company-link:hover {
56
- opacity: 0.8;
57
- transform: translateY(-2px);
58
- }
59
-
60
- .company-link:focus {
61
- outline: 2px solid #007bff;
62
- outline-offset: 2px;
63
- }
64
-
65
- .company-logo {
66
- height: 50px;
67
- width: auto;
68
- object-fit: contain;
69
- }
70
-
71
- .company-name {
72
- font-size: 1.2em;
73
- font-weight: 600;
74
- color: #2c3e50;
75
- }
76
-
77
- /* ===========================
78
- CSV FOOTER WITH COPYRIGHT AND LICENSE
79
- =========================== */
80
- .csv-footer {
81
- margin-top: 30px;
82
- padding: 20px;
83
- background: white;
84
- border-radius: 8px;
85
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
86
- text-align: center;
87
- }
88
-
89
- .footer-content {
90
- display: flex;
91
- justify-content: center;
92
- align-items: center;
93
- flex-wrap: wrap;
94
- gap: 15px;
95
- color: #6c757d;
96
- font-size: 0.9em;
97
- margin-bottom: 10px;
98
- }
99
-
100
- .footer-content .separator {
101
- color: #dee2e6;
102
- font-weight: bold;
103
- }
104
-
105
- .footer-content a {
106
- color: #007bff;
107
- text-decoration: none;
108
- transition: color 0.3s ease;
109
- }
110
-
111
- .footer-content a:hover {
112
- color: #0056b3;
113
- text-decoration: underline;
114
- }
115
-
116
- .generated-date {
117
- color: #6c757d;
118
- font-size: 0.85em;
119
- margin: 5px 0 0 0;
120
- }
121
-
122
- /* ===========================
123
- INFO SECTION
124
- =========================== */
125
- .info-section {
126
- background: linear-gradient(135deg, #e8f4f8 0%, #d1ecf1 100%);
127
- border-left: 4px solid #3498db;
128
- padding: 20px;
129
- border-radius: 6px;
130
- margin-bottom: 20px;
131
- box-shadow: 0 2px 4px rgba(52, 152, 219, 0.1);
132
- }
133
-
134
- .info-section p {
135
- margin: 10px 0;
136
- line-height: 1.6;
137
- color: #2c3e50;
138
- }
139
-
140
- .info-section strong {
141
- color: #2980b9;
142
- }
143
-
144
- /* ===========================
145
- ACTIONS SECTION
146
- =========================== */
147
- .actions {
148
- margin-bottom: 20px;
149
- display: flex;
150
- gap: 10px;
151
- flex-wrap: wrap;
152
- }
153
-
154
- .btn-export {
155
- display: inline-flex;
156
- align-items: center;
157
- gap: 8px;
158
- padding: 12px 24px;
159
- border: none;
160
- border-radius: 6px;
161
- background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
162
- color: white;
163
- font-size: 14px;
164
- font-weight: 600;
165
- text-decoration: none;
166
- box-shadow: 0 4px 8px rgba(0, 123, 255, 0.2);
167
- transition: all 0.3s ease;
168
- cursor: pointer;
169
- }
170
-
171
- .btn-export:hover {
172
- background: linear-gradient(135deg, #0056b3 0%, #004085 100%);
173
- transform: translateY(-2px);
174
- box-shadow: 0 6px 12px rgba(0, 123, 255, 0.3);
175
- }
176
-
177
- .btn-export:active {
178
- transform: translateY(0);
179
- }
180
-
181
- .btn-export:focus {
182
- outline: 2px solid #007bff;
183
- outline-offset: 2px;
184
- }
185
-
186
- /* ===========================
187
- TABLE CONTAINER
188
- =========================== */
189
- .table-container {
190
- background: white;
191
- border-radius: 8px;
192
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
193
- overflow: auto;
194
- max-height: calc(100vh - 450px);
195
- }
196
-
197
- /* ===========================
198
- TABLE STYLES
199
- =========================== */
200
- table {
201
- border-collapse: collapse;
202
- width: max-content;
203
- min-width: 100%;
204
- font-size: 13px;
205
- }
206
-
207
- th, td {
208
- border: 1px solid #dee2e6;
209
- padding: 10px 12px;
210
- white-space: nowrap;
211
- text-align: left;
212
- }
213
-
214
- /* ===========================
215
- TABLE HEADER
216
- =========================== */
217
- thead th {
218
- background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
219
- color: #2c3e50;
220
- font-weight: 600;
221
- position: sticky;
222
- top: 0;
223
- z-index: 10;
224
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
225
- }
226
-
227
- thead th:first-child {
228
- border-top-left-radius: 8px;
229
- }
230
-
231
- thead th:last-child {
232
- border-top-right-radius: 8px;
233
- }
234
-
235
- /* ===========================
236
- TABLE BODY - ALTERNATING COLORS
237
- =========================== */
238
- tbody tr {
239
- transition: all 0.2s ease;
240
- }
241
-
242
- tbody tr:hover {
243
- background-color: #f8f9fa !important;
244
- transform: scale(1.01);
245
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
246
- }
247
-
248
- tr.even-group {
249
- background-color: #ffffff;
250
- }
251
-
252
- tr.odd-group {
253
- background-color: #e3f2fd;
254
- }
255
-
256
- tbody td {
257
- color: #495057;
258
- }
259
-
260
- /* First column (key number) styling */
261
- tbody td:first-child {
262
- font-weight: 600;
263
- color: #2c3e50;
264
- background-color: rgba(52, 152, 219, 0.05);
265
- }
266
-
267
- /* ===========================
268
- RESPONSIVE DESIGN
269
- =========================== */
270
- @media (max-width: 768px) {
271
- body {
272
- padding: 10px;
273
- }
274
-
275
- .csv-header {
276
- flex-direction: column;
277
- gap: 15px;
278
- text-align: center;
279
- padding: 20px;
280
- }
281
-
282
- .csv-header h1 {
283
- font-size: 1.4em;
284
- }
285
-
286
- .company-logo {
287
- height: 40px;
288
- }
289
-
290
- .company-name {
291
- font-size: 1em;
292
- }
293
-
294
- .info-section {
295
- padding: 15px;
296
- }
297
-
298
- table {
299
- font-size: 11px;
300
- }
301
-
302
- th, td {
303
- padding: 8px 10px;
304
- }
305
-
306
- .btn-export {
307
- width: 100%;
308
- justify-content: center;
309
- }
310
-
311
- .table-container {
312
- max-height: calc(100vh - 500px);
313
- }
314
-
315
- .footer-content {
316
- flex-direction: column;
317
- gap: 8px;
318
- }
319
-
320
- .footer-content .separator {
321
- display: none;
322
- }
323
- }
324
-
325
- @media (max-width: 480px) {
326
- .csv-header h1 {
327
- font-size: 1.2em;
328
- }
329
-
330
- table {
331
- font-size: 10px;
332
- }
333
-
334
- th, td {
335
- padding: 6px 8px;
336
- }
337
-
338
- .company-logo {
339
- height: 35px;
340
- }
341
- }
342
-
343
- /* ===========================
344
- PRINT STYLES
345
- =========================== */
346
- @media print {
347
- body {
348
- background: white;
349
- padding: 0;
350
- }
351
-
352
- .actions {
353
- display: none;
354
- }
355
-
356
- .table-container {
357
- max-height: none;
358
- box-shadow: none;
359
- overflow: visible;
360
- }
361
-
362
- thead th {
363
- position: static;
364
- box-shadow: none;
365
- }
366
-
367
- tbody tr:hover {
368
- transform: none;
369
- box-shadow: none;
370
- }
371
-
372
- .info-section {
373
- page-break-inside: avoid;
374
- }
375
-
376
- .csv-header,
377
- .csv-footer {
378
- box-shadow: none;
379
- }
380
-
381
- .company-link {
382
- pointer-events: none;
383
- }
384
-
385
- a {
386
- color: #000;
387
- text-decoration: underline;
388
- }
389
- }
390
-
391
- /* ===========================
392
- ACCESSIBILITY
393
- =========================== */
394
- @media (prefers-reduced-motion: reduce) {
395
- * {
396
- animation: none !important;
397
- transition: none !important;
398
- }
399
- }
400
-
401
- /* Focus visible for keyboard navigation */
402
- .table-container:focus,
403
- .btn-export:focus,
404
- .company-link:focus {
405
- outline: 2px solid #007bff;
406
- outline-offset: 2px;
407
- }
408
-
409
- /* High contrast mode support */
410
- @media (prefers-contrast: high) {
411
- table {
412
- border: 2px solid #000;
413
- }
414
-
415
- th, td {
416
- border: 1px solid #000;
417
- }
418
-
419
- .btn-export {
420
- border: 2px solid #000;
421
- }
422
-
423
- .csv-header,
424
- .csv-footer {
425
- border: 2px solid #000;
426
- }
427
- }
428
-
429
- /* ===========================
430
- LOADING STATE (if needed)
431
- =========================== */
432
- .loading {
433
- display: flex;
434
- justify-content: center;
435
- align-items: center;
436
- padding: 40px;
437
- color: #6c757d;
438
- }
439
-
440
- .loading::after {
441
- content: "Loading...";
442
- animation: loading 1.5s infinite;
443
- }
444
-
445
- @keyframes loading {
446
- 0%, 100% { opacity: 0.5; }
447
- 50% { opacity: 1; }
448
- }