@allurereport/web-awesome 3.0.0 → 3.1.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 (146) hide show
  1. package/dist/multi/173.app-79c65c7bff941abcbc51.js +1 -0
  2. package/dist/multi/174.app-79c65c7bff941abcbc51.js +1 -0
  3. package/dist/multi/252.app-79c65c7bff941abcbc51.js +1 -0
  4. package/dist/multi/282.app-79c65c7bff941abcbc51.js +1 -0
  5. package/dist/multi/29.app-79c65c7bff941abcbc51.js +1 -0
  6. package/dist/multi/416.app-79c65c7bff941abcbc51.js +1 -0
  7. package/dist/multi/527.app-79c65c7bff941abcbc51.js +1 -0
  8. package/dist/multi/600.app-79c65c7bff941abcbc51.js +1 -0
  9. package/dist/multi/605.app-79c65c7bff941abcbc51.js +1 -0
  10. package/dist/multi/638.app-79c65c7bff941abcbc51.js +1 -0
  11. package/dist/multi/672.app-79c65c7bff941abcbc51.js +1 -0
  12. package/dist/multi/686.app-79c65c7bff941abcbc51.js +1 -0
  13. package/dist/multi/725.app-79c65c7bff941abcbc51.js +1 -0
  14. package/dist/multi/741.app-79c65c7bff941abcbc51.js +1 -0
  15. package/dist/multi/755.app-79c65c7bff941abcbc51.js +1 -0
  16. package/dist/multi/894.app-79c65c7bff941abcbc51.js +1 -0
  17. package/dist/multi/91.app-79c65c7bff941abcbc51.js +1 -0
  18. package/dist/multi/943.app-79c65c7bff941abcbc51.js +1 -0
  19. package/dist/multi/980.app-79c65c7bff941abcbc51.js +1 -0
  20. package/dist/multi/app-79c65c7bff941abcbc51.js +2 -0
  21. package/dist/multi/{app-9931797d1602fc52db5b.js.LICENSE.txt → app-79c65c7bff941abcbc51.js.LICENSE.txt} +7 -0
  22. package/dist/multi/manifest.json +21 -21
  23. package/dist/multi/styles-9e390bad7ce54a807a8e.css +49 -0
  24. package/dist/single/app-3ca67f29d0f1166c08ca.js +2 -0
  25. package/dist/single/{app-6199dc1c2fd3bddc2526.js.LICENSE.txt → app-3ca67f29d0f1166c08ca.js.LICENSE.txt} +7 -0
  26. package/dist/single/manifest.json +1 -1
  27. package/package.json +8 -8
  28. package/src/assets/scss/palette.scss +102 -102
  29. package/src/assets/scss/vars.scss +3 -0
  30. package/src/components/BaseLayout/index.tsx +25 -21
  31. package/src/components/BaseLayout/styles.scss +1 -0
  32. package/src/components/Charts/index.tsx +5 -2
  33. package/src/components/Footer/FooterVersion.tsx +14 -8
  34. package/src/components/Header/index.tsx +9 -7
  35. package/src/components/HeaderControls/index.tsx +5 -2
  36. package/src/components/MainReport/styles.scss +1 -0
  37. package/src/components/Metadata/index.tsx +24 -7
  38. package/src/components/ReportBody/HeaderActions.tsx +4 -13
  39. package/src/components/ReportBody/SortBy.tsx +28 -17
  40. package/src/components/ReportBody/index.tsx +12 -17
  41. package/src/components/ReportBody/styles.scss +4 -1
  42. package/src/components/ReportFilters/BaseFilters.tsx +345 -0
  43. package/src/components/ReportFilters/RetryFlaky.tsx +29 -0
  44. package/src/components/ReportFilters/TagsFilter.tsx +41 -0
  45. package/src/components/ReportFilters/TransitionFilter.tsx +49 -0
  46. package/src/components/ReportFilters/index.tsx +44 -0
  47. package/src/components/ReportFilters/styles.scss +55 -0
  48. package/src/components/ReportSearch/index.tsx +29 -0
  49. package/src/components/ReportTabs/index.tsx +37 -0
  50. package/src/components/SectionPicker/index.tsx +1 -1
  51. package/src/components/SplitLayout/index.tsx +7 -5
  52. package/src/components/TestResult/TestStepsEmpty/index.tsx +1 -7
  53. package/src/components/TestResult/TrEmpty/index.tsx +1 -7
  54. package/src/components/TestResult/TrEnvironmentItem/index.tsx +2 -2
  55. package/src/components/TestResult/TrError/index.tsx +9 -2
  56. package/src/components/TestResult/TrHeader/TrBreadcrumbs.tsx +2 -2
  57. package/src/components/TestResult/TrHistory/TrHistoryItem.tsx +38 -7
  58. package/src/components/TestResult/TrHistory/index.tsx +18 -8
  59. package/src/components/TestResult/TrHistory/styles.scss +4 -7
  60. package/src/components/TestResult/TrInfo/styles.scss +1 -0
  61. package/src/components/TestResult/TrNavigation/index.tsx +109 -68
  62. package/src/components/TestResult/TrNavigation/styles.scss +15 -25
  63. package/src/components/TestResult/TrPwTraces/PwTraceButton.tsx +1 -8
  64. package/src/components/TestResult/TrRetriesView/TrRetriesItem.tsx +2 -3
  65. package/src/components/TestResult/TrRetriesView/index.tsx +4 -3
  66. package/src/components/TestResult/TrSteps/TrAttachment.tsx +5 -3
  67. package/src/components/TestResult/TrSteps/TrAttachmentInfo.tsx +10 -3
  68. package/src/components/TestResult/TrSteps/TrStep.tsx +3 -3
  69. package/src/components/TestResult/TrTabs/index.tsx +7 -23
  70. package/src/components/TestResult/index.tsx +9 -4
  71. package/src/components/TestResult/styles.scss +1 -0
  72. package/src/components/Tree/index.tsx +22 -25
  73. package/src/index.html +19 -18
  74. package/src/index.tsx +20 -28
  75. package/src/locales/az.json +42 -12
  76. package/src/locales/de.json +42 -12
  77. package/src/locales/en.json +42 -12
  78. package/src/locales/es.json +42 -12
  79. package/src/locales/fr.json +42 -12
  80. package/src/locales/he.json +42 -12
  81. package/src/locales/hy.json +42 -12
  82. package/src/locales/it.json +42 -12
  83. package/src/locales/ja.json +42 -12
  84. package/src/locales/ka.json +42 -12
  85. package/src/locales/kr.json +42 -12
  86. package/src/locales/nl.json +42 -12
  87. package/src/locales/pl.json +42 -12
  88. package/src/locales/pt.json +42 -12
  89. package/src/locales/ru.json +42 -12
  90. package/src/locales/sv.json +42 -12
  91. package/src/locales/tr.json +42 -12
  92. package/src/locales/ua.json +42 -12
  93. package/src/locales/zh.json +42 -12
  94. package/src/stores/chart.ts +2 -2
  95. package/src/stores/env.ts +6 -6
  96. package/src/stores/envInfo.ts +2 -2
  97. package/src/stores/globals.ts +1 -1
  98. package/src/stores/index.ts +0 -1
  99. package/src/stores/layout.ts +20 -11
  100. package/src/stores/locale.ts +2 -1
  101. package/src/stores/qualityGate.ts +2 -2
  102. package/src/stores/router.ts +25 -91
  103. package/src/stores/sections.ts +32 -45
  104. package/src/stores/stats.ts +4 -4
  105. package/src/stores/testResult.ts +5 -0
  106. package/src/stores/testResults.ts +7 -5
  107. package/src/stores/tree.ts +49 -126
  108. package/src/stores/treeFilters/actions.ts +63 -0
  109. package/src/stores/treeFilters/constants.ts +13 -0
  110. package/src/stores/treeFilters/model.ts +51 -0
  111. package/src/stores/treeFilters/store.ts +273 -0
  112. package/src/stores/treeFilters/utils.ts +132 -0
  113. package/src/stores/treeSort.ts +71 -0
  114. package/src/stores/variables.ts +3 -3
  115. package/src/utils/persist.ts +23 -0
  116. package/src/utils/tree.ts +12 -5
  117. package/src/utils/treeFilters.ts +48 -54
  118. package/test/components/Header.test.tsx +49 -58
  119. package/test/utils/treeFilters.test.ts +18 -176
  120. package/types.d.ts +4 -1
  121. package/dist/multi/173.app-9931797d1602fc52db5b.js +0 -1
  122. package/dist/multi/174.app-9931797d1602fc52db5b.js +0 -1
  123. package/dist/multi/252.app-9931797d1602fc52db5b.js +0 -1
  124. package/dist/multi/282.app-9931797d1602fc52db5b.js +0 -1
  125. package/dist/multi/29.app-9931797d1602fc52db5b.js +0 -1
  126. package/dist/multi/416.app-9931797d1602fc52db5b.js +0 -1
  127. package/dist/multi/527.app-9931797d1602fc52db5b.js +0 -1
  128. package/dist/multi/600.app-9931797d1602fc52db5b.js +0 -1
  129. package/dist/multi/605.app-9931797d1602fc52db5b.js +0 -1
  130. package/dist/multi/638.app-9931797d1602fc52db5b.js +0 -1
  131. package/dist/multi/672.app-9931797d1602fc52db5b.js +0 -1
  132. package/dist/multi/686.app-9931797d1602fc52db5b.js +0 -1
  133. package/dist/multi/725.app-9931797d1602fc52db5b.js +0 -1
  134. package/dist/multi/741.app-9931797d1602fc52db5b.js +0 -1
  135. package/dist/multi/755.app-9931797d1602fc52db5b.js +0 -1
  136. package/dist/multi/894.app-9931797d1602fc52db5b.js +0 -1
  137. package/dist/multi/91.app-9931797d1602fc52db5b.js +0 -1
  138. package/dist/multi/943.app-9931797d1602fc52db5b.js +0 -1
  139. package/dist/multi/980.app-9931797d1602fc52db5b.js +0 -1
  140. package/dist/multi/app-9931797d1602fc52db5b.js +0 -2
  141. package/dist/multi/styles-8fe37354d1c2270c691e.css +0 -48
  142. package/dist/single/app-6199dc1c2fd3bddc2526.js +0 -2
  143. package/src/components/ReportBody/Filters.tsx +0 -71
  144. package/src/components/Tabs/index.tsx +0 -62
  145. package/src/stores/theme.ts +0 -30
  146. /package/src/components/{Tabs → ReportTabs}/styles.scss +0 -0
