@allurereport/web-awesome 3.2.0 → 3.3.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 (113) hide show
  1. package/dist/multi/173.app-8be6acc0a596a2197dbf.js +1 -0
  2. package/dist/multi/174.app-8be6acc0a596a2197dbf.js +1 -0
  3. package/dist/multi/252.app-8be6acc0a596a2197dbf.js +1 -0
  4. package/dist/multi/282.app-8be6acc0a596a2197dbf.js +1 -0
  5. package/dist/multi/29.app-8be6acc0a596a2197dbf.js +1 -0
  6. package/dist/multi/416.app-8be6acc0a596a2197dbf.js +1 -0
  7. package/dist/multi/527.app-8be6acc0a596a2197dbf.js +1 -0
  8. package/dist/multi/600.app-8be6acc0a596a2197dbf.js +1 -0
  9. package/dist/multi/605.app-8be6acc0a596a2197dbf.js +1 -0
  10. package/dist/multi/638.app-8be6acc0a596a2197dbf.js +1 -0
  11. package/dist/multi/672.app-8be6acc0a596a2197dbf.js +1 -0
  12. package/dist/multi/686.app-8be6acc0a596a2197dbf.js +1 -0
  13. package/dist/multi/725.app-8be6acc0a596a2197dbf.js +1 -0
  14. package/dist/multi/741.app-8be6acc0a596a2197dbf.js +1 -0
  15. package/dist/multi/749.app-8be6acc0a596a2197dbf.js +1 -0
  16. package/dist/multi/755.app-8be6acc0a596a2197dbf.js +1 -0
  17. package/dist/multi/894.app-8be6acc0a596a2197dbf.js +1 -0
  18. package/dist/multi/943.app-8be6acc0a596a2197dbf.js +1 -0
  19. package/dist/multi/980.app-8be6acc0a596a2197dbf.js +1 -0
  20. package/dist/multi/app-8be6acc0a596a2197dbf.js +2 -0
  21. package/dist/multi/manifest.json +21 -21
  22. package/dist/multi/{styles-13107bbe6906beabc50f.css → styles-0b84e1ef76554ad2db9a.css} +15 -6
  23. package/dist/single/app-8221eb856e47b4ef50d6.js +2 -0
  24. package/dist/single/manifest.json +1 -1
  25. package/package.json +6 -6
  26. package/src/components/BaseLayout/index.tsx +5 -4
  27. package/src/components/Categories/CategoriesTree/index.tsx +14 -0
  28. package/src/components/Categories/CategoriesTree/styles.scss +14 -0
  29. package/src/components/Categories/CategoryHeaderItem/index.tsx +50 -0
  30. package/src/components/Categories/CategoryHeaderItem/styles.scss +32 -0
  31. package/src/components/Categories/CategoryTreeItem/index.tsx +309 -0
  32. package/src/components/Categories/CategoryTreeItem/styles.scss +47 -0
  33. package/src/components/Categories/GroupTreeItem/index.tsx +76 -0
  34. package/src/components/Categories/GroupTreeItem/styles.scss +47 -0
  35. package/src/components/Categories/HistoryTreeItem/index.tsx +71 -0
  36. package/src/components/Categories/HistoryTreeItem/styles.scss +53 -0
  37. package/src/components/Categories/LabelTreeItem/index.tsx +150 -0
  38. package/src/components/Categories/LabelTreeItem/styles.scss +102 -0
  39. package/src/components/Categories/MessageTreeItem/index.tsx +107 -0
  40. package/src/components/Categories/MessageTreeItem/styles.scss +178 -0
  41. package/src/components/Categories/SeverityTreeItem/index.tsx +50 -0
  42. package/src/components/Categories/SeverityTreeItem/styles.scss +12 -0
  43. package/src/components/Categories/sticky.ts +12 -0
  44. package/src/components/Header/index.tsx +4 -2
  45. package/src/components/MainReport/index.tsx +106 -10
  46. package/src/components/ReportBody/styles.scss +1 -1
  47. package/src/components/ReportCategories/index.tsx +26 -0
  48. package/src/components/ReportCategories/styles.scss +55 -0
  49. package/src/components/ReportFilters/CategoriesFilter.tsx +41 -0
  50. package/src/components/ReportFilters/index.tsx +12 -1
  51. package/src/components/SplitLayout/index.tsx +4 -2
  52. package/src/components/SplitLayout/styles.scss +1 -0
  53. package/src/components/TestResult/TrInfo/index.tsx +8 -1
  54. package/src/components/TestResult/TrInfo/styles.scss +4 -0
  55. package/src/components/TestResult/TrSeverity/index.tsx +13 -4
  56. package/src/components/TestResult/TrSeverity/styles.scss +1 -0
  57. package/src/components/TestResult/TrTabs/index.tsx +5 -0
  58. package/src/index.tsx +6 -2
  59. package/src/locales/az.json +106 -78
  60. package/src/locales/de.json +23 -3
  61. package/src/locales/en.json +23 -3
  62. package/src/locales/es.json +23 -3
  63. package/src/locales/fr.json +23 -3
  64. package/src/locales/he.json +23 -3
  65. package/src/locales/hy.json +23 -3
  66. package/src/locales/it.json +23 -3
  67. package/src/locales/ja.json +23 -3
  68. package/src/locales/ka.json +23 -3
  69. package/src/locales/kr.json +23 -3
  70. package/src/locales/nl.json +23 -3
  71. package/src/locales/pl.json +23 -3
  72. package/src/locales/pt.json +23 -3
  73. package/src/locales/ru.json +23 -3
  74. package/src/locales/sv.json +23 -3
  75. package/src/locales/tr.json +23 -3
  76. package/src/locales/uk.json +23 -3
  77. package/src/locales/zh.json +23 -3
  78. package/src/stores/categories.ts +44 -0
  79. package/src/stores/router.ts +55 -3
  80. package/src/stores/testResult.ts +14 -3
  81. package/src/stores/treeFilters/actions.ts +10 -1
  82. package/src/stores/treeFilters/constants.ts +1 -0
  83. package/src/stores/treeFilters/model.ts +2 -0
  84. package/src/stores/treeFilters/store.ts +45 -0
  85. package/src/stores/treeFilters/utils.ts +10 -0
  86. package/src/stores/treeSwitcher.ts +9 -0
  87. package/src/utils/treeFilters.ts +16 -9
  88. package/test/utils/treeFilters.test.ts +39 -0
  89. package/types.d.ts +1 -0
  90. package/dist/multi/173.app-d0210ed2e64d38a2ee8e.js +0 -1
  91. package/dist/multi/174.app-d0210ed2e64d38a2ee8e.js +0 -1
  92. package/dist/multi/252.app-d0210ed2e64d38a2ee8e.js +0 -1
  93. package/dist/multi/282.app-d0210ed2e64d38a2ee8e.js +0 -1
  94. package/dist/multi/29.app-d0210ed2e64d38a2ee8e.js +0 -1
  95. package/dist/multi/416.app-d0210ed2e64d38a2ee8e.js +0 -1
  96. package/dist/multi/527.app-d0210ed2e64d38a2ee8e.js +0 -1
  97. package/dist/multi/600.app-d0210ed2e64d38a2ee8e.js +0 -1
  98. package/dist/multi/605.app-d0210ed2e64d38a2ee8e.js +0 -1
  99. package/dist/multi/638.app-d0210ed2e64d38a2ee8e.js +0 -1
  100. package/dist/multi/672.app-d0210ed2e64d38a2ee8e.js +0 -1
  101. package/dist/multi/686.app-d0210ed2e64d38a2ee8e.js +0 -1
  102. package/dist/multi/725.app-d0210ed2e64d38a2ee8e.js +0 -1
  103. package/dist/multi/741.app-d0210ed2e64d38a2ee8e.js +0 -1
  104. package/dist/multi/749.app-d0210ed2e64d38a2ee8e.js +0 -1
  105. package/dist/multi/755.app-d0210ed2e64d38a2ee8e.js +0 -1
  106. package/dist/multi/894.app-d0210ed2e64d38a2ee8e.js +0 -1
  107. package/dist/multi/943.app-d0210ed2e64d38a2ee8e.js +0 -1
  108. package/dist/multi/980.app-d0210ed2e64d38a2ee8e.js +0 -1
  109. package/dist/multi/app-d0210ed2e64d38a2ee8e.js +0 -2
  110. package/dist/single/app-01fed10ad5f9083fd39c.js +0 -2
  111. package/src/components/SectionTabs/index.tsx +0 -0
  112. /package/dist/multi/{app-d0210ed2e64d38a2ee8e.js.LICENSE.txt → app-8be6acc0a596a2197dbf.js.LICENSE.txt} +0 -0
  113. /package/dist/single/{app-01fed10ad5f9083fd39c.js.LICENSE.txt → app-8221eb856e47b4ef50d6.js.LICENSE.txt} +0 -0
