@allurereport/web-allure2
Version:
The static files for Allure Classic Report
201 lines (177 loc) • 6.09 kB
JavaScript
import { View } from "backbone.marionette";
import { SEARCH_QUERY_KEY } from "@/components/node-search/NodeSearchView.js";
import getComparator from "@/data/tree/comparator.js";
import { byCriteria, byMark, byStatuses, mix } from "@/data/tree/filter.js";
import { behavior, className, on } from "@/decorators/index.js";
import router from "@/router.js";
import hotkeys from "@/utils/hotkeys.js";
import template from "./TreeView.hbs";
import "./styles.scss";
class TreeView extends View {
template = template;
cachedQuery = "";
initialize({ routeState, state, tabName, baseUrl, settings }) {
this.state = state;
this.routeState = routeState;
this.baseUrl = baseUrl;
this.tabName = tabName;
this.setState();
this.listenTo(this.routeState, "change:treeNode", this.selectNode);
this.listenTo(this.routeState, "change:testResultTab", this.render);
this.settings = settings;
this.listenTo(this.settings, "change", this.render);
this.listenTo(this.state, "change", this.handleStateChange);
this.listenTo(hotkeys, "key:up", this.onKeyUp, this);
this.listenTo(hotkeys, "key:down", this.onKeyDown, this);
this.listenTo(hotkeys, "key:esc", this.onKeyBack, this);
this.listenTo(hotkeys, "key:left", this.onKeyBack, this);
}
applyFilters() {
const visibleStatuses = this.settings.getVisibleStatuses();
const visibleMarks = this.settings.getVisibleMarks();
const searchQuery = this.state.get(SEARCH_QUERY_KEY);
const filter = mix(byCriteria(searchQuery), byStatuses(visibleStatuses), byMark(visibleMarks));
const sortSettings = this.settings.getTreeSorting();
const sorter = getComparator(sortSettings);
this.collection.applyFilterAndSorting(filter, sorter);
}
setState() {
const treeNode = this.routeState.get("treeNode");
if (treeNode && treeNode.testResult) {
const uid = treeNode.testResult;
this.state.set(uid, true);
}
if (treeNode && treeNode.testGroup) {
const uid = treeNode.testGroup;
this.state.set(uid, true);
}
}
onBeforeRender() {
this.applyFilters();
}
handleStateChange() {
const query = this.state.get(SEARCH_QUERY_KEY);
// need to check this ot to re-render nodes on folding
if (query !== this.cachedQuery) {
this.cachedQuery = query;
this.render();
}
}
onRender() {
this.selectNode();
if (this.state.get(SEARCH_QUERY_KEY)) {
this.$(".node__title").each((i, node) => {
this.$(node).parent().addClass("node__expanded");
});
} else {
this.restoreState();
}
}
selectNode() {
const previous = this.routeState.previous("treeNode");
this.toggleNode(previous, false);
const current = this.routeState.get("treeNode");
this.toggleNode(current, true);
this.restoreState();
}
toggleNode(node, active = true) {
if (node) {
const el = this.findElement(node);
el.toggleClass("node__title_active", active);
this.changeState(node.testResult);
this.changeState(node.testGroup);
}
}
changeState(uid, active = true) {
if (active) {
this.state.set(uid, true);
} else {
this.state.unset(uid);
}
}
restoreState() {
this.$("[data-uid]").each((i, node) => {
const el = this.$(node);
const uid = el.data("uid");
el.toggleClass("node__expanded", this.state.has(uid));
});
this.$(".node__title_active").parents(".node").toggleClass("node__expanded", true);
if (this.$(".node").parents(".node__expanded").length > 0) {
this.$(".node__expanded").parents("div.node.node__expanded").toggleClass("node__expanded", true);
} else {
this.$(".node__expanded").parents(".node").toggleClass("node__expanded", true);
}
}
findElement(treeNode) {
if (treeNode.testResult) {
return this.$(`[data-uid='${treeNode.testResult}'][data-parentUid='${treeNode.testGroup}']`);
} else {
return this.$(`[data-uid='${treeNode.testGroup}']`);
}
}
onNodeClick(e) {
const node = this.$(e.currentTarget);
const uid = node.data("uid");
this.changeState(uid, !this.state.has(uid));
node.parent().toggleClass("node__expanded");
}
onKeyUp(event) {
event.preventDefault();
const current = this.routeState.get("treeNode");
if (current && current.testResult) {
this.selectTestResult(this.collection.getPreviousTestResult(current.testResult));
} else {
this.selectTestResult(this.collection.getLastTestResult());
}
}
onKeyDown(event) {
event.preventDefault();
const current = this.routeState.get("treeNode");
if (current && current.testResult) {
this.selectTestResult(this.collection.getNextTestResult(current.testResult));
} else {
this.selectTestResult(this.collection.getFirstTestResult());
}
}
onKeyBack(event) {
event.preventDefault();
const current = this.routeState.get("treeNode");
if (!current) {
return;
}
if (current.testGroup && current.testResult) {
if (this.routeState.get("attachment")) {
router.setSearch({ attachment: null });
} else {
router.toUrl(`${this.baseUrl}/${current.testGroup}`);
}
} else if (current.testGroup) {
router.toUrl(`${this.baseUrl}`);
}
}
selectTestResult(testResult) {
if (testResult) {
const tab = this.routeState.get("testResultTab") || "";
router.toUrl(`${this.baseUrl}/${testResult.parentUid}/${testResult.uid}/${tab}`, {
replace: true,
});
}
}
templateContext() {
return {
cls: this.className,
baseUrl: this.baseUrl,
showGroupInfo: this.settings.isShowGroupInfo(),
time: this.collection.time,
statistic: this.collection.statistic,
uid: this.collection.uid,
tabName: this.tabName,
items: this.collection.toJSON(),
testResultTab: this.routeState.get("testResultTab") || "",
};
}
}
export default TreeView;