@@ -28,22 +28,28 @@
28
28
  "search-placeholder": "Ad veya ID"
29
29
  },
30
30
  "filters": {
31
- "more-filters": "Daha fazla filtre",
32
- "enable-filter": "\"{{filter}}\" filtresini etkinleştir",
33
31
  "flaky": "İstikrarsız",
34
32
  "retry": "Tekrar",
35
33
  "new": "Yeni",
36
34
  "fixed": "Düzeltildi",
37
35
  "regressed": "Geri Döndü",
38
- "malfunctioned": "Bozuk"
39
- },
40
- "filters.description": {
41
- "flaky": "İstikrarsız testleri göster",
42
- "retry": "Yeniden çalıştırılan test sonuçlarını göster",
43
- "new": "Bu raporda ilk kez görünen test sonuçlarını göster",
44
- "fixed": "Şimdi başarılı olan ancak daha önce \"başarısız\" veya \"bozuk\" olan testleri göster",
45
- "regressed": "\"başarılı\" veya \"bozuk\" durumundan \"başarısız\" durumuna değişen test sonuçlarını göster",
46
- "malfunctioned": "\"başarılı\" veya \"başarısız\" durumundan \"bozuk\" durumuna değişen test sonuçlarını göster"
36
+ "malfunctioned": "Bozuk",
37
+ "transition": "Geçiş",
38
+ "tags": "Etiketler",
39
+ "goto_filter": "Filtreye git",
40
+ "errors": {
41
+ "max_values_one": "Filtreleme için yalnızca ilk {{count}} değer kullanılır.\nEk değerler yok sayılır",
42
+ "max_values_other": "Filtreleme için yalnızca ilk {{count}} değer kullanılır.\nEk değerler yok sayılır"
43
+ },
44
+ "description": {
45
+ "flaky": "İstikrarsız testleri göster",
46
+ "retry": "Yeniden çalıştırılan test sonuçlarını göster",
47
+ "new": "Bu raporda ilk kez görünen test sonuçlarını göster",
48
+ "fixed": "Şimdi başarılı olan ancak daha önce \"başarısız\" veya \"bozuk\" olan testleri göster",
49
+ "regressed": "\"başarılı\" veya \"bozuk\" durumundan \"başarısız\" durumuna değişen test sonuçlarını göster",
50
+ "malfunctioned": "\"başarılı\" veya \"başarısız\" durumundan \"bozuk\" durumuna değişen test sonuçlarını göster",
51
+ "tags": "Belirtilen etiketlere sahip test sonuçlarını göster"
52
+ }
47
53
  },
