@allurereport/web-awesome 3.0.0-beta.3

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 (263) hide show
  1. package/.babelrc.js +46 -0
  2. package/.eslintrc.cjs +15 -0
  3. package/README.md +27 -0
  4. package/dist/multi/141.app-b6362ca0.js +1 -0
  5. package/dist/multi/222.app-b6362ca0.js +1 -0
  6. package/dist/multi/335.app-b6362ca0.js +1 -0
  7. package/dist/multi/34.app-b6362ca0.js +1 -0
  8. package/dist/multi/349.app-b6362ca0.js +1 -0
  9. package/dist/multi/378.app-b6362ca0.js +1 -0
  10. package/dist/multi/406.app-b6362ca0.js +1 -0
  11. package/dist/multi/476.app-b6362ca0.js +1 -0
  12. package/dist/multi/53.app-b6362ca0.js +1 -0
  13. package/dist/multi/584.app-b6362ca0.js +1 -0
  14. package/dist/multi/690.app-b6362ca0.js +1 -0
  15. package/dist/multi/747.app-b6362ca0.js +1 -0
  16. package/dist/multi/767.app-b6362ca0.js +1 -0
  17. package/dist/multi/816.app-b6362ca0.js +1 -0
  18. package/dist/multi/83.app-b6362ca0.js +1 -0
  19. package/dist/multi/873.app-b6362ca0.js +1 -0
  20. package/dist/multi/920.app-b6362ca0.js +1 -0
  21. package/dist/multi/991.app-b6362ca0.js +1 -0
  22. package/dist/multi/JetBrainsMono_vf-9e9649b6..woff2 +0 -0
  23. package/dist/multi/JetBrainsMono_vf-b9a9c326..woff +0 -0
  24. package/dist/multi/app-b6362ca0.js +2 -0
  25. package/dist/multi/app-b6362ca0.js.LICENSE.txt +16 -0
  26. package/dist/multi/manifest.json +26 -0
  27. package/dist/multi/pt-root-ui_vf-22fe60ca..woff +0 -0
  28. package/dist/multi/pt-root-ui_vf-9d251e8b..woff2 +0 -0
  29. package/dist/multi/styles-b6362ca0.css +363 -0
  30. package/dist/single/app-57ae0a60.js +2 -0
  31. package/dist/single/app-57ae0a60.js.LICENSE.txt +16 -0
  32. package/dist/single/manifest.json +3 -0
  33. package/package.json +93 -0
  34. package/postcss.config.js +5 -0
  35. package/src/assets/fonts/JetBrainsMono_vf.woff +0 -0
  36. package/src/assets/fonts/JetBrainsMono_vf.woff2 +0 -0
  37. package/src/assets/fonts/pt-root-ui_vf.woff +0 -0
  38. package/src/assets/fonts/pt-root-ui_vf.woff2 +0 -0
  39. package/src/assets/scss/_common.scss +134 -0
  40. package/src/assets/scss/code.css +71 -0
  41. package/src/assets/scss/day.scss +51 -0
  42. package/src/assets/scss/fonts.scss +21 -0
  43. package/src/assets/scss/index.scss +9 -0
  44. package/src/assets/scss/mixins.scss +26 -0
  45. package/src/assets/scss/night.scss +61 -0
  46. package/src/assets/scss/palette.scss +393 -0
  47. package/src/assets/scss/theme.scss +117 -0
  48. package/src/assets/scss/typography.scss +218 -0
  49. package/src/assets/scss/vars.scss +8 -0
  50. package/src/assets/svg/arrows-chevron-down.svg +5 -0
  51. package/src/assets/svg/github.svg +5 -0
  52. package/src/assets/svg/line-alerts-notification-box.svg +3 -0
  53. package/src/assets/svg/line-arrows-chevron-down-double.svg +3 -0
  54. package/src/assets/svg/line-arrows-chevron-down.svg +3 -0
  55. package/src/assets/svg/line-arrows-chevron-right.svg +3 -0
  56. package/src/assets/svg/line-arrows-chevron-up-double.svg +3 -0
  57. package/src/assets/svg/line-arrows-chevron-up.svg +3 -0
  58. package/src/assets/svg/line-arrows-corner-down-right.svg +3 -0
  59. package/src/assets/svg/line-arrows-expand-3.svg +3 -0
  60. package/src/assets/svg/line-arrows-refresh-ccw-1.svg +3 -0
  61. package/src/assets/svg/line-arrows-sort-line-asc.svg +3 -0
  62. package/src/assets/svg/line-arrows-sort-line-desc.svg +3 -0
  63. package/src/assets/svg/line-arrows-switch-vertical-1.svg +3 -0
  64. package/src/assets/svg/line-dev-bug-2.svg +3 -0
  65. package/src/assets/svg/line-dev-code-square.svg +3 -0
  66. package/src/assets/svg/line-files-file-attachment-2.svg +3 -0
  67. package/src/assets/svg/line-general-check.svg +3 -0
  68. package/src/assets/svg/line-general-checklist3.svg +3 -0
  69. package/src/assets/svg/line-general-copy-3.svg +3 -0
  70. package/src/assets/svg/line-general-download-cloud.svg +3 -0
  71. package/src/assets/svg/line-general-equal.svg +3 -0
  72. package/src/assets/svg/line-general-home-line.svg +3 -0
  73. package/src/assets/svg/line-general-link-1.svg +3 -0
  74. package/src/assets/svg/line-general-link-external.svg +3 -0
  75. package/src/assets/svg/line-general-search-md.svg +3 -0
  76. package/src/assets/svg/line-general-settings-1.svg +3 -0
  77. package/src/assets/svg/line-general-x-close.svg +3 -0
  78. package/src/assets/svg/line-general-zap.svg +3 -0
  79. package/src/assets/svg/line-helpers-flag.svg +4 -0
  80. package/src/assets/svg/line-helpers-play-circle.svg +4 -0
  81. package/src/assets/svg/line-images-image.svg +3 -0
  82. package/src/assets/svg/line-security-key.svg +3 -0
  83. package/src/assets/svg/line-shapes-dot-circle.svg +3 -0
  84. package/src/assets/svg/line-shapes-moon.svg +3 -0
  85. package/src/assets/svg/line-shapes-sun.svg +3 -0
  86. package/src/assets/svg/line-time-clock-stopwatch.svg +3 -0
  87. package/src/assets/svg/report-logo.svg +64 -0
  88. package/src/assets/svg/solid-alert-circle.svg +3 -0
  89. package/src/assets/svg/solid-check-circle.svg +3 -0
  90. package/src/assets/svg/solid-help-circle.svg +3 -0
  91. package/src/assets/svg/solid-minus-circle.svg +3 -0
  92. package/src/assets/svg/solid-x-circle.svg +3 -0
  93. package/src/assets/svg/spinner.svg +18 -0
  94. package/src/assets/svg/view-off.svg +12 -0
  95. package/src/assets/svg/view.svg +11 -0
  96. package/src/components/app/ArrowButton/index.tsx +36 -0
  97. package/src/components/app/ArrowButton/styles.scss +32 -0
  98. package/src/components/app/BaseLayout/index.tsx +60 -0
  99. package/src/components/app/BaseLayout/styles.scss +60 -0
  100. package/src/components/app/Footer/FooterLogo.tsx +16 -0
  101. package/src/components/app/Footer/FooterVersion.tsx +27 -0
  102. package/src/components/app/Footer/index.tsx +13 -0
  103. package/src/components/app/Footer/styles.scss +14 -0
  104. package/src/components/app/Header/index.tsx +17 -0
  105. package/src/components/app/Header/styles.scss +26 -0
  106. package/src/components/app/LanguagePicker/index.tsx +41 -0
  107. package/src/components/app/MainReport/index.tsx +19 -0
  108. package/src/components/app/Metadata/index.tsx +114 -0
  109. package/src/components/app/Metadata/styles.scss +146 -0
  110. package/src/components/app/MetadataButton/index.tsx +33 -0
  111. package/src/components/app/MetadataButton/styles.scss +53 -0
  112. package/src/components/app/Modal/index.tsx +184 -0
  113. package/src/components/app/Modal/styles.scss +126 -0
  114. package/src/components/app/ReportBody/Filters.tsx +94 -0
  115. package/src/components/app/ReportBody/HeaderActions.tsx +21 -0
  116. package/src/components/app/ReportBody/SortBy.tsx +134 -0
  117. package/src/components/app/ReportBody/context.tsx +107 -0
  118. package/src/components/app/ReportBody/index.tsx +71 -0
  119. package/src/components/app/ReportBody/styles.scss +64 -0
  120. package/src/components/app/ReportHeader/ReportHeaderLabelList.tsx +12 -0
  121. package/src/components/app/ReportHeader/ReportHeaderLogo.tsx +10 -0
  122. package/src/components/app/ReportHeader/ReportHeaderPie.tsx +14 -0
  123. package/src/components/app/ReportHeader/index.tsx +33 -0
  124. package/src/components/app/ReportHeader/styles.scss +49 -0
  125. package/src/components/app/ReportLogo/index.tsx +17 -0
  126. package/src/components/app/ReportLogo/styles.scss +20 -0
  127. package/src/components/app/ReportLogoFull/index.tsx +21 -0
  128. package/src/components/app/ReportLogoFull/styles.scss +7 -0
  129. package/src/components/app/ReportMetadata/MetadataItem.tsx +45 -0
  130. package/src/components/app/ReportMetadata/MetadataSummary.tsx +79 -0
  131. package/src/components/app/ReportMetadata/MetadataTestType.tsx +16 -0
  132. package/src/components/app/ReportMetadata/MetadataWithIcon.tsx +25 -0
  133. package/src/components/app/ReportMetadata/index.tsx +46 -0
  134. package/src/components/app/ReportMetadata/styles.scss +99 -0
  135. package/src/components/app/Tabs/index.tsx +58 -0
  136. package/src/components/app/Tabs/styles.scss +56 -0
  137. package/src/components/app/TestResult/TestResultAttachmentsView/index.tsx +27 -0
  138. package/src/components/app/TestResult/TestResultAttachmentsView/styles.scss +12 -0
  139. package/src/components/app/TestResult/TestResultDescription/index.tsx +27 -0
  140. package/src/components/app/TestResult/TestResultDescription/styles.scss +12 -0
  141. package/src/components/app/TestResult/TestResultDropdown/index.tsx +19 -0
  142. package/src/components/app/TestResult/TestResultDropdown/styles.scss +34 -0
  143. package/src/components/app/TestResult/TestResultEmpty/index.tsx +34 -0
  144. package/src/components/app/TestResult/TestResultEmpty/styles.scss +25 -0
  145. package/src/components/app/TestResult/TestResultError/index.tsx +51 -0
  146. package/src/components/app/TestResult/TestResultError/styles.scss +40 -0
  147. package/src/components/app/TestResult/TestResultHeader/index.tsx +55 -0
  148. package/src/components/app/TestResult/TestResultHeader/styles.scss +43 -0
  149. package/src/components/app/TestResult/TestResultHistory/TestResultHistoryItem.tsx +57 -0
  150. package/src/components/app/TestResult/TestResultHistory/index.tsx +26 -0
  151. package/src/components/app/TestResult/TestResultHistory/styles.scss +63 -0
  152. package/src/components/app/TestResult/TestResultInfo/index.tsx +79 -0
  153. package/src/components/app/TestResult/TestResultInfo/styles.scss +33 -0
  154. package/src/components/app/TestResult/TestResultLinks/index.tsx +60 -0
  155. package/src/components/app/TestResult/TestResultLinks/styles.scss +30 -0
  156. package/src/components/app/TestResult/TestResultMetadata/index.tsx +27 -0
  157. package/src/components/app/TestResult/TestResultMetadata/styles.scss +8 -0
  158. package/src/components/app/TestResult/TestResultNavigation/index.tsx +89 -0
  159. package/src/components/app/TestResult/TestResultNavigation/styles.scss +48 -0
  160. package/src/components/app/TestResult/TestResultOverview.tsx +40 -0
  161. package/src/components/app/TestResult/TestResultParameters/index.tsx +30 -0
  162. package/src/components/app/TestResult/TestResultParameters/styles.scss +8 -0
  163. package/src/components/app/TestResult/TestResultPrevStatuses/index.tsx +52 -0
  164. package/src/components/app/TestResult/TestResultPrevStatuses/styles.scss +57 -0
  165. package/src/components/app/TestResult/TestResultRetriesView/TestResultRetriesItem.tsx +50 -0
  166. package/src/components/app/TestResult/TestResultRetriesView/index.tsx +24 -0
  167. package/src/components/app/TestResult/TestResultRetriesView/styles.scss +69 -0
  168. package/src/components/app/TestResult/TestResultSetup/index.tsx +50 -0
  169. package/src/components/app/TestResult/TestResultSeverity/index.tsx +34 -0
  170. package/src/components/app/TestResult/TestResultSeverity/styles.scss +29 -0
  171. package/src/components/app/TestResult/TestResultStatus/index.tsx +26 -0
  172. package/src/components/app/TestResult/TestResultStatus/styles.scss +36 -0
  173. package/src/components/app/TestResult/TestResultSteps/HtmlAttachmentPreview.tsx +12 -0
  174. package/src/components/app/TestResult/TestResultSteps/attachment.tsx +70 -0
  175. package/src/components/app/TestResult/TestResultSteps/attachmentCode.tsx +15 -0
  176. package/src/components/app/TestResult/TestResultSteps/attachmentImage.tsx +29 -0
  177. package/src/components/app/TestResult/TestResultSteps/attachmentVideo.tsx +12 -0
  178. package/src/components/app/TestResult/TestResultSteps/index.tsx +49 -0
  179. package/src/components/app/TestResult/TestResultSteps/styles.scss +225 -0
  180. package/src/components/app/TestResult/TestResultSteps/testResultAttachment.tsx +79 -0
  181. package/src/components/app/TestResult/TestResultSteps/testResultAttachmentInfo.tsx +87 -0
  182. package/src/components/app/TestResult/TestResultSteps/testResultStep.tsx +71 -0
  183. package/src/components/app/TestResult/TestResultSteps/testResultStepInfo.tsx +33 -0
  184. package/src/components/app/TestResult/TestResultSteps/wrongAttachment.tsx +8 -0
  185. package/src/components/app/TestResult/TestResultTabs/index.tsx +59 -0
  186. package/src/components/app/TestResult/TestResultTabs/styles.scss +76 -0
  187. package/src/components/app/TestResult/TestResultTeardown/index.tsx +49 -0
  188. package/src/components/app/TestResult/index.tsx +56 -0
  189. package/src/components/app/ThemeButton/ThemeButton.tsx +22 -0
  190. package/src/components/app/Tree/Tree.tsx +122 -0
  191. package/src/components/app/Tree/TreeHeader.tsx +81 -0
  192. package/src/components/app/Tree/TreeItem.tsx +31 -0
  193. package/src/components/app/Tree/TreeItemIcon.tsx +35 -0
  194. package/src/components/app/Tree/index.tsx +40 -0
  195. package/src/components/app/Tree/styles.scss +170 -0
  196. package/src/components/commons/Button/index.tsx +176 -0
  197. package/src/components/commons/Button/styles.scss +558 -0
  198. package/src/components/commons/Counter/index.tsx +29 -0
  199. package/src/components/commons/Counter/styles.scss +21 -0
  200. package/src/components/commons/Label/index.tsx +11 -0
  201. package/src/components/commons/Label/styles.scss +7 -0
  202. package/src/components/commons/Link/index.tsx +20 -0
  203. package/src/components/commons/Link/styles.scss +46 -0
  204. package/src/components/commons/Loadable/index.tsx +32 -0
  205. package/src/components/commons/Menu/index.tsx +173 -0
  206. package/src/components/commons/Menu/styles.scss +94 -0
  207. package/src/components/commons/PageLoader/index.tsx +10 -0
  208. package/src/components/commons/PageLoader/styles.scss +29 -0
  209. package/src/components/commons/SearchBox/index.tsx +61 -0
  210. package/src/components/commons/SearchBox/styles.scss +58 -0
  211. package/src/components/commons/Spinner/index.tsx +8 -0
  212. package/src/components/commons/SuccessRatePieChart/index.tsx +52 -0
  213. package/src/components/commons/SuccessRatePieChart/styles.scss +12 -0
  214. package/src/components/commons/SvgIcon/index.tsx +46 -0
  215. package/src/components/commons/SvgIcon/styles.scss +26 -0
  216. package/src/components/commons/Toggle/index.tsx +29 -0
  217. package/src/components/commons/Toggle/styles.scss +48 -0
  218. package/src/components/commons/Tooltip/index.tsx +123 -0
  219. package/src/components/commons/Tooltip/styles.scss +38 -0
  220. package/src/components/commons/Typography/index.tsx +99 -0
  221. package/src/hooks/useDebouncedCallback.ts +31 -0
  222. package/src/i18n/constants.ts +105 -0
  223. package/src/i18n/locales/am.json +115 -0
  224. package/src/i18n/locales/az.json +115 -0
  225. package/src/i18n/locales/de.json +115 -0
  226. package/src/i18n/locales/en.json +115 -0
  227. package/src/i18n/locales/es.json +114 -0
  228. package/src/i18n/locales/fr.json +115 -0
  229. package/src/i18n/locales/he.json +115 -0
  230. package/src/i18n/locales/it.json +115 -0
  231. package/src/i18n/locales/ja.json +115 -0
  232. package/src/i18n/locales/ka.json +115 -0
  233. package/src/i18n/locales/kr.json +115 -0
  234. package/src/i18n/locales/nl.json +115 -0
  235. package/src/i18n/locales/pl.json +113 -0
  236. package/src/i18n/locales/pt.json +115 -0
  237. package/src/i18n/locales/ru.json +113 -0
  238. package/src/i18n/locales/sv.json +115 -0
  239. package/src/i18n/locales/tr.json +115 -0
  240. package/src/i18n/locales/zh.json +115 -0
  241. package/src/index.html +35 -0
  242. package/src/index.tsx +48 -0
  243. package/src/stores/chart.ts +32 -0
  244. package/src/stores/envInfo.ts +34 -0
  245. package/src/stores/index.ts +4 -0
  246. package/src/stores/locale.ts +79 -0
  247. package/src/stores/stats.ts +36 -0
  248. package/src/stores/testResults.ts +40 -0
  249. package/src/stores/theme.ts +33 -0
  250. package/src/stores/tree.ts +33 -0
  251. package/src/stores/types.ts +5 -0
  252. package/src/types/globals.d.ts +8 -0
  253. package/src/types/window.d.ts +8 -0
  254. package/src/utils/attachments.ts +156 -0
  255. package/src/utils/capitalize.ts +4 -0
  256. package/src/utils/copyToClipboard.ts +3 -0
  257. package/src/utils/isMac.ts +7 -0
  258. package/src/utils/statuses.ts +55 -0
  259. package/src/utils/time.ts +17 -0
  260. package/src/utils/treeFilters.ts +150 -0
  261. package/tsconfig.json +25 -0
  262. package/types.d.ts +53 -0
  263. package/webpack.config.js +108 -0
