diff --git a/i18n/english.js b/i18n/english.js
index 9d8adf11..cf854f10 100644
--- a/i18n/english.js
+++ b/i18n/english.js
@@ -271,6 +271,18 @@ const ui = {
lockedNavigation: {
next: "Next",
prev: "Prev"
+ },
+ warnings: {
+ title: "Warnings",
+ totalWarnings: "warnings",
+ totalPackages: "packages affected",
+ noWarnings: "No warnings found",
+ docs: "docs",
+ packages: "packages",
+ occurrences: "occurrences",
+ critical: "Critical",
+ warning: "Warning",
+ information: "Information"
}
};
diff --git a/i18n/french.js b/i18n/french.js
index 904b082b..b0b151e6 100644
--- a/i18n/french.js
+++ b/i18n/french.js
@@ -271,6 +271,18 @@ const ui = {
lockedNavigation: {
next: "Suivant",
prev: "Précédent"
+ },
+ warnings: {
+ title: "Avertissements",
+ totalWarnings: "avertissements",
+ totalPackages: "packages concernés",
+ noWarnings: "Aucun avertissement trouvé",
+ docs: "docs",
+ packages: "packages",
+ occurrences: "occurrences",
+ critical: "Critique",
+ warning: "Avertissement",
+ information: "Information"
}
};
diff --git a/public/components/navigation/navigation.js b/public/components/navigation/navigation.js
index acaf968c..e6b8ff99 100644
--- a/public/components/navigation/navigation.js
+++ b/public/components/navigation/navigation.js
@@ -7,7 +7,8 @@ const kAvailableView = new Set([
"network--view",
"home--view",
"search--view",
- "settings--view"
+ "settings--view",
+ "warnings--view"
]);
export class ViewNavigation {
@@ -58,6 +59,10 @@ export class ViewNavigation {
this.onNavigationSelected(this.menus.get("search--view"));
break;
}
+ case hotkeys.warnings: {
+ this.onNavigationSelected(this.menus.get("warnings--view"));
+ break;
+ }
}
});
}
@@ -77,6 +82,10 @@ export class ViewNavigation {
this.setAnchor(menuName);
this.activeMenu = selectedNav;
+
+ if (menuName === "network--view") {
+ window.dispatchEvent(new CustomEvent(EVENTS.NETWORK_VIEW_SHOWED, { composed: true }));
+ }
}
disableActiveMenu() {
@@ -85,6 +94,10 @@ export class ViewNavigation {
this.activeMenu.classList.remove("active");
view.classList.add("hidden");
+
+ if (menuName === "network--view") {
+ window.dispatchEvent(new CustomEvent(EVENTS.NETWORK_VIEW_HID, { composed: true }));
+ }
}
getAnchor() {
diff --git a/public/components/root-selector/root-selector.js b/public/components/root-selector/root-selector.js
new file mode 100644
index 00000000..90aff032
--- /dev/null
+++ b/public/components/root-selector/root-selector.js
@@ -0,0 +1,198 @@
+// Import Third-party Dependencies
+import { LitElement, html, css, nothing } from "lit";
+
+// Import Internal Dependencies
+import { EVENTS } from "../../core/events.js";
+
+export class RootSelector extends LitElement {
+ static properties = {
+ secureDataSet: { attribute: false },
+ _open: { state: true }
+ };
+
+ static styles = css`
+ :host {
+ position: relative;
+ display: inline-block;
+ color: #1a1a2e;
+ }
+
+ :host-context(body.dark) {
+ color: rgb(255 255 255 / 87%);
+ }
+
+ .selector-btn {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ background: white;
+ border: 1.5px solid rgb(55 34 175 / 20%);
+ border-radius: 8px;
+ padding: 5px 10px;
+ cursor: pointer;
+ font-family: mononoki, monospace;
+ font-size: 13px;
+ color: #1a1a2e;
+ transition: background 0.12s, border-color 0.12s;
+ white-space: nowrap;
+ }
+
+ .selector-btn:hover {
+ background: #f0eeff;
+ border-color: rgb(55 34 175 / 40%);
+ }
+
+ :host-context(body.dark) .selector-btn {
+ background: #1e1c2e;
+ border-color: rgb(163 148 255 / 25%);
+ color: rgb(255 255 255 / 87%);
+ }
+
+ :host-context(body.dark) .selector-btn:hover {
+ background: #2a2640;
+ border-color: rgb(163 148 255 / 45%);
+ }
+
+ .pkg-version {
+ color: #7c6fff;
+ }
+
+ :host-context(body.dark) .pkg-version {
+ color: #a394ff;
+ }
+
+ .chevron {
+ font-size: 9px;
+ opacity: 0.5;
+ margin-left: 2px;
+ }
+
+ .dropdown {
+ position: absolute;
+ top: calc(100% + 6px);
+ left: 0;
+ min-width: 100%;
+ background: white;
+ border: 1px solid rgb(0 0 0 / 10%);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgb(0 0 0 / 10%);
+ z-index: 100;
+ overflow: hidden;
+ padding: 4px 0;
+ }
+
+ :host-context(body.dark) .dropdown {
+ background: #1e1c2e;
+ border-color: rgb(255 255 255 / 10%);
+ box-shadow: 0 8px 24px rgb(0 0 0 / 40%);
+ }
+
+ .pkg-item {
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ padding: 7px 14px;
+ font-family: mononoki, monospace;
+ font-size: 12px;
+ color: #1a1a2e;
+ cursor: pointer;
+ white-space: nowrap;
+ transition: background 0.1s;
+ }
+
+ :host-context(body.dark) .pkg-item {
+ color: rgb(255 255 255 / 87%);
+ }
+
+ .pkg-item:hover {
+ background: rgb(124 111 255 / 8%);
+ }
+
+ :host-context(body.dark) .pkg-item:hover {
+ background: rgb(163 148 255 / 10%);
+ }
+
+ .item-version {
+ color: #7c6fff;
+ }
+
+ :host-context(body.dark) .item-version {
+ color: #a394ff;
+ }
+ `;
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._handleOutsideClick = (event) => {
+ if (!event.composedPath().includes(this)) {
+ this._open = false;
+ }
+ };
+
+ document.addEventListener("click", this._handleOutsideClick);
+ }
+
+ disconnectedCallback() {
+ super.disconnectedCallback();
+ document.removeEventListener("click", this._handleOutsideClick);
+ }
+
+ #switchTo(spec) {
+ window.dispatchEvent(new CustomEvent(EVENTS.ROOT_SWITCH, {
+ detail: { spec }
+ }));
+ this._open = false;
+ }
+
+ render() {
+ if (!this.secureDataSet) {
+ return nothing;
+ }
+
+ const rootEntry = this.secureDataSet.linker.get(0);
+ if (!rootEntry) {
+ return nothing;
+ }
+
+ const others = (window.cachedSpecs ?? []).filter(
+ (pkg) => pkg.spec !== window.activePackage
+ );
+
+ return html`
+
+ ${this._open && others.length > 0 ? html`
+
+ ${others.map((pkg) => {
+ const atIndex = pkg.spec.lastIndexOf("@");
+ const pkgName = pkg.spec.slice(0, atIndex);
+ const pkgVersion = pkg.spec.slice(atIndex);
+
+ return html`
+
this.#switchTo(pkg.spec)}>
+ ${pkgName}
+ ${pkgVersion}
+
+ `;
+ })}
+
+ ` : nothing}
+ `;
+ }
+}
+
+customElements.define("root-selector", RootSelector);
diff --git a/public/components/views/settings/settings.js b/public/components/views/settings/settings.js
index ed8ce20f..abae9ae9 100644
--- a/public/components/views/settings/settings.js
+++ b/public/components/views/settings/settings.js
@@ -18,7 +18,8 @@ const kDefaultHotKeys = {
settings: "S",
wiki: "W",
lock: "L",
- search: "F"
+ search: "F",
+ warnings: "A"
};
const kShortcutInputTargetIds = new Set(Object.keys(kDefaultHotKeys));
diff --git a/public/components/views/warnings/warnings.js b/public/components/views/warnings/warnings.js
new file mode 100644
index 00000000..ed469467
--- /dev/null
+++ b/public/components/views/warnings/warnings.js
@@ -0,0 +1,491 @@
+// Import Third-party Dependencies
+import { LitElement, html, css, nothing } from "lit";
+
+// Import Internal Dependencies
+import { EVENTS } from "../../../core/events.js";
+import { currentLang } from "../../../common/utils.js";
+import "../../root-selector/root-selector.js";
+
+// CONSTANTS
+const kSeverityOrder = ["Critical", "Warning", "Information"];
+const kSeverityColors = {
+ Critical: "#ef4444",
+ Warning: "#f97316",
+ Information: "#3b82f6"
+};
+const kDocsBaseUrl = "https://github.com/NodeSecure/js-x-ray/blob/master/docs";
+
+function buildWarningsData(secureDataSet) {
+ const nodeIdBySpec = new Map();
+ for (const [nodeId, entry] of secureDataSet.linker) {
+ const spec = `${entry.name}@${entry.version}`;
+ if (!nodeIdBySpec.has(spec)) {
+ nodeIdBySpec.set(spec, nodeId);
+ }
+ }
+
+ const byKind = new Map();
+ for (const [packageName, dependency] of Object.entries(secureDataSet.data.dependencies)) {
+ for (const [version, versionData] of Object.entries(dependency.versions)) {
+ const filteredWarnings = versionData.warnings.filter(
+ (warning) => !window.settings.config.ignore.warnings.has(warning.kind)
+ );
+
+ for (const warning of filteredWarnings) {
+ const { kind, severity } = warning;
+ if (!byKind.has(kind)) {
+ byKind.set(kind, { kind, severity, packages: new Map() });
+ }
+
+ const kindData = byKind.get(kind);
+ const spec = `${packageName}@${version}`;
+ const existing = kindData.packages.get(spec) ?? {
+ name: packageName,
+ version,
+ nodeId: nodeIdBySpec.get(spec),
+ count: 0
+ };
+ existing.count++;
+ kindData.packages.set(spec, existing);
+ }
+ }
+ }
+
+ const grouped = Object.fromEntries(kSeverityOrder.map((severity) => [severity, []]));
+ for (const kindData of byKind.values()) {
+ const list = grouped[kindData.severity];
+ if (list) {
+ list.push(kindData);
+ }
+ }
+
+ for (const list of Object.values(grouped)) {
+ list.sort((kindA, kindB) => {
+ const totalA = [...kindA.packages.values()].reduce((sum, pkg) => sum + pkg.count, 0);
+ const totalB = [...kindB.packages.values()].reduce((sum, pkg) => sum + pkg.count, 0);
+
+ return totalB - totalA;
+ });
+ }
+
+ let totalWarnings = 0;
+ const affectedSpecs = new Set();
+ for (const kindData of byKind.values()) {
+ for (const [spec, pkg] of kindData.packages) {
+ totalWarnings += pkg.count;
+ affectedSpecs.add(spec);
+ }
+ }
+
+ return { grouped, totalWarnings, totalPackages: affectedSpecs.size };
+}
+
+function countBySeverity(grouped) {
+ return Object.fromEntries(
+ kSeverityOrder.map((severity) => [
+ severity,
+ grouped[severity].reduce(
+ (sum, kindData) => sum + [...kindData.packages.values()].reduce((s, pkg) => s + pkg.count, 0),
+ 0
+ )
+ ])
+ );
+}
+
+export class WarningsView extends LitElement {
+ static properties = {
+ secureDataSet: { attribute: false }
+ };
+
+ static styles = css`
+ [class^="icon-"]::before, [class*=" icon-"]::before {
+ font-family: fontello;
+ font-style: normal;
+ font-weight: normal;
+ display: inline-block;
+ text-decoration: inherit;
+ text-align: center;
+ font-variant: normal;
+ text-transform: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+ .icon-warning::before { content: '\\e80e'; }
+
+ :host {
+ display: block;
+ height: 100%;
+ overflow-y: auto;
+ background: var(--bg, #f8f7ff);
+ font-family: Roboto, sans-serif;
+ color: #1a1a2e;
+ }
+
+ :host-context(body.dark) {
+ --bg: var(--dark-theme-gray);
+
+ color: rgb(255 255 255 / 87%);
+ }
+
+ .warnings-header {
+ padding: 24px 32px 20px;
+ border-bottom: 1px solid rgb(0 0 0 / 7%);
+ }
+
+ :host-context(body.dark) .warnings-header {
+ border-bottom-color: rgb(255 255 255 / 7%);
+ }
+
+ .warnings-header--top {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 4px;
+ }
+
+ .warnings-header h1 {
+ font-size: 20px;
+ font-weight: 700;
+ margin: 0 0 4px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .warnings-header h1 i {
+ font-size: 18px;
+ color: #f97316;
+ }
+
+ .warnings-subtitle {
+ font-size: 13px;
+ color: #7a7595;
+ margin: 0 0 16px;
+ }
+
+ :host-context(body.dark) .warnings-subtitle {
+ color: rgb(255 255 255 / 45%);
+ }
+
+ .severity-pills {
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+ }
+
+ .severity-pill {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 3px 10px;
+ border-radius: 20px;
+ border: 1.5px solid currentcolor;
+ }
+
+ .severity-pill .dot {
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background: currentcolor;
+ flex-shrink: 0;
+ }
+
+ .severity-pill.critical { color: #ef4444; }
+ .severity-pill.warning { color: #f97316; }
+ .severity-pill.info { color: #3b82f6; }
+ .severity-pill.zero { opacity: 0.35; }
+
+ .warnings-body {
+ padding: 24px 32px;
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+ }
+
+ .severity-section h2 {
+ font-size: 11px;
+ font-weight: 700;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ margin: 0 0 12px;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .severity-section h2 .section-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ flex-shrink: 0;
+ }
+
+ .kind-list {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ .kind-card {
+ background: white;
+ border-radius: 10px;
+ border: 1px solid rgb(0 0 0 / 7%);
+ overflow: hidden;
+ }
+
+ :host-context(body.dark) .kind-card {
+ background: #1e1c2e;
+ border-color: rgb(255 255 255 / 7%);
+ }
+
+ .kind-card--header {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 16px 10px;
+ }
+
+ .kind-name {
+ font-size: 14px;
+ font-weight: 600;
+ flex: 1;
+ font-family: mononoki, monospace;
+ }
+
+ .severity-badge {
+ font-size: 10px;
+ font-weight: 700;
+ padding: 2px 7px;
+ border-radius: 4px;
+ color: white;
+ letter-spacing: 0.5px;
+ text-transform: uppercase;
+ }
+
+ .docs-link {
+ font-size: 11px;
+ color: #7c6fff;
+ text-decoration: none;
+ opacity: 0.8;
+ display: flex;
+ align-items: center;
+ gap: 3px;
+ flex-shrink: 0;
+ }
+
+ .docs-link:hover { opacity: 1; }
+
+ :host-context(body.dark) .docs-link { color: #a394ff; }
+
+ .kind-card--meta {
+ font-size: 11px;
+ color: #7a7595;
+ padding: 0 16px 10px;
+ }
+
+ :host-context(body.dark) .kind-card--meta {
+ color: rgb(255 255 255 / 40%);
+ }
+
+ .kind-card--packages {
+ border-top: 1px solid rgb(0 0 0 / 5%);
+ padding: 6px 0;
+ }
+
+ :host-context(body.dark) .kind-card--packages {
+ border-top-color: rgb(255 255 255 / 5%);
+ }
+
+ .pkg-row {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 5px 16px;
+ cursor: pointer;
+ transition: background 0.12s;
+ }
+
+ .pkg-row:hover {
+ background: rgb(124 111 255 / 6%);
+ }
+
+ :host-context(body.dark) .pkg-row:hover {
+ background: rgb(163 148 255 / 8%);
+ }
+
+ .pkg-name {
+ font-size: 12px;
+ font-family: mononoki, monospace;
+ flex: 1;
+ }
+
+ .pkg-name .version {
+ color: #7c6fff;
+ }
+
+ :host-context(body.dark) .pkg-name .version {
+ color: #a394ff;
+ }
+
+ .pkg-count {
+ font-size: 11px;
+ font-weight: 600;
+ color: #7a7595;
+ background: rgb(0 0 0 / 5%);
+ border-radius: 4px;
+ padding: 1px 6px;
+ flex-shrink: 0;
+ }
+
+ :host-context(body.dark) .pkg-count {
+ background: rgb(255 255 255 / 7%);
+ color: rgb(255 255 255 / 45%);
+ }
+
+ .empty-state {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ padding: 80px 32px;
+ color: #7a7595;
+ text-align: center;
+ }
+
+ .empty-state .checkmark {
+ font-size: 40px;
+ color: #22c55e;
+ }
+
+ .empty-state p {
+ font-size: 15px;
+ margin: 0;
+ }
+ `;
+
+ #onPackageClick(nodeId) {
+ if (nodeId === undefined) {
+ return;
+ }
+
+ window.dispatchEvent(new CustomEvent(EVENTS.TREE_NODE_CLICK, {
+ detail: { nodeId }
+ }));
+ }
+
+ #renderKindCard(kindData) {
+ const i18n = window.i18n[currentLang()];
+ const packages = [...kindData.packages.values()];
+ const totalCount = packages.reduce((sum, pkg) => sum + pkg.count, 0);
+ const color = kSeverityColors[kindData.severity] ?? "#6b7280";
+ const severityLabel = i18n.warnings[kindData.severity.toLowerCase()];
+ const docsLabel = i18n.warnings.docs;
+
+ return html`
+
+
+
+ ${packages.length} ${i18n.warnings.packages} · ${totalCount} ${i18n.warnings.occurrences}
+
+
+ ${packages.sort((pkgA, pkgB) => pkgB.count - pkgA.count).map((pkg) => html`
+
this.#onPackageClick(pkg.nodeId)}>
+ ${pkg.name}@${pkg.version}
+ ×${pkg.count}
+
+ `)}
+
+
+ `;
+ }
+
+ #renderSeveritySection(severity, kindList, i18n) {
+ if (kindList.length === 0) {
+ return nothing;
+ }
+
+ const color = kSeverityColors[severity];
+ const label = i18n.warnings[severity.toLowerCase()];
+
+ return html`
+
+
+
+ ${label}
+
+
+ ${kindList.map((kindData) => this.#renderKindCard(kindData))}
+
+
+ `;
+ }
+
+ render() {
+ if (!this.secureDataSet) {
+ return nothing;
+ }
+
+ const i18n = window.i18n[currentLang()];
+ const { grouped, totalWarnings, totalPackages } = buildWarningsData(this.secureDataSet);
+ const bySeverity = countBySeverity(grouped);
+ const hasWarnings = totalWarnings > 0;
+
+ return html`
+
+
+ ${hasWarnings
+ ? kSeverityOrder.map(
+ (severity) => this.#renderSeveritySection(severity, grouped[severity], i18n)
+ )
+ : html`
+
+
✓
+
${i18n.warnings.noWarnings}
+
+ `
+ }
+
+ `;
+ }
+}
+
+customElements.define("warnings-view", WarningsView);
diff --git a/public/core/events.js b/public/core/events.js
index 04421754..441ee458 100644
--- a/public/core/events.js
+++ b/public/core/events.js
@@ -15,5 +15,6 @@ export const EVENTS = {
DRILL_BACK: "drill-back",
DRILL_SWITCH: "drill-switch",
ROOT_SWITCH: "root-switch",
- ROOT_REMOVE: "root-remove"
+ ROOT_REMOVE: "root-remove",
+ WARNINGS_PACKAGE_CLICK: "warnings-package-click"
};
diff --git a/public/main.js b/public/main.js
index 92e3d5b2..98e35a90 100644
--- a/public/main.js
+++ b/public/main.js
@@ -13,6 +13,8 @@ import "./components/search-command/search-command.js";
import { Settings } from "./components/views/settings/settings.js";
import { HomeView } from "./components/views/home/home.js";
import "./components/views/search/search.js";
+import "./components/views/warnings/warnings.js";
+import "./components/root-selector/root-selector.js";
import "./components/network-breadcrumb/network-breadcrumb.js";
import { NetworkNavigation } from "./core/network-navigation.js";
import { i18n } from "./core/i18n.js";
@@ -27,12 +29,15 @@ let secureDataSet;
let nsn;
let homeView;
let searchview;
+let warningsView;
+let viewAfterSwitch = null;
let drillBreadcrumb;
let packageInfoOpened = false;
const drillStack = [];
document.addEventListener("DOMContentLoaded", async() => {
searchview = document.querySelector("search-view");
+ warningsView = document.querySelector("warnings-view");
window.cachedSpecs = [];
window.locker = null;
@@ -44,15 +49,24 @@ document.addEventListener("DOMContentLoaded", async() => {
// update searchview after window.i18n is set
searchview.requestUpdate();
- document.body.appendChild(
- utils.createDOMElement("div", {
- classList: ["search-shortcut-hint"],
- attributes: { id: "search-shortcut-hint" },
- childs: [
- utils.createDOMElement("kbd", { text: kSearchShortcut })
- ]
- })
- );
+ const isNetworkViewActive = document.getElementById("network--view").classList.contains("hidden") === false;
+ const searchShortcutHint = utils.createDOMElement("div", {
+ classList: isNetworkViewActive ? ["search-shortcut-hint"] : ["search-shortcut-hint", "hidden"],
+ attributes: { id: "search-shortcut-hint" },
+ childs: [
+ utils.createDOMElement("kbd", { text: kSearchShortcut })
+ ]
+ });
+ document.body.appendChild(searchShortcutHint);
+
+ window.addEventListener(EVENTS.NETWORK_VIEW_HID, () => {
+ searchShortcutHint.classList.add("hidden");
+ });
+ window.addEventListener(EVENTS.NETWORK_VIEW_SHOWED, () => {
+ if (!document.getElementById("network--view").classList.contains("hidden")) {
+ searchShortcutHint.classList.remove("hidden");
+ }
+ });
drillBreadcrumb = document.querySelector("network-breadcrumb");
drillBreadcrumb.addEventListener(EVENTS.DRILL_RESET, resetDrill);
@@ -67,6 +81,11 @@ document.addEventListener("DOMContentLoaded", async() => {
drillBreadcrumb.addEventListener(EVENTS.ROOT_SWITCH, function handleRootSwitch(event) {
window.socket.commands.search(event.detail.spec);
});
+
+ window.addEventListener(EVENTS.ROOT_SWITCH, function handleGlobalRootSwitch(event) {
+ viewAfterSwitch = window.navigation.activeMenu?.getAttribute("data-menu") ?? null;
+ window.socket.commands.search(event.detail.spec);
+ });
drillBreadcrumb.addEventListener(EVENTS.ROOT_REMOVE, function handleRootRemove() {
const specToRemove = window.activePackage;
const nextPackage = drillBreadcrumb.packages[0];
@@ -76,11 +95,21 @@ document.addEventListener("DOMContentLoaded", async() => {
else {
window.navigation.hideMenu("network--view");
window.navigation.hideMenu("home--view");
+ window.navigation.hideMenu("warnings--view");
window.navigation.setNavByName("search--view");
}
window.socket.commands.remove(specToRemove);
});
+ warningsView.addEventListener("click", (event) => {
+ const clickedRow = event.composedPath().find(
+ (el) => el instanceof Element && el.classList.contains("pkg-row")
+ );
+ if (!clickedRow) {
+ PackageInfo.close();
+ }
+ });
+
await init();
window.dispatchEvent(
new CustomEvent(EVENTS.SETTINGS_SAVED, {
@@ -112,7 +141,15 @@ async function onSocketPayload(event) {
const { name, version } = payload.rootDependency;
window.activePackage = name + "@" + version;
- await init({ navigateToNetworkView: true });
+ const targetView = viewAfterSwitch;
+ viewAfterSwitch = null;
+
+ await init({ navigateToNetworkView: targetView === null });
+
+ if (targetView !== null && targetView !== "network--view") {
+ window.navigation.setNavByName(targetView);
+ }
+
dispatchSearchCommandInit();
}
@@ -274,6 +311,8 @@ async function init(options = {}) {
window.navigation.showMenu("network--view");
window.navigation.showMenu("home--view");
+ window.navigation.showMenu("warnings--view");
+ warningsView.secureDataSet = secureDataSet;
window.vulnerabilityStrategy = secureDataSet.data.vulnerabilityStrategy;
@@ -342,6 +381,7 @@ async function loadDataSet() {
if (secureDataSet.data === null) {
window.navigation.hideMenu("network--view");
window.navigation.hideMenu("home--view");
+ window.navigation.hideMenu("warnings--view");
window.navigation.setNavByName("search--view");
return false;
diff --git a/views/index.html b/views/index.html
index 84e35e22..a791694a 100644
--- a/views/index.html
+++ b/views/index.html
@@ -58,6 +58,10 @@
+
+
+
+
@@ -89,6 +93,7 @@
+
[[=z.token('settings.general.title')]]
+
+
+
+