48
54
  "sort-by": {
49
55
  "sort-by-text": "Sıralama ölçütü:",
@@ -366,11 +372,35 @@
366
372
  "new": "Bu test sonucunun rapordaki ilk görünümü",
367
373
  "fixed": "Daha önce \"başarısız\" veya \"bozuk\" olan test artık \"başarılı\"",
368
374
  "regressed": "Daha önce \"başarılı\" veya \"bozuk\" olan test artık \"başarısız\"",
369
- "malfunctioned": "Daha önce \"başarılı\" veya \"başarısız\" olan test artık \"bozuk\""
375
+ "malfunctioned": "Daha önce \"başarılı\" veya \"başarısız\" olan test artık \"bozuk\"",
376
+ "retries": "{{count}} yeniden deneme",
377
+ "flaky": "Çalıştırmalar arasında tutarsız"
370
378
  },
371
379
  "new": "Yeni",
372
380
  "fixed": "Düzeltildi",
373
381
  "regressed": "Geri Döndü",
374
382
  "malfunctioned": "Bozuk"
383
+ },
384
+ "trHistory": {
385
+ "unknown-date": "Bilinmeyen tarih"
386
+ },
387
+ "attachments": {
388
+ "imageDiff": {
389
+ "mode": {
390
+ "diff": "Fark",
391
+ "actual": "Gerçek",
392
+ "expected": "Beklenen",
393
+ "side-by-side": "Yan yana",
394
+ "overlay": "Üst üste"
395
+ },
396
+ "empty": {
397
+ "failed-to-load": "Görüntü karşılaştırması yüklenemedi"
398
+ },
399
+ "image": {
400
+ "diff": "Fark",
401
+ "actual": "Gerçek",
402
+ "expected": "Beklenen"
403
+ }
404
+ }
375
405
  }