@@ -0,0 +1,107 @@
1
+ import { type ComponentChildren, createContext } from "preact";
2
+ import { useCallback, useContext, useReducer } from "preact/hooks";
3
+ import { capitalize } from "@/utils/capitalize";
4
+
5
+ export type SortBy = "order" | "duration" | "status" | "alphabet";
6
+ export type Direction = "asc" | "desc";
7
+ export type Filters = "flaky" | "retry" | "new";
8
+
9
+ export type ReportContentContextValue = {
10
+ query: string;
11
+ filter: Record<Filters, boolean>;
12
+ sortBy: SortBy;
13
+ direction: Direction;
14
+ setQuery: (query: string) => void;
15
+ setSortBy: (sortBy: SortBy) => void;
16
+ setDirection: (direction: Direction) => void;
17
+ setFilter: (filterKey: Filters, value: boolean) => void;
18
+ };
19
+
20
+ export const ReportContentContext = createContext<ReportContentContextValue | null>(null);
21
+
22
+ export const useReportContentContext = () => {
23
+ const context = useContext(ReportContentContext);
24
+
25
+ if (!context) {
26
+ throw new Error("useReportContentContext must be used within a ReportContentProvider");
27
+ }
28
+
29
+ return context;
30
+ };
31
+
32
+ type Actions =
33
+ | {
34
+ type: "setSortBy";
35
+ payload: SortBy;
36
+ }
37
+ | {
38
+ type: "setDirection";
39
+ payload: Direction;
40
+ }
41
+ | {
42
+ type: "setFilter";
43
+ payload: { filterKey: Filters; value: boolean };
44
+ }
45
+ | {
46
+ type: "setQuery";
47
+ payload: string;
48
+ };
49
+
50
+ type State = Omit<ReportContentContextValue, "setSortBy" | "setDirection" | "setFilter" | "setQuery">;
51
+
52
+ export const ReportContentProvider = ({ children }: { children: ComponentChildren }) => {
53
+ const [state, dispatch] = useReducer<State, Actions>(
54
+ (state, action): State => {
55
+ switch (action.type) {
56
+ case "setDirection":
57
+ return { ...state, direction: action.payload };
58
+ case "setSortBy":
59
+ return { ...state, sortBy: action.payload };
60
+ case "setFilter":
61
+ return { ...state, filter: { ...state.filter, [action.payload.filterKey]: action.payload.value } };
62
+ case "setQuery":
63
+ return { ...state, query: action.payload };
64
+ default:
65
+ return state;
66
+ }
67
+ },
68
+ {
69
+ query: "",
70
+ direction: "asc",
71
+ filter: {
72
+ flaky: false,
73
+ new: false,
74
+ retry: false,
75
+ },
76
+ sortBy: "alphabet",
77
+ },
78
+ );
79
+
80
+ const setSortBy = useCallback((sortBy: SortBy) => dispatch({ type: "setSortBy", payload: sortBy }), []);
81
+
82
+ const setDirection = useCallback(
83
+ (direction: Direction) => dispatch({ type: "setDirection", payload: direction }),
84
+ [],
85
+ );
86
+
87
+ const setFilter = useCallback(
88
+ (filterKey: Filters, value: boolean) => dispatch({ type: "setFilter", payload: { filterKey, value } }),
89
+ [],
90
+ );
91
+
92
+ const setQuery = useCallback((query: string) => dispatch({ type: "setQuery", payload: query }), []);
93
+
94
+ return (
95
+ <ReportContentContext.Provider
96
+ value={{
97
+ ...state,
98
+ setSortBy,
99
+ setDirection,
100
+ setFilter,
101
+ setQuery,
102
+ }}
103
+ >
104
+ {children}
105
+ </ReportContentContext.Provider>
106
+ );
107
+ };
@@ -0,0 +1,71 @@
1
+ import { statusesList } from "@allurereport/core-api";
2
+ import { Loadable } from "@/components/commons/Loadable";
3
+ import { statsStore } from "@/stores";
4
+ import { useI18n } from "@/stores/locale";
5
+ import { capitalize } from "@/utils/capitalize";
6
+ import { Counter } from "../../commons/Counter";
7
+ import { Tab, Tabs, TabsList } from "../Tabs";
8
+ import { TreeList } from "../Tree";
9
+ import { HeaderActions } from "./HeaderActions";
10
+ import { SortBy } from "./SortBy";
11
+ import { ReportContentProvider } from "./context";
12
+ import * as styles from "./styles.scss";
13
+
14
+ const ALL_TAB = "total";
15
+
16
+ const Header = () => {
17
+ const { t } = useI18n("statuses");
18
+ return (
19
+ <header className={styles.header}>
20
+ <HeaderActions />
21
+ <div className={styles.headerRow}>
22
+ <TabsList>
23
+ <Loadable
24
+ source={statsStore}
25
+ renderData={(stats) => {
26
+ const allStatuses = statusesList
27
+ .map((status) => ({ status, value: stats[status] }))
28
+ .filter(({ value }) => value)
29
+ .map(({ status, value }) => (
30
+ <Tab data-testid={`tab-${status}`} key={status} id={status}>
31
+ {capitalize(t(status) ?? status)} <Counter count={value} size="s" status={status} />
32
+ </Tab>
33
+ ));
34
+
35
+ return (
36
+ <>
37
+ <Tab data-testid="tab-all" id={ALL_TAB}>
38
+ {capitalize(t("total"))} <Counter count={stats?.total ?? 0} size="s" />
39
+ </Tab>
40
+ {allStatuses}
41
+ </>
42
+ );
43
+ }}
44
+ />
45
+ </TabsList>
46
+ <SortBy />
47
+ </div>
48
+ </header>
49
+ );
50
+ };
51
+
52
+ const Body = () => {
53
+ return (
54
+ <div className={styles.body}>
55
+ <TreeList />
56
+ </div>
57
+ );
58
+ };
59
+
60
+ export const ReportBody = () => {
61
+ return (
62
+ <ReportContentProvider>
63
+ <section>
64
+ <Tabs initialTab="total">
65
+ <Header />
66
+ <Body />
67
+ </Tabs>
68
+ </section>
69
+ </ReportContentProvider>
70
+ );
71
+ };
@@ -0,0 +1,64 @@
1
+ .header {
2
+ padding: 24px;
3
+ padding-bottom: 0;
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: 12px;
7
+ }
8
+
9
+ .headerRow {
10
+ display: flex;
11
+ flex-direction: row;
12
+ column-gap: 8px;
13
+ row-gap: 12px;
14
+ flex-wrap: wrap;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ }
18
+
19
+ .body {
20
+ padding: 16px 24px;
21
+ }
22
+
23
+ .headerActions {
24
+ display: flex;
25
+ gap: 8px;
26
+ }
27
+
28
+ /* This is a hack because button do not have this state */
29
+ .filtersBtnWithFilters > button::after {
30
+ content: "";
31
+ background-color: var(--bg-support-aldebaran);
32
+ width: 6px;
33
+ height: 6px;
34
+ border-radius: 100px;
35
+ position: absolute;
36
+ top: 7px;
37
+ right: 3px;
38
+ }
39
+
40
+ .filterToggle {
41
+ padding-top: 2px;
42
+ }
43
+
44
+ .sortByText {
45
+ color: var(--on-text-secondary);
46
+ }
47
+
48
+ .sortByBtnWrap {
49
+ /*
50
+ Because button is 24px height it makes
51
+ menu item to be 24px height too
52
+ But design is not that
53
+ */
54
+ margin-top: -2px;
55
+ margin-bottom: -2px;
56
+ }
57
+
58
+ .sortByIcon {
59
+ transition: transform var(--interaction-transition-duration) ease-out;
60
+
61
+ &.sortByIconReversed {
62
+ transform: rotate(180deg);
63
+ }
64
+ }
@@ -0,0 +1,12 @@
1
+ import * as styles from "@/components/app/ReportHeader/styles.scss";
2
+ import { Label } from "@/components/commons/Label";
3
+
4
+ export const ReportHeaderLabelList = () => {
5
+ return (
6
+ <div className={styles["report-header-label-list"]}>
7
+ {["Smoke", "regression", "nightly"].map((item, key) => {
8
+ return <Label key={key}>{item}</Label>;
9
+ })}
10
+ </div>
11
+ );
12
+ };
@@ -0,0 +1,10 @@
1
+ import * as styles from "@/components/app/ReportHeader/styles.scss";
2
+ import { ReportLogo } from "@/components/app/ReportLogo";
3
+
4
+ export const ReportHeaderLogo = () => {
5
+ return (
6
+ <div className={styles["report-header-logo"]}>
7
+ <ReportLogo />
8
+ </div>
9
+ );
10
+ };
@@ -0,0 +1,14 @@
1
+ import { Loadable } from "@/components/commons/Loadable";
2
+ import { SuccessRatePieChart } from "@/components/commons/SuccessRatePieChart";
3
+ import { pieChartStore } from "@/stores/chart";
4
+ import * as styles from "./styles.scss";
5
+
6
+ export const ReportHeaderPie = () => (
7
+ <div className={styles["report-header-pie"]}>
8
+ <Loadable
9
+ source={pieChartStore}
10
+ renderLoader={() => null}
11
+ renderData={(chartData) => <SuccessRatePieChart slices={chartData.slices} percentage={chartData.percentage} />}
12
+ />
13
+ </div>
14
+ );
@@ -0,0 +1,33 @@
1
+ import { getReportOptions } from "@allurereport/web-commons";
2
+ import { ReportHeaderLogo } from "@/components/app/ReportHeader/ReportHeaderLogo";
3
+ import { ReportHeaderPie } from "@/components/app/ReportHeader/ReportHeaderPie";
4
+ import { Heading, Text } from "@/components/commons/Typography";
5
+ import { currentLocaleIso } from "@/stores";
6
+ import type { AllureAwesomeReportOptions } from "../../../../types.js";
7
+ import * as styles from "./styles.scss";
8
+
9
+ export const ReportHeader = () => {
10
+ const { reportName, createdAt } = getReportOptions<AllureAwesomeReportOptions>() ?? {};
11
+ const formattedCreatedAt = new Date(createdAt).toLocaleDateString(currentLocaleIso.value as string, {
12
+ month: "long",
13
+ day: "numeric",
14
+ year: "numeric",
15
+ });
16
+
17
+ return (
18
+ <div className={styles["report-header"]}>
19
+ <div className={styles["report-wrapper"]}>
20
+ <ReportHeaderLogo />
21
+ <div className={styles["report-wrapper-text"]}>
22
+ <Heading size={"s"} tag={"h2"} className={styles["wrapper-header"]}>
23
+ {reportName}
24
+ </Heading>
25
+ <Text type="paragraph" size="m" className={styles["report-date"]}>
26
+ {formattedCreatedAt}
27
+ </Text>
28
+ </div>
29
+ </div>
30
+ <ReportHeaderPie />
31
+ </div>
32
+ );
33
+ };
@@ -0,0 +1,49 @@
1
+ .report-header {
2
+ display: flex;
3
+ column-gap: 12px;
4
+ justify-content: space-between;
5
+ padding: 24px;
6
+ align-items: flex-start;
7
+ }
8
+
9
+ .report-wrapper {
10
+ display: flex;
11
+ flex-wrap: wrap;
12
+ flex-grow: 1;
13
+ }
14
+
15
+ .report-wrapper-text {
16
+ flex-grow: 1;
17
+ margin-bottom: 16px;
18
+ }
19
+
20
+ .report-date {
21
+ color: var(--on-text-secondary);
22
+ display: block;
23
+ }
24
+
25
+ .report-header-logo {
26
+ margin-right: 12px;
27
+ }
28
+
29
+ .report-header-labels {
30
+ display: flex;
31
+ }
32
+
33
+ .report-header-label-list {
34
+ display: flex;
35
+ width: 100%;
36
+ column-gap: 8px;
37
+ }
38
+
39
+ .wrapper-header {
40
+ margin-bottom: 2px;
41
+ }
42
+
43
+ .report-header-pie {
44
+ width: 88px;
45
+ }
46
+
47
+ .report-header-pie-chart {
48
+ width: 88px;
49
+ }
@@ -0,0 +1,17 @@
1
+ import { getReportOptions } from "@allurereport/web-commons";
2
+ import { clsx } from "clsx";
3
+ import reportLogoDefault from "@/assets/svg/report-logo.svg";
4
+ import { AllureAwesomeReportOptions } from "../../../../types";
5
+ import { SvgIcon } from "../../commons/SvgIcon";
6
+ import * as styles from "./styles.scss";
7
+
8
+ export const ReportLogo = (props: { className?: string; logo?: never }) => {
9
+ const { className } = props;
10
+ const { logo } = getReportOptions<AllureAwesomeReportOptions>() ?? {};
11
+
12
+ return (
13
+ <div className={clsx(styles["report-logo"], className)}>
14
+ {logo ? <img src={logo} alt="report logo" /> : <SvgIcon id={reportLogoDefault.id} inline />}
15
+ </div>
16
+ );
17
+ };
@@ -0,0 +1,20 @@
1
+ .report-logo {
2
+ padding: 8px;
3
+ background: var(--bg-base-secondary);
4
+ border-radius: 8px;
5
+ width: 48px;
6
+ height: 48px;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+
11
+ img {
12
+ width: 100%;
13
+ height: 100%;
14
+ object-fit: contain;
15
+ }
16
+ }
17
+
18
+ .text {
19
+ color: var(--on-text-primary);
20
+ }
@@ -0,0 +1,21 @@
1
+ import { clsx } from "clsx";
2
+ import reportLogo from "@/assets/svg/report-logo.svg";
3
+ import { SvgIcon } from "../../commons/SvgIcon";
4
+ import { Text } from "../../commons/Typography";
5
+ import * as styles from "./styles.scss";
6
+
7
+ export const ReportLogoFull = (props: {
8
+ /**
9
+ * Additional class name
10
+ */
11
+ className?: string;
12
+ }) => {
13
+ const { className } = props;
14
+
15
+ return (
16
+ <Text type="paragraph" size="m" bold className={clsx(className, styles.text)}>
17
+ <SvgIcon id={reportLogo.id} size="m" inline className={styles.logo} />
18
+ <span>Allure Report</span>
19
+ </Text>
20
+ );
21
+ };
@@ -0,0 +1,7 @@
1
+ .logo {
2
+ margin-right: 8px;
3
+ }
4
+
5
+ .text {
6
+ color: var(--on-text-primary);
7
+ }
@@ -0,0 +1,45 @@
1
+ import { clsx } from "clsx";
2
+ import { FunctionalComponent } from "preact";
3
+ import { Text } from "@/components/commons/Typography";
4
+ import * as styles from "./styles.scss";
5
+
6
+ export type MetadataProps = {
7
+ count?: number;
8
+ title?: string;
9
+ type?: string;
10
+ status?: string;
11
+ };
12
+
13
+ export const MetadataValue: FunctionalComponent<MetadataProps> = ({ count }) => {
14
+ return (
15
+ <Text data-testid="metadata-value" type={"ui"} size={"m"} tag={"div"} className={styles["metadata-item-value"]}>
16
+ {count}
17
+ </Text>
18
+ );
19
+ };
20
+
21
+ interface ReportMetadataItemProps {
22
+ className?: string;
23
+ renderComponent?: FunctionalComponent<MetadataProps>;
24
+ props?: MetadataProps;
25
+ }
26
+
27
+ const MetadataItem: FunctionalComponent<ReportMetadataItemProps> = ({
28
+ className,
29
+ renderComponent: RenderComponent = MetadataValue,
30
+ props,
31
+ ...rest
32
+ }) => {
33
+ const { title } = props || {};
34
+
35
+ return (
36
+ <div {...rest} className={clsx("metadata-item", className)}>
37
+ <Text type={"ui"} size={"s"} tag={"div"} className={styles["metadata-item-title"]}>
38
+ {title}
39
+ </Text>
40
+ {RenderComponent ? <RenderComponent {...props} /> : <MetadataValue {...props} />}
41
+ </div>
42
+ );
43
+ };
44
+
45
+ export default MetadataItem;
@@ -0,0 +1,79 @@
1
+ import { statusesList } from "@allurereport/core-api";
2
+ import { computed } from "@preact/signals";
3
+ import { FunctionComponent } from "preact";
4
+ import MetadataItem, { MetadataProps } from "@/components/app/ReportMetadata/MetadataItem";
5
+ import { MetadataTestType } from "@/components/app/ReportMetadata/MetadataTestType";
6
+ import { MetadataWithIcon } from "@/components/app/ReportMetadata/MetadataWithIcon";
7
+ import * as styles from "@/components/app/ReportMetadata/styles.scss";
8
+ import { Loadable } from "@/components/commons/Loadable";
9
+ import { statsStore } from "@/stores";
10
+ import { useI18n } from "@/stores/locale";
11
+ import { capitalize } from "@/utils/capitalize";
12
+
13
+ export const MetadataSummary: FunctionComponent = () => {
14
+ const { t } = useI18n("statuses");
15
+
16
+ return (
17
+ <Loadable
18
+ source={statsStore}
19
+ renderError={() => null}
20
+ renderData={(stats) => {
21
+ const allTest = computed(() => ({
22
+ title: capitalize(t("total")),
23
+ type: "all",
24
+ count: stats.total,
25
+ }));
26
+ // TODO: https://github.com/qameta/allure3/issues/178
27
+ // const metadataStatsKeys: (keyof Statistic)[] = ["flakyTests", "retryTests", "newTests"];
28
+ // const metaDataTests = metadataStatsKeys
29
+ // .filter((key) => stats[key])
30
+ // .map((key) => {
31
+ // const title = t[key];
32
+ // const props = { title, count: stats[key], type: key };
33
+ //
34
+ // return (
35
+ // <>
36
+ // <MetadataItem key={key} props={props} renderComponent={MetadataWithIcon} />
37
+ // </>
38
+ // );
39
+ // });
40
+
41
+ const metadataStatuses = statusesList
42
+ .map((status) => ({ status, value: stats[status] }))
43
+ .filter(({ value }) => value)
44
+ .map(({ status, value }) => {
45
+ const title = capitalize(t(status) ?? status ?? "");
46
+ const props = {
47
+ title,
48
+ count: value,
49
+ status,
50
+ } as MetadataProps;
51
+
52
+ return (
53
+ <MetadataItem
54
+ data-testid={`metadata-item-${status}`}
55
+ key={status}
56
+ props={props}
57
+ renderComponent={MetadataTestType}
58
+ />
59
+ );
60
+ });
61
+
62
+ return (
63
+ <div class={styles["report-metadata-summary"]}>
64
+ <div className={styles["report-metadata-all-tests"]}>
65
+ <MetadataItem
66
+ data-testid="metadata-item-total"
67
+ props={allTest.value}
68
+ renderComponent={MetadataWithIcon}
69
+ />
70
+ {/*<div className={styles["report-metadata-separator"]}></div>*/}
71
+ {/*{metaDataTests}*/}
72
+ </div>
73
+ <div className={styles["report-metadata-status"]}>{metadataStatuses}</div>
74
+ </div>
75
+ );
76
+ }}
77
+ />
78
+ );
79
+ };
@@ -0,0 +1,16 @@
1
+ import { clsx } from "clsx";
2
+ import { FunctionComponent } from "preact";
3
+ import { MetadataProps } from "@/components/app/ReportMetadata/MetadataItem";
4
+ import * as styles from "@/components/app/ReportMetadata/styles.scss";
5
+ import { Text } from "@/components/commons/Typography";
6
+
7
+ export const MetadataTestType: FunctionComponent<MetadataProps> = ({ status, count }) => {
8
+ return (
9
+ <div data-testid="metadata-value" className={styles["metadata-test-type"]}>
10
+ <div className={clsx(styles["metadata-color-badge"], styles?.[`status-${status}`])}></div>
11
+ <Text type={"ui"} size={"m"} bold>
12
+ {count}
13
+ </Text>
14
+ </div>
15
+ );
16
+ };
@@ -0,0 +1,25 @@
1
+ import { FunctionComponent, h } from "preact";
2
+ import notifications from "@/assets/svg/line-alerts-notification-box.svg";
3
+ import refresh from "@/assets/svg/line-arrows-refresh-ccw-1.svg";
4
+ import lineGeneralZap from "@/assets/svg/line-general-zap.svg";
5
+ import { MetadataProps } from "@/components/app/ReportMetadata/MetadataItem";
6
+ import { SvgIcon } from "@/components/commons/SvgIcon";
7
+ import { Text } from "@/components/commons/Typography";
8
+ import * as styles from "./styles.scss";
9
+
10
+ const icons = {
11
+ flaky: lineGeneralZap.id,
12
+ retry: refresh.id,
13
+ new: notifications.id,
14
+ };
15
+
16
+ export const MetadataWithIcon: FunctionComponent<MetadataProps> = ({ type, count }) => {
17
+ return (
18
+ <div data-testid="metadata-value" className={styles["metadata-with-icon"]}>
19
+ {type !== "all" && <SvgIcon className={styles["metadata-icon"]} id={icons[type]} size={"s"} />}
20
+ <Text size={"m"} bold>
21
+ {count}
22
+ </Text>
23
+ </div>
24
+ );
25
+ };
@@ -0,0 +1,46 @@
1
+ import type { EnvironmentItem } from "@allurereport/core-api";
2
+ import { FunctionalComponent } from "preact";
3
+ import { useState } from "preact/hooks";
4
+ import { MetadataList } from "@/components/app/Metadata";
5
+ import { MetadataButton } from "@/components/app/MetadataButton";
6
+ import { MetadataSummary } from "@/components/app/ReportMetadata/MetadataSummary";
7
+ import { Loadable } from "@/components/commons/Loadable";
8
+ import { envInfoStore } from "@/stores/envInfo";
9
+ import * as styles from "./styles.scss";
10
+
11
+ export interface MetadataItem extends EnvironmentItem {
12
+ value?: string;
13
+ }
14
+
15
+ export type MetadataProps = {
16
+ envInfo?: MetadataItem[];
17
+ size?: "s" | "m";
18
+ groupedLabels?: Record<string, string[]>;
19
+ };
20
+
21
+ const Metadata: FunctionalComponent<MetadataProps> = ({ envInfo }) => {
22
+ const [isOpened, setIsOpen] = useState(true);
23
+ const convertedEnvInfo = envInfo.map((env) => {
24
+ return { ...env, value: env.values.join(", ") };
25
+ });
26
+
27
+ return (
28
+ <div class={styles["report-metadata"]}>
29
+ <MetadataButton isOpened={isOpened} setIsOpen={setIsOpen} title={"Metadata"} counter={envInfo.length} />
30
+ {isOpened && <MetadataList envInfo={convertedEnvInfo} />}
31
+ </div>
32
+ );
33
+ };
34
+
35
+ export const ReportMetadata = () => {
36
+ return (
37
+ <div className={styles["report-metadata-wrapper"]}>
38
+ <MetadataSummary />
39
+ <Loadable
40
+ source={envInfoStore}
41
+ renderError={() => null}
42
+ renderData={(data) => Boolean(data?.length) && <Metadata envInfo={data} />}
43
+ />
44
+ </div>
45
+ );
46
+ };