@@ -0,0 +1,71 @@
1
+ import type { CategoryNode, CategoryNodeProps, Statistic } from "@allurereport/core-api";
2
+ import { IconButton, TooltipWrapper, TreeHeader, allureIcons } from "@allurereport/web-components";
3
+ import clsx from "clsx";
4
+ import type { ComponentChildren } from "preact";
5
+ import type { FC } from "preact/compat";
6
+ import { createCategoriesStickyStyle } from "@/components/Categories/sticky";
7
+ import { useI18n } from "@/stores/locale";
8
+ import { copyToClipboard } from "@/utils/copyToClipboard";
9
+ import * as styles from "./styles.scss";
10
+
11
+ type HistoryTreeItemProps = CategoryNodeProps & {
12
+ node: CategoryNode;
13
+ isOpened: boolean;
14
+ onToggle: () => void;
15
+ children: ComponentChildren;
16
+ depth: number;
17
+ subtreeToggle?: ComponentChildren;
18
+ reportStatistic?: Statistic;
19
+ };
20
+
21
+ export const HistoryTreeItem: FC<HistoryTreeItemProps> = ({
22
+ node,
23
+ nodeId,
24
+ isOpened,
25
+ onToggle,
26
+ children,
27
+ depth,
28
+ subtreeToggle,
29
+ reportStatistic,
30
+ }) => {
31
+ const { t } = useI18n("controls");
32
+ const stickyStyle = createCategoriesStickyStyle(depth);
33
+ const categoryTitle = (
34
+ <div className={styles["tree-item-history-title"]}>
35
+ <div className={styles["tree-item-history-main"]}>
36
+ <span className={styles["tree-item-history-name"]}>{node.name}</span>
37
+ {node.historyId && (
38
+ <span className={styles["tree-item-history-copy"]}>
39
+ <TooltipWrapper tooltipText={t("clipboard")} tooltipTextAfterClick={t("clipboardSuccess")}>
40
+ <IconButton
41
+ style={"ghost"}
42
+ size={"s"}
43
+ icon={allureIcons.lineGeneralCopy3}
44
+ onClick={(event) => {
45
+ event.stopPropagation();
46
+ copyToClipboard(node.historyId ?? "");
47
+ }}
48
+ />
49
+ </TooltipWrapper>
50
+ </span>
51
+ )}
52
+ </div>
53
+ {subtreeToggle}
54
+ </div>
55
+ );
56
+ return (
57
+ <div className={clsx(styles["tree-content"], styles["tree-item-history"])} id={nodeId}>
58
+ <TreeHeader
59
+ categoryTitle={categoryTitle}
60
+ isOpened={isOpened}
61
+ toggleTree={onToggle}
62
+ data-tree-header
63
+ style={stickyStyle}
64
+ statistic={node.statistic}
65
+ reportStatistic={reportStatistic}
66
+ statusFilter={"total"}
67
+ />
68
+ {isOpened && children}
69
+ </div>
70
+ );
71
+ };
@@ -0,0 +1,53 @@
1
+ .tree-content {
2
+ padding-left: 24px;
3
+ }
4
+
5
+ .tree-item-history {
6
+ padding: 0;
7
+ background: var(--bg-base-primary);
8
+ }
9
+
10
+ .tree-item-history :global(.styles_tree-section-title) {
11
+ display: flex;
12
+ align-items: center;
13
+ flex: 1 1 auto;
14
+ min-width: 0;
15
+ margin-right: 8px;
16
+ }
17
+
18
+ .tree-item-history-title {
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 6px;
22
+ width: 100%;
23
+ }
24
+
25
+ .tree-item-history-main {
26
+ display: inline-flex;
27
+ align-items: center;
28
+ gap: 6px;
29
+ flex: 1 1 auto;
30
+ min-width: 0;
31
+ overflow: hidden;
32
+ }
33
+
34
+ .tree-item-history-name {
35
+ color: var(--on-text-primary);
36
+ flex: 1 1 auto;
37
+ min-width: 0;
38
+ overflow: hidden;
39
+ text-overflow: ellipsis;
40
+ white-space: nowrap;
41
+ }
42
+
43
+ .tree-item-history-copy {
44
+ display: inline-flex;
45
+ align-items: center;
46
+ opacity: 0;
47
+ transition: opacity 200ms;
48
+ }
49
+
50
+ .tree-item-history-title:hover .tree-item-history-copy {
51
+ opacity: 1;
52
+ }
53
+
@@ -0,0 +1,150 @@
1
+ import type {
2
+ CategoryNode,
3
+ CategoryNodeProps,
4
+ Statistic,
5
+ TestStatus,
6
+ TestStatusTransition,
7
+ } from "@allurereport/core-api";
8
+ import { capitalize } from "@allurereport/core-api";
9
+ import { SvgIcon, Text, TreeItemIcon, allureIcons } from "@allurereport/web-components";
10
+ import clsx from "clsx";
11
+ import type { ComponentChildren } from "preact";
12
+ import type { FC } from "preact/compat";
13
+ import { GroupTreeItem } from "@/components/Categories/GroupTreeItem";
14
+ import { TrStatus } from "@/components/TestResult/TrStatus";
15
+ import { useI18n } from "@/stores";
16
+ import * as styles from "./styles.scss";
17
+
18
+ type LabelTreeItemProps = CategoryNodeProps & {
19
+ node: CategoryNode;
20
+ isOpened: boolean;
21
+ onToggle: () => void;
22
+ children: ComponentChildren;
23
+ depth: number;
24
+ subtreeToggle?: ComponentChildren;
25
+ reportStatistic?: Statistic;
26
+ };
27
+
28
+ export const LabelTreeItem: FC<LabelTreeItemProps> = ({
29
+ node,
30
+ nodeId,
31
+ store,
32
+ isOpened,
33
+ onToggle,
34
+ children,
35
+ depth,
36
+ subtreeToggle,
37
+ reportStatistic,
38
+ }) => {
39
+ const { t: tTransitions } = useI18n("transitions");
40
+ const { t: tEnvironments } = useI18n("environments");
41
+ const { t: tFilters } = useI18n("filters");
42
+ const { t: tEmpty } = useI18n("empty");
43
+ const transitionIcons: Partial<Record<TestStatusTransition, string>> = {
44
+ new: allureIcons.lineAlertsNew,
45
+ fixed: allureIcons.lineAlertsFixed,
46
+ regressed: allureIcons.lineAlertsRegressed,
47
+ malfunctioned: allureIcons.lineAlertsMalfunctioned,
48
+ };
49
+ const keyLabels: Partial<Record<string, string>> = {
50
+ owner: tFilters("owner"),
51
+ layer: tFilters("layer"),
52
+ severity: tFilters("severity"),
53
+ status: tFilters("status"),
54
+ transition: tFilters("transition"),
55
+ flaky: tFilters("flaky"),
56
+ environment: tEnvironments("environment", { count: 1 }),
57
+ };
58
+ const keyLabel = node.key ? (keyLabels[node.key] ?? node.key) : node.key;
59
+ const emptyKeyByGroup: Partial<Record<string, string>> = {
60
+ transition: "no-transition",
61
+ layer: "no-layer",
62
+ owner: "no-owner",
63
+ severity: "no-severity",
64
+ status: "no-status",
65
+ environment: "no-environment",
66
+ flaky: "no-flaky",
67
+ };
68
+ const emptyValueLabel = node.key ? tEmpty(emptyKeyByGroup[node.key] ?? "no-value") : tEmpty("no-value");
69
+ const value = node.value === "<Empty>" ? emptyValueLabel : (node.value ?? "");
70
+ const isStatusGroup = node.key === "status";
71
+ const isTransitionGroup = node.key === "transition";
72
+ const isFlakyGroup = node.key === "flaky";
73
+ const statusLabelValue = node.value === "<Empty>" ? "unknown" : (node.value ?? "unknown");
74
+ const statusValue = node.key === "status" ? (node.value ?? "") : "";
75
+ const transitionValue = node.key === "transition" ? (node.value ?? "") : "";
76
+ const statusIcon = statusValue && statusValue !== "<Empty>" ? (statusValue as TestStatus) : undefined;
77
+ const transitionIcon =
78
+ transitionValue && transitionValue !== "<Empty>"
79
+ ? transitionIcons[transitionValue as TestStatusTransition]
80
+ : undefined;
81
+ const transitionLabel =
82
+ transitionValue === "<Empty>"
83
+ ? tEmpty("no-transition")
84
+ : transitionValue
85
+ ? (tTransitions(transitionValue) ?? transitionValue)
86
+ : transitionValue;
87
+ const isFlakyValue = node.value === true || node.value === "true";
88
+ const flakyLabel =
89
+ node.value === "<Empty>" ? tEmpty("no-flaky") : isFlakyValue ? tFilters("flaky") : tFilters("nonFlaky");
90
+ const flakyIcon = isFlakyValue ? allureIcons.lineIconBomb2 : undefined;
91
+ return (
92
+ <GroupTreeItem
93
+ node={node}
94
+ nodeId={nodeId}
95
+ store={store}
96
+ isOpened={isOpened}
97
+ onToggle={onToggle}
98
+ depth={depth}
99
+ subtreeToggle={subtreeToggle}
100
+ reportStatistic={reportStatistic}
101
+ className={clsx(
102
+ styles["tree-item-label"],
103
+ isStatusGroup && styles["tree-item-label-status"],
104
+ isTransitionGroup && styles["tree-item-label-transition"],
105
+ isFlakyGroup && styles["tree-item-label-flaky"],
106
+ )}
107
+ title={
108
+ isStatusGroup ? (
109
+ <div className={styles["tree-item-label-status-title"]}>
110
+ <TrStatus status={statusLabelValue as TestStatus} />
111
+ </div>
112
+ ) : isTransitionGroup ? (
113
+ <div className={styles["tree-item-label-transition-title"]}>
114
+ {transitionIcon && <SvgIcon id={transitionIcon} className={styles["tree-item-label-transition-icon"]} />}
115
+ <Text size="m" className={styles["tree-item-label-transition-text"]}>
116
+ {capitalize(transitionLabel ?? "")}
117
+ </Text>
118
+ </div>
119
+ ) : isFlakyGroup ? (
120
+ <div className={styles["tree-item-label-flaky-title"]}>
121
+ {flakyIcon && <SvgIcon id={flakyIcon} className={styles["tree-item-label-flaky-icon"]} />}
122
+ <Text size="m" className={styles["tree-item-label-flaky-text"]}>
123
+ {flakyLabel}
124
+ </Text>
125
+ </div>
126
+ ) : (
127
+ <div className={styles["tree-item-label-row"]}>
128
+ <Text type={"ui"} size="m" className={styles["tree-item-label-key"]}>
129
+ {keyLabel}
130
+ </Text>
131
+ <div className={styles["tree-item-label-values"]}>
132
+ <div className={styles["tree-item-label-bubble"]}>
133
+ {statusIcon ? (
134
+ <TreeItemIcon status={statusIcon} className={styles["tree-item-label-icon"]} />
135
+ ) : transitionIcon ? (
136
+ <SvgIcon id={transitionIcon} className={styles["tree-item-label-transition-icon"]} />
137
+ ) : null}
138
+ <Text size="m" bold className={styles["tree-item-label-value-text"]}>
139
+ {value}
140
+ </Text>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ )
145
+ }
146
+ >
147
+ {children}
148
+ </GroupTreeItem>
149
+ );
150
+ };
@@ -0,0 +1,102 @@
1
+ .tree-item-label {
2
+ padding: 0;
3
+ border-top: 1px solid var(--on-border-muted);
4
+ }
5
+
6
+ .tree-item-label-status {
7
+ :global(.styles_tree-section-title) {
8
+ display: flex;
9
+ align-items: center;
10
+ }
11
+ }
12
+
13
+ .tree-item-label-status-title {
14
+ display: inline-flex;
15
+ align-items: center;
16
+ gap: 8px;
17
+ }
18
+
19
+ .tree-item-label-transition {
20
+ :global(.styles_tree-section-title) {
21
+ display: flex;
22
+ align-items: center;
23
+ }
24
+ }
25
+
26
+ .tree-item-label-transition-title {
27
+ display: inline-flex;
28
+ align-items: center;
29
+ gap: 8px;
30
+ }
31
+
32
+ .tree-item-label-transition-text {
33
+ font-weight: 600;
34
+ }
35
+
36
+ .tree-item-label-flaky {
37
+ :global(.styles_tree-section-title) {
38
+ display: flex;
39
+ align-items: center;
40
+ }
41
+ }
42
+
43
+ .tree-item-label-flaky-title {
44
+ display: inline-flex;
45
+ align-items: center;
46
+ gap: 8px;
47
+ }
48
+
49
+ .tree-item-label-flaky-text {
50
+ font-weight: 600;
51
+ }
52
+
53
+ .tree-item-label-flaky-icon {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ color: currentColor;
57
+ }
58
+
59
+ .tree-item-label-row {
60
+ display: flex;
61
+ gap: 16px;
62
+ align-items: center;
63
+ }
64
+
65
+ .tree-item-label-key {
66
+ padding: 4px 0;
67
+ }
68
+
69
+ .tree-item-label-values {
70
+ display: flex;
71
+ gap: 6px;
72
+ align-items: center;
73
+ }
74
+
75
+ .tree-item-label-bubble {
76
+ background: var(--on-border-primary);
77
+ border-radius: 4px;
78
+ padding: 2px 4px;
79
+ line-height: 16px;
80
+ display: inline-flex;
81
+ align-items: center;
82
+ gap: 4px;
83
+ max-width: 100%;
84
+ }
85
+
86
+ .tree-item-label-icon {
87
+ margin-right: 2px;
88
+ }
89
+
90
+ .tree-item-label-transition-icon {
91
+ display: inline-flex;
92
+ align-items: center;
93
+ color: currentColor;
94
+ }
95
+
96
+ .tree-item-label-value-text {
97
+ width: max-content;
98
+ height: max-content;
99
+ overflow: hidden;
100
+ white-space: nowrap;
101
+ text-overflow: ellipsis;
102
+ }
@@ -0,0 +1,107 @@
1
+ import type { CategoryNode, CategoryNodeProps, Statistic, TestStatus } from "@allurereport/core-api";
2
+ import { getWorstStatus } from "@allurereport/core-api";
3
+ import { ansiToHTML } from "@allurereport/web-commons";
4
+ import { ArrowButton, Button, Code, TreeStatusBar } from "@allurereport/web-components";
5
+ import clsx from "clsx";
6
+ import type { ComponentChildren } from "preact";
7
+ import type { FC } from "preact/compat";
8
+ import { useState } from "preact/hooks";
9
+ import { createCategoriesStickyStyle } from "@/components/Categories/sticky";
10
+ import { useI18n } from "@/stores/locale";
11
+ import * as styles from "./styles.scss";
12
+
13
+ type MessageTreeItemProps = CategoryNodeProps & {
14
+ node: CategoryNode;
15
+ isOpened: boolean;
16
+ onToggle: () => void;
17
+ children: ComponentChildren;
18
+ depth: number;
19
+ subtreeToggle?: ComponentChildren;
20
+ reportStatistic?: Statistic;
21
+ };
22
+
23
+ const statusFromStatistic = (stat?: Statistic): TestStatus | undefined => {
24
+ if (!stat) {
25
+ return;
26
+ }
27
+ const statuses: TestStatus[] = [];
28
+ if (stat.failed) {
29
+ statuses.push("failed");
30
+ }
31
+ if (stat.broken) {
32
+ statuses.push("broken");
33
+ }
34
+ if (stat.passed) {
35
+ statuses.push("passed");
36
+ }
37
+ if (stat.skipped) {
38
+ statuses.push("skipped");
39
+ }
40
+ if (stat.unknown) {
41
+ statuses.push("unknown");
42
+ }
43
+ return getWorstStatus(statuses);
44
+ };
45
+
46
+ export const MessageTreeItem: FC<MessageTreeItemProps> = ({
47
+ node,
48
+ nodeId,
49
+ isOpened,
50
+ onToggle,
51
+ children,
52
+ depth,
53
+ subtreeToggle,
54
+ reportStatistic,
55
+ }) => {
56
+ const { t } = useI18n("ui");
57
+ const status = statusFromStatistic(node.statistic);
58
+ const sanitizedMessage = ansiToHTML(node.name ?? "", { fg: "var(--on-text-primary)", colors: {} });
59
+ const stickyStyle = createCategoriesStickyStyle(depth);
60
+ const hasLongMessage = (node.name ?? "").length > 80;
61
+ const [isMessageExpanded, setIsMessageExpanded] = useState(false);
62
+
63
+ return (
64
+ <div className={clsx(styles["tree-content"], styles["tree-item-message"])} id={nodeId}>
65
+ <div className={styles["tree-item-message-container"]} data-tree-header style={stickyStyle} onClick={onToggle}>
66
+ <ArrowButton isOpened={isOpened} className={styles["tree-item-message-arrow"]} />
67
+ <div
68
+ className={clsx(
69
+ styles["tree-item-message-card"],
70
+ status && styles[`message-status-${status}`],
71
+ isMessageExpanded && styles["tree-item-message-card-expanded"],
72
+ )}
73
+ >
74
+ <Code
75
+ size="s"
76
+ className={clsx(
77
+ styles["tree-item-message-header"],
78
+ isMessageExpanded && styles["tree-item-message-header-expanded"],
79
+ )}
80
+ >
81
+ {/* eslint-disable-next-line react/no-danger */}
82
+ <pre dangerouslySetInnerHTML={{ __html: sanitizedMessage }} />
83
+ </Code>
84
+ <div className={styles["tree-item-message-actions"]}>
85
+ {hasLongMessage && (
86
+ <Button
87
+ size="s"
88
+ style="ghost"
89
+ text={isMessageExpanded ? t("showLess") : t("showMore")}
90
+ className={styles["tree-item-message-expand"]}
91
+ onClick={(event) => {
92
+ event.stopPropagation();
93
+ setIsMessageExpanded((value) => !value);
94
+ }}
95
+ />
96
+ )}
97
+ {subtreeToggle}
98
+ <div className={styles["tree-item-message-stats"]}>
99
+ <TreeStatusBar reportStatistic={reportStatistic} statusFilter={"total"} statistic={node.statistic} />
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ {isOpened && children}
105
+ </div>
106
+ );
107
+ };
@@ -0,0 +1,178 @@
1
+ .tree-content {
2
+ padding-left: 24px;
3
+ }
4
+
5
+ .tree-item-message {
6
+ padding: 0;
7
+ }
8
+
9
+ .tree-item-message-container {
10
+ display: flex;
11
+ gap: 8px;
12
+ align-items: center;
13
+ flex: 1 1 auto;
14
+ background: var(--bg-base-primary);
15
+ min-height: var(--tree-section-min-height, auto);
16
+ padding: 4px 0;
17
+ position: var(--tree-section-position, relative);
18
+ top: var(--tree-section-top, auto);
19
+ transition: background-color 0.3s;
20
+ z-index: var(--tree-section-z, auto);
21
+ }
22
+
23
+ .tree-item-message-card {
24
+ width: 100%;
25
+ padding: 4px 8px 4px 16px;
26
+ border-radius: 4px;
27
+ background-color: var(--bg-alpha-capella);
28
+ position: relative;
29
+ overflow: hidden;
30
+ text-overflow: ellipsis;
31
+ display: flex;
32
+ align-items: flex-start;
33
+
34
+ &:before {
35
+ content: "";
36
+ display: block;
37
+ height: 100%;
38
+ width: 2px;
39
+ position: absolute;
40
+ left: 0;
41
+ top: 0;
42
+ background-color: var(--bg-support-capella);
43
+ }
44
+ }
45
+
46
+ .tree-item-message-card-expanded {
47
+ overflow: visible;
48
+ }
49
+
50
+ .tree-item-message-header {
51
+ display: flex;
52
+ gap: 4px;
53
+ cursor: pointer;
54
+ box-sizing: border-box;
55
+ flex: 1 1 auto;
56
+ min-width: 0;
57
+ align-self: center;
58
+
59
+ pre {
60
+ white-space: nowrap;
61
+ overflow: hidden;
62
+ text-overflow: ellipsis;
63
+ }
64
+ }
65
+
66
+ .tree-item-message-header-expanded {
67
+ pre {
68
+ white-space: pre-wrap;
69
+ overflow: visible;
70
+ text-overflow: unset;
71
+ word-break: break-word;
72
+ }
73
+ }
74
+
75
+ .tree-item-message-arrow {
76
+ margin-left: 0;
77
+ }
78
+
79
+ .tree-item-message-title {
80
+ padding-left: 8px;
81
+ margin-right: auto;
82
+ }
83
+
84
+ .tree-item-message-actions {
85
+ margin-left: auto;
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 8px;
89
+ }
90
+
91
+ .tree-item-message-expand {
92
+ flex: 0 0 auto;
93
+ opacity: 0;
94
+ pointer-events: none;
95
+ transition: opacity 200ms;
96
+ }
97
+
98
+ .tree-item-message-card:hover .tree-item-message-expand {
99
+ opacity: 1;
100
+ pointer-events: auto;
101
+ }
102
+
103
+ .tree-item-message-actions .tree-item-subtree-toggle {
104
+ margin-left: 0;
105
+ }
106
+
107
+ .tree-item-message-stats {
108
+ display: flex;
109
+ align-items: center;
110
+ margin-left: 24px;
111
+ }
112
+
113
+ .tree-item-message-body {
114
+ padding: 8px;
115
+ border-radius: 8px;
116
+ cursor: pointer;
117
+ transition: background-color 300ms;
118
+ margin-bottom: 4px;
119
+
120
+ &:hover {
121
+ background: inherit;
122
+ }
123
+ }
124
+
125
+ .message-status-failed {
126
+ background-color: var(--bg-alpha-capella);
127
+ &:before {
128
+ background-color: var(--bg-support-capella);
129
+ }
130
+ }
131
+
132
+ .message-status-broken {
133
+ background-color: var(--bg-alpha-atlas);
134
+ &:before {
135
+ background-color: var(--bg-support-atlas);
136
+ }
137
+ }
138
+
139
+ .message-status-skipped {
140
+ background-color: var(--bg-alpha-rau);
141
+ &:before {
142
+ background-color: var(--bg-support-rau);
143
+ }
144
+ }
145
+
146
+ .message-status-unknown {
147
+ background-color: var(--bg-alpha-skat);
148
+ &:before {
149
+ background-color: var(--bg-support-skat);
150
+ }
151
+ }
152
+
153
+ .message-status-passed {
154
+ background-color: var(--bg-alpha-castor);
155
+ &:before {
156
+ background-color: var(--bg-support-castor);
157
+ }
158
+ }
159
+
160
+ .message-color-failed {
161
+ color: var(--on-support-capella);
162
+ }
163
+
164
+ .message-color-broken {
165
+ color: var(--on-support-atlas);
166
+ }
167
+
168
+ .message-color-skipped {
169
+ color: var(--on-support-rau);
170
+ }
171
+
172
+ .message-color-passed {
173
+ color: var(--on-support-castor);
174
+ }
175
+
176
+ .message-color-unknown {
177
+ color: var(--on-support-skat);
178
+ }
@@ -0,0 +1,50 @@
1
+ import type { CategoryNode, CategoryNodeProps, Statistic } from "@allurereport/core-api";
2
+ import type { ComponentChildren } from "preact";
3
+ import type { FC } from "preact/compat";
4
+ import { GroupTreeItem } from "@/components/Categories/GroupTreeItem";
5
+ import { TrSeverity } from "@/components/TestResult/TrSeverity";
6
+ import * as styles from "./styles.scss";
7
+
8
+ type SeverityTreeItemProps = CategoryNodeProps & {
9
+ node: CategoryNode;
10
+ isOpened: boolean;
11
+ onToggle: () => void;
12
+ children: ComponentChildren;
13
+ depth: number;
14
+ subtreeToggle?: ComponentChildren;
15
+ reportStatistic?: Statistic;
16
+ };
17
+
18
+ export const SeverityTreeItem: FC<SeverityTreeItemProps> = ({
19
+ node,
20
+ nodeId,
21
+ store,
22
+ isOpened,
23
+ onToggle,
24
+ children,
25
+ depth,
26
+ subtreeToggle,
27
+ reportStatistic,
28
+ }) => {
29
+ const severityValue = node.value === "<Empty>" ? "normal" : (node.value ?? "normal");
30
+ return (
31
+ <GroupTreeItem
32
+ node={node}
33
+ nodeId={nodeId}
34
+ store={store}
35
+ isOpened={isOpened}
36
+ onToggle={onToggle}
37
+ depth={depth}
38
+ subtreeToggle={subtreeToggle}
39
+ reportStatistic={reportStatistic}
40
+ className={styles["tree-item-severity"]}
41
+ title={
42
+ <div className={styles["tree-item-severity-title"]}>
43
+ <TrSeverity severity={severityValue} size="m" />
44
+ </div>
45
+ }
46
+ >
47
+ {children}
48
+ </GroupTreeItem>
49
+ );
50
+ };