376
406
  }
@@ -28,22 +28,28 @@
28
28
  "search-placeholder": "Назва або ID"
29
29
  },
30
30
  "filters": {
31
- "more-filters": "Фільтри",
32
- "enable-filter": "Увімкнути фільтр за \"{{filter}}\"",
33
31
  "flaky": "Нестабільні",
34
32
  "retry": "Повторені",
35
33
  "new": "Нові",
36
34
  "fixed": "Виправлені",
37
35
  "regressed": "Регресовані",
38
- "malfunctioned": "Зламані"
39
- },
40
- "filters.description": {
41
- "flaky": "Показати нестабільні тести",
42
- "retry": "Показати результати тестів, які були перезапущені",
43
- "new": "Показати результати тестів, які вперше з'являються в цьому звіті",
44
- "fixed": "Показати тести, які тепер успішні, але раніше були \"неуспішними\" або \"зламаними\" в попередньому звіті",
45
- "regressed": "Показати результати тестів, які змінили статус на \"неуспішний\" з \"успішний\" або \"зламаний\"",
46
- "malfunctioned": "Показати результати тестів, які змінили статус на \"зламаний\" з \"успішний\" або \"неуспішний\""
36
+ "malfunctioned": "Зламані",
37
+ "transition": "Перехід",
38
+ "tags": "Теги",
39
+ "goto_filter": "Перейти до фільтру",
40
+ "errors": {
41
+ "max_values_one": "Тільки перше {{count}} значення використовується для фільтрації.\nДодаткові значення ігноруються",
42
+ "max_values_other": "Тільки перші {{count}} значення використовуються для фільтрації.\nДодаткові значення ігноруються"
43
+ },
44
+ "description": {
45
+ "flaky": "Показати нестабільні тести",
46
+ "retry": "Показати результати тестів, які були перезапущені",
47
+ "new": "Показати результати тестів, які вперше з'являються в цьому звіті",
48
+ "fixed": "Показати тести, які тепер успішні, але раніше були \"неуспішними\" або \"зламаними\" в попередньому звіті",
49
+ "regressed": "Показати результати тестів, які змінили статус на \"неуспішний\" з \"успішний\" або \"зламаний\"",
50
+ "malfunctioned": "Показати результати тестів, які змінили статус на \"зламаний\" з \"успішний\" або \"неуспішний\"",
51
+ "tags": "Показати результати тестів, які мають вказані теги"
52
+ }
47
53
  },
48
54
  "sort-by": {
49
55
  "sort-by-text": "Сортувати за:",
@@ -317,11 +323,35 @@
317
323
  "new": "Перша поява цього результату тесту в звіті",
318
324
  "fixed": "Раніше \"неуспішний\" або \"зламаний\" тест, який тепер \"успішний\"",
319
325
  "regressed": "Раніше \"успішний\" або \"зламаний\" тест, який тепер \"неуспішний\"",
320
- "malfunctioned": "Раніше \"успішний\" або \"неуспішний\" тест, який тепер \"зламаний\""
326
+ "malfunctioned": "Раніше \"успішний\" або \"неуспішний\" тест, який тепер \"зламаний\"",
327
+ "retries": "{{count}} повторних спроб",
328
+ "flaky": "Нестабільний між запусками"
321
329
  },
322
330
  "new": "Нові",
323
331
  "fixed": "Виправлені",
324
332
  "regressed": "Регресовані",
325
333
  "malfunctioned": "Зламані"
334
+ },
335
+ "trHistory": {
336
+ "unknown-date": "Невідома дата"
337
+ },
338
+ "attachments": {
339
+ "imageDiff": {
340
+ "mode": {
341
+ "diff": "Різниця",
342
+ "actual": "Фактичний",
343
+ "expected": "Очікуваний",
344
+ "side-by-side": "Поруч",
345
+ "overlay": "Наложення"
346
+ },
347
+ "empty": {
348
+ "failed-to-load": "Не вдалося завантажити порівняння зображень"
349
+ },
350
+ "image": {
351
+ "diff": "Різниця",
352
+ "actual": "Фактичний",
353
+ "expected": "Очікуваний"
354
+ }
355
+ }
326
356
  }
327
357
  }
@@ -28,22 +28,28 @@
28
28
  "search-placeholder": "名称或ID"
29
29
  },
