@allurereport/web-awesome 3.0.0-beta.4 → 3.0.0-beta.6
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.
- package/.eslintrc.cjs +1 -1
- package/CONTRIBUTING.md +34 -0
- package/dist/multi/141.app-07a6d2ea.js +1 -0
- package/dist/multi/222.app-07a6d2ea.js +1 -0
- package/dist/multi/335.app-07a6d2ea.js +1 -0
- package/dist/multi/34.app-07a6d2ea.js +1 -0
- package/dist/multi/349.app-07a6d2ea.js +1 -0
- package/dist/multi/378.app-07a6d2ea.js +1 -0
- package/dist/multi/406.app-07a6d2ea.js +1 -0
- package/dist/multi/476.app-07a6d2ea.js +1 -0
- package/dist/multi/53.app-07a6d2ea.js +1 -0
- package/dist/multi/584.app-07a6d2ea.js +1 -0
- package/dist/multi/690.app-07a6d2ea.js +1 -0
- package/dist/multi/747.app-07a6d2ea.js +1 -0
- package/dist/multi/767.app-07a6d2ea.js +1 -0
- package/dist/multi/{816.app-13f840d5.js → 816.app-07a6d2ea.js} +1 -1
- package/dist/multi/83.app-07a6d2ea.js +1 -0
- package/dist/multi/873.app-07a6d2ea.js +1 -0
- package/dist/multi/920.app-07a6d2ea.js +1 -0
- package/dist/multi/991.app-07a6d2ea.js +1 -0
- package/dist/multi/app-07a6d2ea.js +2 -0
- package/dist/multi/manifest.json +20 -20
- package/dist/multi/{styles-13f840d5.css → styles-07a6d2ea.css} +7 -7
- package/dist/single/app-c2627b69.js +2 -0
- package/dist/single/manifest.json +1 -1
- package/package.json +11 -4
- package/src/assets/svg/line-alerts-alert-circle.svg +12 -0
- package/src/assets/svg/line-general-eye.svg +7 -0
- package/src/assets/svg/line-icon-bomb-2.svg +12 -0
- package/src/components/app/ArrowButton/index.tsx +3 -2
- package/src/components/app/ArrowButton/styles.scss +3 -0
- package/src/components/app/BaseLayout/index.tsx +5 -5
- package/src/components/app/ReportBody/Filters.tsx +12 -10
- package/src/components/app/ReportBody/HeaderActions.tsx +3 -3
- package/src/components/app/ReportBody/SortBy.tsx +8 -8
- package/src/components/app/ReportBody/context.tsx +0 -1
- package/src/components/app/ReportMetadata/MetadataSummary.tsx +22 -18
- package/src/components/app/ReportMetadata/MetadataWithIcon.tsx +2 -2
- package/src/components/app/Tabs/index.tsx +2 -3
- package/src/components/app/TestResult/TestResultDescription/index.tsx +3 -3
- package/src/components/app/TestResult/TestResultError/index.tsx +18 -16
- package/src/components/app/TestResult/TestResultError/styles.scss +16 -5
- package/src/components/app/TestResult/TestResultHeader/index.tsx +2 -2
- package/src/components/app/TestResult/TestResultHistory/TestResultHistoryItem.tsx +21 -10
- package/src/components/app/TestResult/TestResultInfo/TestResultInfoStatuses.tsx +31 -0
- package/src/components/app/TestResult/TestResultInfo/index.tsx +6 -4
- package/src/components/app/TestResult/TestResultInfo/styles.scss +17 -0
- package/src/components/app/TestResult/TestResultNavigation/index.tsx +34 -38
- package/src/components/app/TestResult/TestResultNavigation/styles.scss +1 -1
- package/src/components/app/TestResult/TestResultPrevStatuses/index.tsx +6 -6
- package/src/components/app/TestResult/TestResultSteps/attachment.tsx +4 -6
- package/src/components/app/TestResult/TestResultTeardown/index.tsx +2 -2
- package/src/components/app/TestResult/index.tsx +2 -2
- package/src/components/app/Tree/Tree.tsx +54 -101
- package/src/components/app/Tree/TreeHeader.tsx +13 -12
- package/src/components/app/Tree/TreeItem.tsx +5 -1
- package/src/components/app/Tree/index.tsx +31 -7
- package/src/components/app/Tree/styles.scss +16 -4
- package/src/components/commons/Button/styles.scss +6 -4
- package/src/components/commons/Menu/index.tsx +4 -4
- package/src/components/commons/SearchBox/index.tsx +8 -6
- package/src/components/commons/Toggle/index.tsx +2 -1
- package/src/components/commons/Tooltip/index.tsx +3 -3
- package/src/i18n/constants.ts +23 -4
- package/src/i18n/locales/am.json +5 -2
- package/src/i18n/locales/az.json +5 -2
- package/src/i18n/locales/de.json +5 -2
- package/src/i18n/locales/en.json +6 -3
- package/src/i18n/locales/es.json +5 -1
- package/src/i18n/locales/fr.json +5 -2
- package/src/i18n/locales/he.json +5 -2
- package/src/i18n/locales/it.json +5 -2
- package/src/i18n/locales/ja.json +5 -2
- package/src/i18n/locales/ka.json +5 -2
- package/src/i18n/locales/kr.json +5 -2
- package/src/i18n/locales/nl.json +5 -2
- package/src/i18n/locales/pl.json +5 -2
- package/src/i18n/locales/pt.json +5 -2
- package/src/i18n/locales/ru.json +5 -2
- package/src/i18n/locales/sv.json +5 -2
- package/src/i18n/locales/tr.json +5 -2
- package/src/i18n/locales/zh.json +6 -3
- package/src/index.html +1 -0
- package/src/index.tsx +4 -0
- package/src/stores/chart.ts +2 -2
- package/src/stores/stats.ts +1 -1
- package/src/stores/testResults.ts +26 -4
- package/src/stores/tree.ts +98 -4
- package/src/types/globals.d.ts +6 -1
- package/src/utils/copyToClipboard.ts +14 -1
- package/src/utils/treeFilters.ts +73 -120
- package/test/utils/treeFilters.test.ts +424 -0
- package/types.d.ts +25 -4
- package/vitest.config.ts +12 -0
- package/dist/multi/141.app-13f840d5.js +0 -1
- package/dist/multi/222.app-13f840d5.js +0 -1
- package/dist/multi/335.app-13f840d5.js +0 -1
- package/dist/multi/34.app-13f840d5.js +0 -1
- package/dist/multi/349.app-13f840d5.js +0 -1
- package/dist/multi/378.app-13f840d5.js +0 -1
- package/dist/multi/406.app-13f840d5.js +0 -1
- package/dist/multi/476.app-13f840d5.js +0 -1
- package/dist/multi/53.app-13f840d5.js +0 -1
- package/dist/multi/584.app-13f840d5.js +0 -1
- package/dist/multi/690.app-13f840d5.js +0 -1
- package/dist/multi/747.app-13f840d5.js +0 -1
- package/dist/multi/767.app-13f840d5.js +0 -1
- package/dist/multi/83.app-13f840d5.js +0 -1
- package/dist/multi/873.app-13f840d5.js +0 -1
- package/dist/multi/920.app-13f840d5.js +0 -1
- package/dist/multi/991.app-13f840d5.js +0 -1
- package/dist/multi/app-13f840d5.js +0 -2
- package/dist/single/app-d31bd53e.js +0 -2
- /package/dist/multi/{app-13f840d5.js.LICENSE.txt → app-07a6d2ea.js.LICENSE.txt} +0 -0
- /package/dist/single/{app-d31bd53e.js.LICENSE.txt → app-c2627b69.js.LICENSE.txt} +0 -0
|
@@ -9,6 +9,30 @@ export const testResultStore = signal<StoreSignalState<Record<string, AllureAwes
|
|
|
9
9
|
data: undefined,
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
+
export const testResultNavStore = signal<StoreSignalState<string[]>>({
|
|
13
|
+
loading: true,
|
|
14
|
+
error: undefined,
|
|
15
|
+
data: undefined,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const fetchTestResultNav = async () => {
|
|
19
|
+
try {
|
|
20
|
+
const data = await fetchReportJsonData<string[]>("widgets/nav.json");
|
|
21
|
+
|
|
22
|
+
testResultNavStore.value = {
|
|
23
|
+
data,
|
|
24
|
+
error: undefined,
|
|
25
|
+
loading: false,
|
|
26
|
+
};
|
|
27
|
+
} catch (err) {
|
|
28
|
+
testResultNavStore.value = {
|
|
29
|
+
...testResultNavStore.value,
|
|
30
|
+
error: err.message,
|
|
31
|
+
loading: false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
12
36
|
export const fetchTestResult = async (testResultId: string) => {
|
|
13
37
|
if (!testResultId || testResultStore.value.data?.[testResultId]) {
|
|
14
38
|
return;
|
|
@@ -18,12 +42,10 @@ export const fetchTestResult = async (testResultId: string) => {
|
|
|
18
42
|
...testResultStore.value,
|
|
19
43
|
loading: true,
|
|
20
44
|
error: undefined,
|
|
21
|
-
}
|
|
45
|
+
};
|
|
22
46
|
|
|
23
47
|
try {
|
|
24
|
-
const data = await fetchReportJsonData<AllureAwesomeTestResult>(
|
|
25
|
-
`data/test-results/${testResultId}.json`,
|
|
26
|
-
);
|
|
48
|
+
const data = await fetchReportJsonData<AllureAwesomeTestResult>(`data/test-results/${testResultId}.json`);
|
|
27
49
|
|
|
28
50
|
testResultStore.value = {
|
|
29
51
|
data: { ...testResultStore.value.data, [testResultId]: data },
|
package/src/stores/tree.ts
CHANGED
|
@@ -1,14 +1,108 @@
|
|
|
1
1
|
import { fetchReportJsonData } from "@allurereport/web-commons";
|
|
2
|
-
import { signal } from "@preact/signals";
|
|
2
|
+
import { computed, signal } from "@preact/signals";
|
|
3
3
|
import type { StoreSignalState } from "@/stores/types";
|
|
4
|
+
import { createRecursiveTree, isRecursiveTreeEmpty } from "@/utils/treeFilters";
|
|
5
|
+
import type {AllureAwesomeStatus, AllureAwesomeTree, AllureAwesomeTreeGroup} from "../../types";
|
|
4
6
|
|
|
5
|
-
export
|
|
7
|
+
export type TreeSortBy = "order" | "duration" | "status" | "alphabet";
|
|
8
|
+
export type TreeDirection = "asc" | "desc";
|
|
9
|
+
export type TreeFilters = "flaky" | "retry" | "new";
|
|
10
|
+
export type TreeFiltersState = {
|
|
11
|
+
query: string;
|
|
12
|
+
status: AllureAwesomeStatus;
|
|
13
|
+
filter: Record<TreeFilters, boolean>;
|
|
14
|
+
sortBy: TreeSortBy;
|
|
15
|
+
direction: TreeDirection;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const treeStore = signal<StoreSignalState<AllureAwesomeTree>>({
|
|
6
19
|
loading: true,
|
|
7
20
|
error: undefined,
|
|
8
21
|
data: undefined,
|
|
9
22
|
});
|
|
10
23
|
|
|
11
|
-
export const
|
|
24
|
+
export const noTests = computed(() => !Object.keys(treeStore?.value?.data?.leavesById).length);
|
|
25
|
+
|
|
26
|
+
export const treeFiltersStore = signal<TreeFiltersState>({
|
|
27
|
+
query: "",
|
|
28
|
+
status: "total",
|
|
29
|
+
filter: {
|
|
30
|
+
flaky: false,
|
|
31
|
+
retry: false,
|
|
32
|
+
new: false,
|
|
33
|
+
},
|
|
34
|
+
sortBy: "order",
|
|
35
|
+
direction: "asc",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const filteredTree = computed(() => {
|
|
39
|
+
const { root, leavesById, groupsById } = treeStore.value.data;
|
|
40
|
+
|
|
41
|
+
return createRecursiveTree({
|
|
42
|
+
group: root as AllureAwesomeTreeGroup,
|
|
43
|
+
leavesById,
|
|
44
|
+
groupsById,
|
|
45
|
+
filterOptions: treeFiltersStore.value,
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const noTestsFound = computed(() => {
|
|
50
|
+
return isRecursiveTreeEmpty(filteredTree.value);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export const clearTreeFilters = () => {
|
|
54
|
+
treeFiltersStore.value = {
|
|
55
|
+
query: "",
|
|
56
|
+
status: "total",
|
|
57
|
+
filter: {
|
|
58
|
+
flaky: false,
|
|
59
|
+
retry: false,
|
|
60
|
+
new: false,
|
|
61
|
+
},
|
|
62
|
+
sortBy: "order",
|
|
63
|
+
direction: "asc",
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const setTreeQuery = (query: string) => {
|
|
68
|
+
treeFiltersStore.value = {
|
|
69
|
+
...treeFiltersStore.value,
|
|
70
|
+
query,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const setTreeStatus = (status: AllureAwesomeStatus) => {
|
|
75
|
+
treeFiltersStore.value = {
|
|
76
|
+
...treeFiltersStore.value,
|
|
77
|
+
status,
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const setTreeSortBy = (sortBy: TreeSortBy) => {
|
|
82
|
+
treeFiltersStore.value = {
|
|
83
|
+
...treeFiltersStore.value,
|
|
84
|
+
sortBy,
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const setTreeDirection = (direction: TreeDirection) => {
|
|
89
|
+
treeFiltersStore.value = {
|
|
90
|
+
...treeFiltersStore.value,
|
|
91
|
+
direction,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const setTreeFilter = (filterKey: TreeFilters, value: boolean) => {
|
|
96
|
+
treeFiltersStore.value = {
|
|
97
|
+
...treeFiltersStore.value,
|
|
98
|
+
filter: {
|
|
99
|
+
...treeFiltersStore.value.filter,
|
|
100
|
+
[filterKey]: value,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const fetchTreeData = async () => {
|
|
12
106
|
treeStore.value = {
|
|
13
107
|
...treeStore.value,
|
|
14
108
|
loading: true,
|
|
@@ -16,7 +110,7 @@ export const fetchTreeData = async (treeName: string) => {
|
|
|
16
110
|
};
|
|
17
111
|
|
|
18
112
|
try {
|
|
19
|
-
const res = await fetchReportJsonData(
|
|
113
|
+
const res = await fetchReportJsonData<AllureAwesomeTree>("widgets/tree.json");
|
|
20
114
|
|
|
21
115
|
treeStore.value = {
|
|
22
116
|
data: res,
|
package/src/types/globals.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
export const copyToClipboard = async (text: string) => {
|
|
2
|
-
|
|
2
|
+
if (navigator.clipboard) {
|
|
3
|
+
await navigator.clipboard.writeText(text);
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const textarea = document.createElement("textarea");
|
|
8
|
+
textarea.value = text;
|
|
9
|
+
textarea.style.position = "fixed";
|
|
10
|
+
textarea.style.opacity = "0";
|
|
11
|
+
document.body.appendChild(textarea);
|
|
12
|
+
textarea.focus();
|
|
13
|
+
textarea.select();
|
|
14
|
+
document.execCommand("copy");
|
|
15
|
+
document.body.removeChild(textarea);
|
|
3
16
|
};
|
package/src/utils/treeFilters.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { TreeFiltersState } from "@/stores/tree";
|
|
2
|
+
import type { AllureAwesomeRecursiveTree, AllureAwesomeTree, AllureAwesomeTreeGroup } from "../../types";
|
|
3
3
|
|
|
4
4
|
const statusOrder = {
|
|
5
5
|
failed: 1,
|
|
@@ -9,142 +9,95 @@ const statusOrder = {
|
|
|
9
9
|
unknown: 5,
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
leaves,
|
|
14
|
-
leavesById,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
export const filterLeaves = (
|
|
13
|
+
leaves: string[] = [],
|
|
14
|
+
leavesById: AllureAwesomeTree["leavesById"],
|
|
15
|
+
filterOptions?: TreeFiltersState,
|
|
16
|
+
) => {
|
|
17
|
+
const filteredLeaves = [...leaves]
|
|
18
|
+
.map((leafId) => leavesById[leafId])
|
|
19
|
+
.filter((leaf) => {
|
|
20
|
+
const queryMatched = !filterOptions?.query || leaf.name.toLowerCase().includes(filterOptions.query.toLowerCase());
|
|
21
|
+
const statusMatched =
|
|
22
|
+
!filterOptions?.status || filterOptions?.status === "total" || leaf.status === filterOptions.status;
|
|
23
|
+
const flakyMatched = !filterOptions?.filter?.flaky || leaf.flaky;
|
|
24
|
+
const retryMatched = !filterOptions?.filter?.retry || leaf.retry;
|
|
25
|
+
// TODO: at this moment we don't have a new field implementation even in the generator
|
|
26
|
+
// const newMatched = !filterOptions?.filter?.new || leaf.new;
|
|
27
|
+
|
|
28
|
+
return [queryMatched, statusMatched, flakyMatched, retryMatched].every(Boolean);
|
|
29
|
+
});
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
if (!filterOptions) {
|
|
32
|
+
return filteredLeaves;
|
|
33
|
+
}
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
leavesById,
|
|
32
|
-
filterOptions,
|
|
33
|
-
}: {
|
|
34
|
-
leavesFiltered: string[];
|
|
35
|
-
leavesById: DefaultTreeData["leavesById"];
|
|
36
|
-
filterOptions: ReportContentContextValue;
|
|
37
|
-
}) => {
|
|
38
|
-
leavesFiltered.sort((a, b) => {
|
|
39
|
-
const leafA = leavesById[a];
|
|
40
|
-
const leafB = leavesById[b];
|
|
41
|
-
const filterDirection = filterOptions.direction === "asc";
|
|
35
|
+
return filteredLeaves.sort((a, b) => {
|
|
36
|
+
const asc = filterOptions.direction === "asc";
|
|
42
37
|
|
|
43
38
|
switch (filterOptions.sortBy) {
|
|
39
|
+
case "order":
|
|
40
|
+
return asc ? a.groupOrder - b.groupOrder : b.groupOrder - a.groupOrder;
|
|
44
41
|
case "duration":
|
|
45
|
-
return
|
|
46
|
-
? (leafA.duration || 0) - (leafB.duration || 0)
|
|
47
|
-
: (leafB.duration || 0) - (leafA.duration || 0);
|
|
42
|
+
return asc ? (a.duration || 0) - (b.duration || 0) : (b.duration || 0) - (a.duration || 0);
|
|
48
43
|
case "alphabet":
|
|
49
|
-
return
|
|
44
|
+
return asc ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
|
|
50
45
|
case "status": {
|
|
51
|
-
const statusA = statusOrder[
|
|
52
|
-
const statusB = statusOrder[
|
|
53
|
-
|
|
46
|
+
const statusA = statusOrder[a.status] || statusOrder.unknown;
|
|
47
|
+
const statusB = statusOrder[b.status] || statusOrder.unknown;
|
|
48
|
+
|
|
49
|
+
return asc ? statusA - statusB : statusB - statusA;
|
|
54
50
|
}
|
|
55
51
|
default:
|
|
56
52
|
return 0;
|
|
57
53
|
}
|
|
58
54
|
});
|
|
59
|
-
|
|
60
|
-
if (filterOptions.direction === "desc" && ["order"].includes(filterOptions.sortBy as string)) {
|
|
61
|
-
leavesFiltered.reverse();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return leavesFiltered;
|
|
65
55
|
};
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Fills the given tree from generator and returns recursive tree which includes leaves data instead of their IDs
|
|
59
|
+
* Filters leaves when `filterOptions` property is provided
|
|
60
|
+
* @param payload
|
|
61
|
+
*/
|
|
62
|
+
export const createRecursiveTree = (payload: {
|
|
63
|
+
group: AllureAwesomeTreeGroup;
|
|
64
|
+
groupsById: AllureAwesomeTree["groupsById"];
|
|
65
|
+
leavesById: AllureAwesomeTree["leavesById"];
|
|
66
|
+
filterOptions?: TreeFiltersState;
|
|
67
|
+
}): AllureAwesomeRecursiveTree => {
|
|
68
|
+
const { group, groupsById, leavesById, filterOptions } = payload;
|
|
69
|
+
const groupLeaves = group.leaves ?? [];
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
...group,
|
|
73
|
+
// FIXME: don't have any idea, why eslint marks next line as unsafe because it actually has a correct type
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
75
|
+
leaves: filterLeaves(groupLeaves, leavesById, filterOptions),
|
|
76
|
+
trees: group?.groups
|
|
77
|
+
?.filter((groupId) => {
|
|
78
|
+
const subGroup = groupsById[groupId];
|
|
79
|
+
|
|
80
|
+
return subGroup?.leaves?.length || subGroup?.groups?.length;
|
|
81
|
+
})
|
|
82
|
+
?.map((groupId) =>
|
|
83
|
+
createRecursiveTree({
|
|
84
|
+
group: groupsById[groupId],
|
|
85
|
+
groupsById,
|
|
92
86
|
leavesById,
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
leavesFiltered = filterByQuery({
|
|
98
|
-
leaves: leavesFiltered,
|
|
99
|
-
leavesById,
|
|
100
|
-
query: filterOptions.query,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
leavesFiltered = filterByTestType({ leaves: leavesFiltered, leavesById, filterTypes: filterOptions.filter });
|
|
104
|
-
|
|
105
|
-
leavesFiltered = sortedLeaves({ leavesFiltered, leavesById, filterOptions });
|
|
106
|
-
|
|
107
|
-
return leavesFiltered;
|
|
87
|
+
filterOptions,
|
|
88
|
+
}),
|
|
89
|
+
),
|
|
90
|
+
};
|
|
108
91
|
};
|
|
109
92
|
|
|
110
|
-
export const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
statusFilter?: string,
|
|
115
|
-
filterOptions?: ReportContentContextValue,
|
|
116
|
-
): string[] => {
|
|
117
|
-
const gro = groups.filter((groupId) => {
|
|
118
|
-
const group = groupsById?.[groupId];
|
|
119
|
-
const groupLeaves = filterLeaves((group?.leaves as string[]) || [], leavesById, statusFilter, filterOptions);
|
|
120
|
-
const filteredSubGroups = group?.groups?.filter((subGroupId: number) => {
|
|
121
|
-
const subGroup = groupsById?.[subGroupId] as { leaves: string[]; groups: string[] };
|
|
122
|
-
return (
|
|
123
|
-
filterLeaves(subGroup?.leaves || [], leavesById, statusFilter, filterOptions).length > 0 ||
|
|
124
|
-
filterGroups(subGroup?.groups || [], groupsById, leavesById, statusFilter, filterOptions).length > 0
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
return groupLeaves.length > 0 || (filteredSubGroups && filteredSubGroups.length > 0);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const sortedGroups = gro.sort((a, b) => {
|
|
132
|
-
const leafA = groupsById[a];
|
|
133
|
-
const leafB = groupsById[b];
|
|
134
|
-
const filterDirection = filterOptions.direction === "asc";
|
|
135
|
-
|
|
136
|
-
switch (filterOptions.sortBy) {
|
|
137
|
-
case "alphabet": {
|
|
138
|
-
return filterDirection ? leafA.name.localeCompare(leafB.name) : leafB.name.localeCompare(leafA.name);
|
|
139
|
-
}
|
|
140
|
-
default:
|
|
141
|
-
return 0;
|
|
142
|
-
}
|
|
143
|
-
});
|
|
93
|
+
export const isRecursiveTreeEmpty = (tree: AllureAwesomeRecursiveTree) => {
|
|
94
|
+
if (!tree.trees?.length && !tree.leaves?.length) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
144
97
|
|
|
145
|
-
if (
|
|
146
|
-
|
|
98
|
+
if (tree.leaves?.length) {
|
|
99
|
+
return false;
|
|
147
100
|
}
|
|
148
101
|
|
|
149
|
-
return
|
|
102
|
+
return tree.trees?.every((subTree) => isRecursiveTreeEmpty(subTree));
|
|
150
103
|
};
|