30
30
  "filters": {
31
- "more-filters": "更多过滤器",
32
- "enable-filter": "启用 \"{{filter}}\" 过滤器",
33
31
  "flaky": "不稳定",
34
32
  "retry": "重试",
35
33
  "new": "新的",
36
34
  "fixed": "已修复",
37
35
  "regressed": "已回归",
38
- "malfunctioned": "已损坏"
39
- },
40
- "filters.description": {
41
- "flaky": "显示不稳定的测试",
42
- "retry": "显示重新运行的测试结果",
43
- "new": "显示在此报告中首次出现的测试结果",
44
- "fixed": "显示现在通过但之前\"失败\"或\"损坏\"的测试",
45
- "regressed": "显示从\"通过\"或\"损坏\"状态变为\"失败\"状态的测试结果",
46
- "malfunctioned": "显示从\"通过\"或\"失败\"状态变为\"损坏\"状态的测试结果"
36
+ "malfunctioned": "已损坏",
37
+ "transition": "过渡",
38
+ "tags": "标签",
39
+ "goto_filter": "转到过滤器",
40
+ "errors": {
41
+ "max_values_one": "仅使用第一个 {{count}} 值进行过滤。\n忽略其他值",
42
+ "max_values_other": "仅使用前 {{count}} 个值进行过滤。\n忽略其他值"
43
+ },
44
+ "description": {
45
+ "flaky": "显示不稳定的测试",
46
+ "retry": "显示重新运行的测试结果",
47
+ "new": "显示在此报告中首次出现的测试结果",
48
+ "fixed": "显示现在通过但之前\"失败\"或\"损坏\"的测试",
49
+ "regressed": "显示从\"通过\"或\"损坏\"状态变为\"失败\"状态的测试结果",
50
+ "malfunctioned": "显示从\"通过\"或\"失败\"状态变为\"损坏\"状态的测试结果",
51
+ "tags": "显示具有指定标签的测试结果"
52
+ }
47
53
  },
48
54
  "sort-by": {
49
55
  "sort-by-text": "排序依据:",
@@ -366,11 +372,35 @@
366
372
  "new": "此测试结果在报告中的首次出现",
367
373
  "fixed": "之前\"失败\"或\"损坏\"的测试现在\"通过\"了",
368
374
  "regressed": "之前\"通过\"或\"损坏\"的测试现在\"失败\"了",
369
- "malfunctioned": "之前\"通过\"或\"失败\"的测试现在\"损坏\"了"
375
+ "malfunctioned": "之前\"通过\"或\"失败\"的测试现在\"损坏\"了",
376
+ "retries": "{{count}} 次重试",
377
+ "flaky": "多次运行结果不一致"
370
378
  },
371
379
  "new": "新的",
372
380
  "fixed": "已修复",
373
381
  "regressed": "已回归",
374
382
  "malfunctioned": "已损坏"
383
+ },
384
+ "trHistory": {
385
+ "unknown-date": "未知日期"
386
+ },
387
+ "attachments": {
388
+ "imageDiff": {
389
+ "mode": {
390
+ "diff": "差异",
391
+ "actual": "实际",
392
+ "expected": "预期",
393
+ "side-by-side": "并排",
394
+ "overlay": "叠加"
395
+ },
396
+ "empty": {
397
+ "failed-to-load": "无法加载图像对比"
398
+ },
399
+ "image": {
400
+ "diff": "差异",
401
+ "actual": "实际",
402
+ "expected": "预期"
403
+ }
404
+ }
375
405
  }
376
406
  }
@@ -13,7 +13,7 @@ export const pieChartStore = signal<StoreSignalState<PieChartValues>>({
13
13
 
14
14
  export const fetchPieChartData = async (env: string) => {
15
15
  pieChartStore.value = {
16
- ...pieChartStore.value,
16
+ ...pieChartStore.peek(),
17
17
  loading: true,
18
18
  error: undefined,
19
19
  };
@@ -44,7 +44,7 @@ export const chartsStore = signal<StoreSignalState<UIChartsDataWithEnvs>>({
44
44
 
45
45
  export const fetchChartsData = async () => {
46
46
  chartsStore.value = {
47
- ...chartsStore.value,
47
+ ...chartsStore.peek(),
48
48
  loading: true,
49
49
  error: undefined,
50
50
  };
package/src/stores/env.ts CHANGED
@@ -26,7 +26,7 @@ export const setCurrentEnvironment = (env: string) => {
26
26
 
27
27
  export const fetchEnvironments = async () => {
28
28
  environmentsStore.value = {
29
- ...environmentsStore.value,
29
+ ...environmentsStore.peek(),
30
30
  loading: true,
31
31
  error: undefined,
32
32
  };
@@ -41,7 +41,7 @@ export const fetchEnvironments = async () => {
41
41
  };
42
42
  } catch (e) {
43
43
  environmentsStore.value = {
44
- ...environmentsStore.value,
44
+ ...environmentsStore.peek(),
45
45
  error: e.message,
46
46
  loading: false,
47
47
  };
@@ -49,12 +49,12 @@ export const fetchEnvironments = async () => {
49
49
  };
50
50
 
51
51
  export const fetchTestEnvGroup = async (id: string) => {
52
- if (testEnvGroupsStore.value.data[id]) {
52
+ if (testEnvGroupsStore.peek().data[id]) {
53
53
  return;
54
54
  }
55
55
 
56
56
  testEnvGroupsStore.value = {
57
- ...testEnvGroupsStore.value,
57
+ ...testEnvGroupsStore.peek(),
58
58
  loading: true,
59
59
  error: undefined,
60
60
  };
@@ -64,7 +64,7 @@ export const fetchTestEnvGroup = async (id: string) => {
64
64
 
65
65
  testEnvGroupsStore.value = {
66
66
  data: {
67
- ...testEnvGroupsStore.value.data,
67
+ ...testEnvGroupsStore.peek().data,
68
68
  [id]: res,
69
69
  },
70
70
  error: undefined,
@@ -72,7 +72,7 @@ export const fetchTestEnvGroup = async (id: string) => {
72
72
  };
73
73
  } catch (e) {
74
74
  testEnvGroupsStore.value = {
75
- ...testEnvGroupsStore.value,
75
+ ...testEnvGroupsStore.peek(),
76
76
  error: e.message,
77
77
  loading: false,
78
78
  };
@@ -11,7 +11,7 @@ export const envInfoStore = signal<StoreSignalState<EnvironmentItem[]>>({
11
11
 
12
12
  export const fetchEnvInfo = async () => {
13
13
  envInfoStore.value = {
14
- ...envInfoStore.value,
14
+ ...envInfoStore.peek(),
15
15
  loading: true,
16
16
  error: undefined,
17
17
  };
@@ -26,7 +26,7 @@ export const fetchEnvInfo = async () => {
26
26
  };
27
27
  } catch (e) {
28
28
  envInfoStore.value = {
29
- ...envInfoStore.value,
29
+ ...envInfoStore.peek(),
30
30
  error: e.message,
31
31
  loading: false,
32
32
  };
@@ -20,7 +20,7 @@ export const fetchGlobals = async () => {
20
20
  };
21
21
  } catch (err) {
22
22
  globalsStore.value = {
23
- ...globalsStore.value,
23
+ ...globalsStore.peek(),
24
24
  error: err.message,
25
25
  loading: false,
26
26
  };
@@ -1,4 +1,3 @@
1
- export * from "./theme";
2
1
  export type * from "./types";
3
2
  export * from "./stats";
4
3
  export * from "./locale";
@@ -2,7 +2,26 @@ import { getReportOptions } from "@allurereport/web-commons";
2
2
  import { computed, signal } from "@preact/signals";
3
3
  import type { AwesomeReportOptions, Layout } from "types";
4
4
 
5
- export const layoutStore = signal<Layout>("base");
5
+ const reportOptions = getReportOptions<AwesomeReportOptions>();
6
+
7
+ const DEFAULT_LAYOUT = "base";
8
+
9
+ const getInitialLayout = (): Layout => {
10
+ if (typeof window === "undefined") {
11
+ return DEFAULT_LAYOUT;
12
+ }
13
+
14
+ const lsLayout = localStorage.getItem("layout") as Layout | null;
15
+
16
+ if (lsLayout !== null) {
17
+ return lsLayout;
18
+ }
19
+
20
+ return lsLayout ?? reportOptions?.layout ?? DEFAULT_LAYOUT;
21
+ };
22
+
23
+ export const layoutStore = signal<Layout>(getInitialLayout());
24
+
6
25
  export const isLayoutLoading = signal(false);
7
26
 
8
27
  export const setLayout = (newLayout: Layout): void => {
@@ -24,13 +43,3 @@ export const toggleLayout = () => {
24
43
  };
25
44
 
26
45
  export const isSplitMode = computed(() => layoutStore.value === "split");
27
-
28
- export const getLayout = () => {
29
- const { layout } = getReportOptions<AwesomeReportOptions>() ?? {};
30
- const layoutFromLS = window.localStorage.getItem("layout") || (layout as Layout) || "base";
31
-
32
- if (layoutFromLS) {
33
- setLayout(layoutFromLS as Layout);
34
- return;
35
- }
36
- };
@@ -8,7 +8,6 @@ const namespaces = [
8
8
  "empty",
9
9
  "execution",
10
10
  "filters",
11
- "filters.description",
12
11
  "search",
13
12
  "severity",
14
13
  "sort-by",
@@ -28,6 +27,8 @@ const namespaces = [
28
27
  "sections",
29
28
  "timeline",
30
29
  "transitions",
30
+ "trHistory",
31
+ "attachments",
31
32
  ] as const;
32
33
 
33
34
  export const currentLocale = signal<LangLocale>("en" as LangLocale);
@@ -1,4 +1,4 @@
1
- import { QualityGateValidationResult } from "@allurereport/plugin-api";
1
+ import type { QualityGateValidationResult } from "@allurereport/plugin-api";
2
2
  import { fetchReportJsonData } from "@allurereport/web-commons";
3
3
  import { signal } from "@preact/signals";
4
4
  import { type StoreSignalState } from "./types";
@@ -20,7 +20,7 @@ export const fetchQualityGateResults = async () => {
20
20
  };
21
21
  } catch (err) {
22
22
  qualityGateStore.value = {
23
- ...qualityGateStore.value,
23
+ ...qualityGateStore.peek(),
24
24
  error: err.message,
25
25
  loading: false,
26
26
  };
@@ -1,108 +1,42 @@
1
- import { computed, signal } from "@preact/signals";
1
+ import { createRoute, navigateTo as routerNavigateTo } from "@allurereport/web-commons";
2
+ import { computed } from "@preact/signals";
2
3
 
3
- type NavigateToObject = {
4
- category?: string;
5
- params?: {
6
- testResultId?: string | null;
7
- subTab?: string | null;
8
- };
4
+ export const navigateToTestResult = (params: { testResultId: string; tab?: string }) => {
5
+ routerNavigateTo({ path: "/:testResultId/:tab?", params, keepSearchParams: true });
9
6
  };
10
7
 
11
- type Route = {
12
- category?: string;
13
- params?: {
14
- testResultId?: string | null;
15
- subTab?: string | null;
16
- };
8
+ export const navigateToTestResultTab = (params: { testResultId: string; tab: string }) => {
9
+ routerNavigateTo({ path: "/:testResultId/:tab?", params, keepSearchParams: true, replace: true });
17
10
  };
18
11
 
19
- export const parseHash = (): Route => {
20
- const hash = globalThis.location.hash.replace(/^#/, "").trim();
21
- const parts = hash.split("/").filter(Boolean);
22
- const [first, second] = parts;
23
-
24
- if (parts.length === 0) {
25
- return {};
26
- }
27
-
28
- if (parts.length === 1) {
29
- if (/^[a-f0-9]{32,}$/.test(first)) {
30
- return { params: { testResultId: first } };
31
- }
32
- return { category: first || "", params: { testResultId: second } };
33
- }
34
-
35
- if (parts.length === 2) {
36
- if (/^[a-f0-9]{32,}$/.test(first)) {
37
- return {
38
- params: {
39
- testResultId: first,
40
- subTab: second,
41
- },
42
- };
43
- }
44
-
45
- return {
46
- category: first,
47
- params: {
48
- testResultId: second,
49
- },
50
- };
51
- }
52
-
53
- if (parts.length === 3) {
54
- const [category, testResultId, subTab] = parts;
55
- return { category, params: { testResultId, subTab } };
56
- }
57
-
58
- return {};
12
+ export const navigateToRoot = () => {
13
+ routerNavigateTo({ path: "/", keepSearchParams: true });
59
14
  };
60
15
 
61
- export const route = signal<Route>(parseHash());
62
-
63
- export const handleHashChange = () => {
64
- const newRoute = parseHash();
65
-
66
- if (
67
- newRoute.category !== route.value?.category ||
68
- newRoute.params?.testResultId !== route.value.params?.testResultId ||
69
- newRoute.params?.subTab !== route.value.params?.subTab
70
- ) {
71
- route.value = { ...newRoute };
72
- }
16
+ export const navigateToSection = (params: { section: "timeline" | "charts" }) => {
17
+ routerNavigateTo({ path: "/:section", params, keepSearchParams: true, replace: false });
73
18
  };
74
19
 
75
- export const navigateTo = (path: NavigateToObject | string) => {
76
- let newHash = "";
20
+ const sections = ["charts", "timeline"];
77
21
 
78
- if (typeof path === "string") {
79
- newHash = path.startsWith("#") ? path.slice(1) : path;
80
- } else {
81
- const { category, params = {} } = path;
82
- const parts: string[] = [];
22
+ export const testResultRoute = computed(() =>
23
+ createRoute<{ testResultId: string; tab?: string }>("/:testResultId/:tab?", ({ params }) => {
24
+ return params.testResultId && !sections.includes(params.testResultId);
25
+ }),
26
+ );
83
27
 
84
- if (category) {
85
- parts.push(category);
86
- }
28
+ export const rootRoute = computed(() => createRoute<{}>("/"));
87
29
 
88
- if (params.testResultId) {
89
- parts.push(params.testResultId);
90
- }
30
+ export const sectionRoute = computed(() =>
31
+ createRoute<{ section: "timeline" | "charts" }>("/:section", ({ params }) => {
32
+ return sections.includes(params.section);
33
+ }),
34
+ );
91
35
 
92
- if (params.subTab) {
93
- parts.push(params.subTab);
94
- }
95
-
96
- newHash = parts.join("/");
36
+ export const openInNewTab = (path: string) => {
37
+ if (typeof window === "undefined") {
38
+ return;
97
39
  }
98
40
 
99
- history.pushState(null, "", `#${newHash}`);
100
- handleHashChange();
101
- };
102
-
103
- export const openInNewTab = (path: string) => {
104
41
  window.open(`#${path}`, "_blank");
105
42
  };
106
-
107
- export const activeTab = computed(() => route.value.category || "");
108
- export const activeSubTab = computed(() => route.value.params?.subTab || "overview");
@@ -1,63 +1,50 @@
1
1
  import { getReportOptions } from "@allurereport/web-commons";
2
- import { effect, signal } from "@preact/signals";
3
- import { navigateTo, parseHash, route } from "@/stores/router";
2
+ import { computed, effect } from "@preact/signals";
4
3
  import type { AwesomeReportOptions } from "../../types.js";
4
+ import { navigateToRoot, navigateToSection, sectionRoute } from "./router";
5
5
 
6
6
  const DEFAULT_SECTION = "default";
7
- type Section = string;
8
7
 
9
- export const currentSection = signal<Section>("");
10
- export const availableSections = signal<Section[]>([]);
8
+ type Section = "timeline" | "charts" | "default";
11
9
 
12
- const updateSectionState = (section: Section): void => {
13
- currentSection.value = section;
14
- document.documentElement.setAttribute("data-section", section);
15
- globalThis.localStorage.setItem("chosenSection", section);
16
- };
10
+ const reportOptions = getReportOptions<AwesomeReportOptions>();
11
+ const defaultSectionFromReportOptions: Section = (reportOptions?.defaultSection as Section) ?? "default";
17
12
 
18
- export const setSection = (chosenSection: Section): void => {
19
- const isDefaultSection = chosenSection === DEFAULT_SECTION;
20
- const isValidSection = availableSections.value?.includes(chosenSection);
21
- const isSectionChanged = currentSection.value !== chosenSection;
13
+ export const availableSections = (reportOptions?.sections ?? []) as Section[];
22
14
 
23
- updateSectionState(chosenSection);
15
+ const onInit = () => {
16
+ const isSectionRoute = sectionRoute.peek().matches;
17
+ const isDefaultSection = defaultSectionFromReportOptions === DEFAULT_SECTION;
18
+ const isValidSection = availableSections.includes(defaultSectionFromReportOptions);
24
19
 
25
- if (isDefaultSection) {
26
- navigateTo({ category: "" });
27
- return;
28
- }
29
-
30
- if (isSectionChanged && isValidSection) {
31
- navigateTo({ category: chosenSection });
20
+ if (!isSectionRoute && !isDefaultSection && isValidSection) {
21
+ navigateToSection({ section: defaultSectionFromReportOptions });
32
22
  }
33
23
  };
34
24
 
35
- export const getSection = () => {
36
- const { category } = parseHash();
37
- availableSections.value = getReportOptions<AwesomeReportOptions>()?.sections ?? [];
38
- const defaultSectionFromReportOptions = getReportOptions<AwesomeReportOptions>()?.defaultSection ?? "";
39
- const sectionFromUrl = parseHash().category;
40
- const sectionFromLS =
41
- globalThis.localStorage.getItem("chosenSection") === ""
42
- ? ""
43
- : globalThis.localStorage.getItem("chosenSection") || defaultSectionFromReportOptions;
44
- currentSection.value = sectionFromUrl || sectionFromLS;
45
-
46
- if (category) {
47
- setSection(category);
48
- return;
25
+ onInit();
26
+
27
+ export const currentSection = computed(() => sectionRoute.value.params.section ?? "default");
28
+
29
+ effect(() => {
30
+ const section = currentSection.value;
31
+
32
+ if (section) {
33
+ document.documentElement.setAttribute("data-section", section);
49
34
  }
35
+ });
36
+
37
+ export const setSection = (chosenSection: Section | string): void => {
38
+ const isDefaultSection = chosenSection === DEFAULT_SECTION;
39
+ const isValidSection = availableSections.includes(chosenSection as Section);
40
+ const isSectionChanged = currentSection.peek() !== chosenSection;
50
41
 
51
- if (sectionFromLS) {
52
- setSection(sectionFromLS);
42
+ if (isDefaultSection) {
43
+ navigateToRoot();
53
44
  return;
54
45
  }
55
46
 
56
- setSection("");
47
+ if (isSectionChanged && isValidSection) {
48
+ navigateToSection({ section: chosenSection as "timeline" | "charts" });
49
+ }
57
50
  };
58
-
59
- effect(() => {
60
- const category = route.value.category;
61
-
62
- setSection(category || "");
63
- });