@64mb/freelens-power 2.1.0 → 2.2.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.
- package/README.md +4 -4
- package/out/main/common/power-logs.js.map +1 -1
- package/out/main/common/resource-search.js.map +1 -1
- package/out/main/power-logs-child.js +3 -3
- package/out/main/power-logs-child.js.map +1 -1
- package/out/main/power-logs-database.js +165 -7
- package/out/main/power-logs-database.js.map +1 -1
- package/out/main/power-logs-ipc.js +12 -3
- package/out/main/power-logs-ipc.js.map +1 -1
- package/out/main/power-logs-worker.js +29 -7
- package/out/main/power-logs-worker.js.map +1 -1
- package/out/main/resource-search-database.js +3 -2
- package/out/main/resource-search-database.js.map +1 -1
- package/out/main/resource-search.js +2 -1
- package/out/main/resource-search.js.map +1 -1
- package/out/renderer/_virtual/_global-external_react.js +2 -1
- package/out/renderer/ai-context-mutations.js +14 -0
- package/out/renderer/ai-context-mutations.js.map +1 -0
- package/out/renderer/ai-copy-answer.js +18 -15
- package/out/renderer/ai-copy-answer.js.map +1 -1
- package/out/renderer/ai-diagnostic-handoff.js +2 -2
- package/out/renderer/ai-diagnostic-handoff.js.map +1 -1
- package/out/renderer/ai-extras.js +41 -38
- package/out/renderer/ai-extras.js.map +1 -1
- package/out/renderer/ai-message.js +50 -39
- package/out/renderer/ai-message.js.map +1 -1
- package/out/renderer/ai-provider-icon.js +39 -32
- package/out/renderer/ai-provider-icon.js.map +1 -1
- package/out/renderer/ai-resize.js +40 -37
- package/out/renderer/ai-resize.js.map +1 -1
- package/out/renderer/ai-shortcuts.js +20 -17
- package/out/renderer/ai-shortcuts.js.map +1 -1
- package/out/renderer/ai-terminal-context.js +42 -48
- package/out/renderer/ai-terminal-context.js.map +1 -1
- package/out/renderer/ai.js +137 -111
- package/out/renderer/ai.js.map +1 -1
- package/out/renderer/cluster-icon-colors.js +10 -7
- package/out/renderer/cluster-icon-colors.js.map +1 -1
- package/out/renderer/cluster-icons.js +47 -40
- package/out/renderer/cluster-icons.js.map +1 -1
- package/out/renderer/details/service-diagnostics-details.js +25 -23
- package/out/renderer/details/service-diagnostics-details.js.map +1 -1
- package/out/renderer/diagnostic-explain-button.js +7 -4
- package/out/renderer/diagnostic-explain-button.js.map +1 -1
- package/out/renderer/diagnostics-screen-finding.js +51 -0
- package/out/renderer/diagnostics-screen-finding.js.map +1 -0
- package/out/renderer/diagnostics.css.js +1 -1
- package/out/renderer/diagnostics.css.js.map +1 -1
- package/out/renderer/diagnostics.js +146 -107
- package/out/renderer/diagnostics.js.map +1 -1
- package/out/renderer/incident-copy-button.js +24 -21
- package/out/renderer/incident-copy-button.js.map +1 -1
- package/out/renderer/index.js +2 -0
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/monitoring.js +19 -22
- package/out/renderer/monitoring.js.map +1 -1
- package/out/renderer/native-tooltip.js +22 -0
- package/out/renderer/native-tooltip.js.map +1 -0
- package/out/renderer/pod-details-enhancements.js +106 -0
- package/out/renderer/pod-details-enhancements.js.map +1 -0
- package/out/renderer/power-log-json-cell.js +44 -38
- package/out/renderer/power-log-json-cell.js.map +1 -1
- package/out/renderer/power-log-json.js +17 -10
- package/out/renderer/power-log-json.js.map +1 -1
- package/out/renderer/power-log-sql-editor.js +31 -2
- package/out/renderer/power-log-sql-editor.js.map +1 -1
- package/out/renderer/power-logs-client.js +5 -0
- package/out/renderer/power-logs-client.js.map +1 -1
- package/out/renderer/power-logs-entrypoints.js +10 -36
- package/out/renderer/power-logs-entrypoints.js.map +1 -1
- package/out/renderer/power-logs.css.js +9 -2
- package/out/renderer/power-logs.css.js.map +1 -1
- package/out/renderer/power-logs.js +376 -214
- package/out/renderer/power-logs.js.map +1 -1
- package/out/renderer/preferences/dashboard-preferences.js +42 -35
- package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
- package/out/renderer/preferences/logs-preferences.js +1 -1
- package/out/renderer/preferences/logs-preferences.js.map +1 -1
- package/out/renderer/preferences/monitoring-preferences.js +7 -4
- package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +2 -2
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/preferences/settings-icon-action.js +12 -11
- package/out/renderer/preferences/settings-icon-action.js.map +1 -1
- package/out/renderer/relationship-map-finding.js +53 -0
- package/out/renderer/relationship-map-finding.js.map +1 -0
- package/out/renderer/resource-relationships.css.js +6 -0
- package/out/renderer/resource-relationships.css.js.map +1 -1
- package/out/renderer/resource-relationships.js +94 -47
- package/out/renderer/resource-relationships.js.map +1 -1
- package/out/renderer/resource-search-client.js.map +1 -1
- package/out/renderer/resource-search.js +88 -35
- package/out/renderer/resource-search.js.map +1 -1
- package/out/renderer/src/common/gateway-relationships.js +8 -7
- package/out/renderer/src/common/gateway-relationships.js.map +1 -1
- package/out/renderer/src/common/power-log-json-filter-sql.js +12 -0
- package/out/renderer/src/common/power-log-json-filter-sql.js.map +1 -1
- package/out/renderer/src/common/power-log-json-preset.js +2 -2
- package/out/renderer/src/common/power-log-json-preset.js.map +1 -1
- package/out/renderer/src/common/power-logs.js.map +1 -1
- package/out/renderer/src/common/resource-relationships.js +10 -8
- package/out/renderer/src/common/resource-relationships.js.map +1 -1
- package/out/renderer/src/common/resource-search.js.map +1 -1
- package/out/renderer/welcome.js +16 -1
- package/out/renderer/welcome.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ const require_dashboard = require("../src/common/dashboard.js");
|
|
|
5
5
|
const require_dashboard_preferences_store = require("../src/common/store/dashboard-preferences-store.js");
|
|
6
6
|
const require__global_external_react = require("../_virtual/_global-external_react.js");
|
|
7
7
|
const require_jsx_runtime = require("../_virtual/_global-external_react/jsx-runtime.js");
|
|
8
|
+
const require_native_tooltip = require("../native-tooltip.js");
|
|
8
9
|
const require_settings_modal = require("./settings-modal.js");
|
|
9
10
|
const require_dashboard_views = require("../src/common/dashboard-views.js");
|
|
10
11
|
const require_settings_icon_action = require("./settings-icon-action.js");
|
|
@@ -313,25 +314,27 @@ var DashboardPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
313
314
|
opacity: draggingId === card.id ? .5 : 1
|
|
314
315
|
},
|
|
315
316
|
children: [
|
|
316
|
-
/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
317
|
-
type: "button",
|
|
318
|
-
className: "power-dashboard-drag-handle",
|
|
319
|
-
draggable: true,
|
|
320
|
-
"aria-label": `Reorder ${card.title}`,
|
|
317
|
+
/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
321
318
|
title: "Drag to reorder, or use the Up and Down arrow keys",
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
319
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
320
|
+
type: "button",
|
|
321
|
+
className: "power-dashboard-drag-handle",
|
|
322
|
+
draggable: true,
|
|
323
|
+
"aria-label": `Reorder ${card.title}`,
|
|
324
|
+
onDragStart: (event) => {
|
|
325
|
+
event.dataTransfer.effectAllowed = "move";
|
|
326
|
+
event.dataTransfer.setData("text/plain", card.id);
|
|
327
|
+
setDraggingId(card.id);
|
|
328
|
+
},
|
|
329
|
+
onDragEnd: finishDrag,
|
|
330
|
+
onKeyDown: (event) => {
|
|
331
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
332
|
+
event.preventDefault();
|
|
333
|
+
event.stopPropagation();
|
|
334
|
+
moveCard(card, Math.max(0, Math.min(preferences.cards.length - 1, index + (event.key === "ArrowUp" ? -1 : 1))));
|
|
335
|
+
},
|
|
336
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(Icon, { material: "drag_indicator" })
|
|
337
|
+
})
|
|
335
338
|
}),
|
|
336
339
|
/* @__PURE__ */ require_jsx_runtime.jsx(WebsiteIcon, {
|
|
337
340
|
url: card.url,
|
|
@@ -342,25 +345,29 @@ var DashboardPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
342
345
|
flex: 1,
|
|
343
346
|
minWidth: 0
|
|
344
347
|
},
|
|
345
|
-
children: [/* @__PURE__ */ require_jsx_runtime.jsx(
|
|
348
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
346
349
|
title: card.title,
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
350
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
351
|
+
style: {
|
|
352
|
+
fontWeight: 600,
|
|
353
|
+
overflow: "hidden",
|
|
354
|
+
textOverflow: "ellipsis",
|
|
355
|
+
whiteSpace: "nowrap"
|
|
356
|
+
},
|
|
357
|
+
children: card.title
|
|
358
|
+
})
|
|
359
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
356
360
|
title: card.url,
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
362
|
+
className: "power-settings-hint",
|
|
363
|
+
style: {
|
|
364
|
+
overflow: "hidden",
|
|
365
|
+
textOverflow: "ellipsis",
|
|
366
|
+
whiteSpace: "nowrap",
|
|
367
|
+
marginTop: 3
|
|
368
|
+
},
|
|
369
|
+
children: card.url
|
|
370
|
+
})
|
|
364
371
|
})]
|
|
365
372
|
}),
|
|
366
373
|
/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-preferences.js","names":[],"sources":["../../../src/renderer/preferences/dashboard-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { ipcRenderer } from \"electron\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { type DashboardCard, type DashboardCardSize, normalizeDashboardUrl } from \"../../common/dashboard\";\nimport { DASHBOARD_PICK_ELEMENT, type DashboardPickerResult } from \"../../common/dashboard-picker\";\nimport { dashboardSelectorLimit, normalizeDashboardSelector } from \"../../common/dashboard-selector\";\nimport { DASHBOARD_SITE_ICONS, type DashboardSiteIcon } from \"../../common/dashboard-views\";\nimport { DashboardPreferencesStore } from \"../../common/store/dashboard-preferences-store\";\nimport { SettingsIconAction } from \"./settings-icon-action\";\nimport { SettingsField, SettingsModal } from \"./settings-modal\";\n\nconst { Input, Select, Button, Icon, Checkbox } = Renderer.Component;\nconst sizeOptions = [\n { value: \"xs\" as const, label: \"XS · Extra small\" },\n { value: \"s\" as const, label: \"S · Small\" },\n { value: \"m\" as const, label: \"M · Medium\" },\n { value: \"l\" as const, label: \"L · Large\" },\n { value: \"xl\" as const, label: \"XL · Extra large\" },\n];\n\nfunction CardEditor({\n card,\n onSave,\n onClose,\n}: {\n card?: DashboardCard;\n onSave: (card: DashboardCard) => void;\n onClose: () => void;\n}) {\n const [title, setTitle] = useState(card?.title ?? \"\");\n const [url, setUrl] = useState(card?.url ?? \"\");\n const [size, setSize] = useState<DashboardCardSize>(card?.size ?? \"m\");\n const [autoRefresh, setAutoRefresh] = useState(card ? card.autoRefresh === true : true);\n const [selector, setSelector] = useState(card?.selector ?? \"\");\n const selectorInvalid = selector.trim().length > 0 && !normalizeDashboardSelector(selector);\n const [picking, setPicking] = useState(false);\n const [pickerError, setPickerError] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const id = `freelens-power-dashboard-${card?.id ?? \"new\"}`;\n const normalizedUrl = normalizeDashboardUrl(url);\n const invalid = (submitted || url.length > 0) && !normalizedUrl;\n\n function save() {\n setSubmitted(true);\n if (!normalizedUrl || selectorInvalid) return;\n onSave({\n id: card?.id ?? crypto.randomUUID(),\n title: title.trim() || new URL(normalizedUrl).hostname,\n url: normalizedUrl,\n size,\n autoRefresh,\n ...(card?.refreshEvery10Seconds ? { refreshEvery10Seconds: true } : {}),\n selector: normalizeDashboardSelector(selector),\n });\n onClose();\n }\n\n return (\n <SettingsModal id={id} title={card ? \"Edit card\" : \"Add a card\"} onClose={onClose}>\n <SettingsField id={`${id}-title`} label=\"Title\">\n <Input autoFocus id={`${id}-title`} value={title} placeholder=\"Website name\" onChange={setTitle} />\n </SettingsField>\n <SettingsField id={`${id}-url`} label=\"URL\">\n <Input\n id={`${id}-url`}\n value={url}\n placeholder=\"https://example.com\"\n onChange={setUrl}\n aria-invalid={invalid}\n aria-describedby={invalid ? `${id}-error` : undefined}\n />\n {invalid && (\n <div id={`${id}-error`} role=\"alert\" style={{ color: \"var(--colorError)\", marginTop: 6 }}>\n Enter a valid HTTP or HTTPS URL.\n </div>\n )}\n </SettingsField>\n <SettingsField id={`${id}-selector`} label=\"CSS selector (optional)\">\n <div className=\"power-dashboard-selector-editor\">\n <div className=\"power-dashboard-selector-field\">\n <Input\n className=\"power-dashboard-selector-input\"\n id={`${id}-selector`}\n value={selector}\n onChange={setSelector}\n placeholder=\"main .chart\"\n aria-invalid={selectorInvalid}\n />\n {selector && (\n <SettingsIconAction\n material=\"close\"\n label=\"Clear selector\"\n disabled={picking}\n onClick={() => setSelector(\"\")}\n />\n )}\n <SettingsIconAction\n material=\"center_focus_strong\"\n label={picking ? \"Selecting element…\" : \"Pick element on website\"}\n disabled={!normalizedUrl || picking}\n onClick={() => {\n if (!normalizedUrl || picking) return;\n setPicking(true);\n setPickerError(false);\n void ipcRenderer\n .invoke(DASHBOARD_PICK_ELEMENT, { url: normalizedUrl })\n .then((result: DashboardPickerResult) => {\n if (result?.status === \"selected\") {\n const selected = normalizeDashboardSelector(result.selector);\n if (selected) setSelector(selected);\n else setPickerError(true);\n } else if (result?.status !== \"canceled\") setPickerError(true);\n })\n .catch(() => setPickerError(true))\n .finally(() => setPicking(false));\n }}\n />\n </div>\n {selectorInvalid && (\n <div role=\"alert\">Use at most {dashboardSelectorLimit} characters without control characters.</div>\n )}\n {pickerError && <div role=\"alert\">Could not select an element. Try again or enter a CSS selector.</div>}\n </div>\n </SettingsField>\n <SettingsField id={`${id}-size`} label=\"Card size\">\n <Select\n id={`${id}-size`}\n aria-label=\"Card size\"\n styles={{ menuPortal: (base) => ({ ...base, zIndex: 12010 }) }}\n options={sizeOptions}\n value={size}\n isSearchable={false}\n isClearable={false}\n onChange={(option) => {\n if (option) setSize(option.value);\n }}\n />\n </SettingsField>\n <SettingsField\n id={`${id}-autorefresh`}\n label={\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n Background refresh\n <Icon\n material=\"info_outline\"\n size={14}\n tooltip={{\n children: \"Refresh cached pages every 10 minutes while the dashboard is closed\",\n style: { zIndex: 12020 },\n }}\n />\n </span>\n }\n >\n <Checkbox {...{ id: `${id}-autorefresh` }} value={autoRefresh} onChange={setAutoRefresh} />\n </SettingsField>\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", gap: 12 }}>\n <Button label=\"Cancel\" onClick={onClose} />\n <Button primary label={card ? \"Save card\" : \"Add card\"} onClick={save} />\n </div>\n </SettingsModal>\n );\n}\n\nfunction WebsiteIcon({ url, favicon }: { url: string; favicon?: string }) {\n const source = favicon || new URL(\"/favicon.ico\", url).href;\n const [failedSource, setFailedSource] = useState<string>();\n return failedSource === source ? (\n <span aria-hidden=\"true\">🌐</span>\n ) : (\n <img\n src={source}\n alt=\"\"\n width={20}\n height={20}\n loading=\"lazy\"\n referrerPolicy=\"no-referrer\"\n onError={() => setFailedSource(source)}\n />\n );\n}\n\nexport const DashboardPreferences = observer(() => {\n const preferences = DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>();\n const [siteIcons, setSiteIcons] = useState<DashboardSiteIcon[]>([]);\n const cardIdentity = JSON.stringify(preferences.cards.map(({ id, url }) => ({ id, url })));\n useEffect(() => {\n let active = true;\n const refreshIcons = () =>\n void ipcRenderer\n .invoke(DASHBOARD_SITE_ICONS)\n .then((icons: DashboardSiteIcon[]) => {\n if (active && Array.isArray(icons)) setSiteIcons(icons);\n })\n .catch(() => {});\n refreshIcons();\n ipcRenderer.on(DASHBOARD_SITE_ICONS, refreshIcons);\n return () => {\n active = false;\n ipcRenderer.removeListener(DASHBOARD_SITE_ICONS, refreshIcons);\n };\n }, [cardIdentity]);\n const [editing, setEditing] = useState<DashboardCard | \"new\" | null>(null);\n const [draggingId, setDraggingId] = useState<string | null>(null);\n const [dropId, setDropId] = useState<string | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n\n function moveCard(card: DashboardCard, index: number) {\n preferences.moveCard(card.id, index);\n setAnnouncement(\n `${card.title} moved to position ${preferences.cards.findIndex((entry) => entry.id === card.id) + 1}`,\n );\n }\n\n function finishDrag() {\n setDraggingId(null);\n setDropId(null);\n }\n\n return (\n <div style={{ display: \"grid\", gap: 8 }}>\n <div className=\"power-settings-hint\">\n Display websites in responsive dashboard cards. Some websites block embedding.\n </div>\n <style>{`\n .power-dashboard-drag-handle { display: inline-flex; align-items: center; padding: 4px; border: 0; border-radius: 4px; background: transparent; color: var(--textColorSecondary); cursor: grab; flex-shrink: 0; }\n .power-dashboard-drag-handle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n .power-dashboard-drag-handle:active { cursor: grabbing; }\n `}</style>\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{ position: \"absolute\", width: 1, height: 1, overflow: \"hidden\", clipPath: \"inset(50%)\" }}\n >\n {announcement}\n </div>\n {preferences.cards.map((card, index) => (\n <div\n key={card.id}\n data-dashboard-card-id={card.id}\n onDragOver={(event) => {\n if (!draggingId || draggingId === card.id) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n setDropId(card.id);\n }}\n onDrop={(event) => {\n if (!draggingId) return;\n event.preventDefault();\n const dragged = preferences.cards.find((entry) => entry.id === draggingId);\n if (dragged) moveCard(dragged, index);\n finishDrag();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n minWidth: 0,\n padding: \"8px 0\",\n borderBottom: \"1px solid var(--borderFaintColor)\",\n boxShadow:\n dropId === card.id && draggingId !== card.id\n ? `0 ${preferences.cards.findIndex((entry) => entry.id === draggingId) < index ? 2 : -2}px 0 var(--primary)`\n : undefined,\n opacity: draggingId === card.id ? 0.5 : 1,\n }}\n >\n <button\n type=\"button\"\n className=\"power-dashboard-drag-handle\"\n draggable\n aria-label={`Reorder ${card.title}`}\n title=\"Drag to reorder, or use the Up and Down arrow keys\"\n onDragStart={(event) => {\n event.dataTransfer.effectAllowed = \"move\";\n event.dataTransfer.setData(\"text/plain\", card.id);\n setDraggingId(card.id);\n }}\n onDragEnd={finishDrag}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n event.preventDefault();\n event.stopPropagation();\n moveCard(\n card,\n Math.max(0, Math.min(preferences.cards.length - 1, index + (event.key === \"ArrowUp\" ? -1 : 1))),\n );\n }}\n >\n <Icon material=\"drag_indicator\" />\n </button>\n <WebsiteIcon\n key={card.url}\n url={card.url}\n favicon={\n siteIcons.find((icon) => icon.id === card.id && icon.pageUrl === normalizeDashboardUrl(card.url))?.dataUrl\n }\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n title={card.title}\n style={{ fontWeight: 600, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}\n >\n {card.title}\n </div>\n <div\n className=\"power-settings-hint\"\n title={card.url}\n style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", marginTop: 3 }}\n >\n {card.url}\n </div>\n </div>\n <span\n aria-label={`Card size ${card.size.toUpperCase()}`}\n style={{\n flexShrink: 0,\n marginRight: 10,\n padding: \"3px 7px\",\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n fontSize: 11,\n fontFamily: \"var(--font-monospace, monospace)\",\n lineHeight: \"18px\",\n color: \"var(--textColorSecondary)\",\n }}\n >\n Size: {card.size.toUpperCase()}\n </span>\n <SettingsIconAction material=\"edit\" label={`Edit ${card.title}`} onClick={() => setEditing(card)} />\n <SettingsIconAction\n material=\"delete_outline\"\n label={`Remove ${card.title}`}\n onClick={() => preferences.removeCard(card.id)}\n />\n </div>\n ))}\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <Button\n primary\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => setEditing(\"new\")}\n >\n <Renderer.Component.Icon material=\"add\" size={16} />\n <span>Add card</span>\n </Button>\n </div>\n {editing && (\n <CardEditor\n card={editing === \"new\" ? undefined : editing}\n onSave={(value) => preferences.upsertCard(value)}\n onClose={() => setEditing(null)}\n />\n )}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dashboard-preferences.js","names":[],"sources":["../../../src/renderer/preferences/dashboard-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { ipcRenderer } from \"electron\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { type DashboardCard, type DashboardCardSize, normalizeDashboardUrl } from \"../../common/dashboard\";\nimport { DASHBOARD_PICK_ELEMENT, type DashboardPickerResult } from \"../../common/dashboard-picker\";\nimport { dashboardSelectorLimit, normalizeDashboardSelector } from \"../../common/dashboard-selector\";\nimport { DASHBOARD_SITE_ICONS, type DashboardSiteIcon } from \"../../common/dashboard-views\";\nimport { DashboardPreferencesStore } from \"../../common/store/dashboard-preferences-store\";\nimport { NativeTooltip } from \"../native-tooltip\";\nimport { SettingsIconAction } from \"./settings-icon-action\";\nimport { SettingsField, SettingsModal } from \"./settings-modal\";\n\nconst { Input, Select, Button, Icon, Checkbox } = Renderer.Component;\nconst sizeOptions = [\n { value: \"xs\" as const, label: \"XS · Extra small\" },\n { value: \"s\" as const, label: \"S · Small\" },\n { value: \"m\" as const, label: \"M · Medium\" },\n { value: \"l\" as const, label: \"L · Large\" },\n { value: \"xl\" as const, label: \"XL · Extra large\" },\n];\n\nfunction CardEditor({\n card,\n onSave,\n onClose,\n}: {\n card?: DashboardCard;\n onSave: (card: DashboardCard) => void;\n onClose: () => void;\n}) {\n const [title, setTitle] = useState(card?.title ?? \"\");\n const [url, setUrl] = useState(card?.url ?? \"\");\n const [size, setSize] = useState<DashboardCardSize>(card?.size ?? \"m\");\n const [autoRefresh, setAutoRefresh] = useState(card ? card.autoRefresh === true : true);\n const [selector, setSelector] = useState(card?.selector ?? \"\");\n const selectorInvalid = selector.trim().length > 0 && !normalizeDashboardSelector(selector);\n const [picking, setPicking] = useState(false);\n const [pickerError, setPickerError] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const id = `freelens-power-dashboard-${card?.id ?? \"new\"}`;\n const normalizedUrl = normalizeDashboardUrl(url);\n const invalid = (submitted || url.length > 0) && !normalizedUrl;\n\n function save() {\n setSubmitted(true);\n if (!normalizedUrl || selectorInvalid) return;\n onSave({\n id: card?.id ?? crypto.randomUUID(),\n title: title.trim() || new URL(normalizedUrl).hostname,\n url: normalizedUrl,\n size,\n autoRefresh,\n ...(card?.refreshEvery10Seconds ? { refreshEvery10Seconds: true } : {}),\n selector: normalizeDashboardSelector(selector),\n });\n onClose();\n }\n\n return (\n <SettingsModal id={id} title={card ? \"Edit card\" : \"Add a card\"} onClose={onClose}>\n <SettingsField id={`${id}-title`} label=\"Title\">\n <Input autoFocus id={`${id}-title`} value={title} placeholder=\"Website name\" onChange={setTitle} />\n </SettingsField>\n <SettingsField id={`${id}-url`} label=\"URL\">\n <Input\n id={`${id}-url`}\n value={url}\n placeholder=\"https://example.com\"\n onChange={setUrl}\n aria-invalid={invalid}\n aria-describedby={invalid ? `${id}-error` : undefined}\n />\n {invalid && (\n <div id={`${id}-error`} role=\"alert\" style={{ color: \"var(--colorError)\", marginTop: 6 }}>\n Enter a valid HTTP or HTTPS URL.\n </div>\n )}\n </SettingsField>\n <SettingsField id={`${id}-selector`} label=\"CSS selector (optional)\">\n <div className=\"power-dashboard-selector-editor\">\n <div className=\"power-dashboard-selector-field\">\n <Input\n className=\"power-dashboard-selector-input\"\n id={`${id}-selector`}\n value={selector}\n onChange={setSelector}\n placeholder=\"main .chart\"\n aria-invalid={selectorInvalid}\n />\n {selector && (\n <SettingsIconAction\n material=\"close\"\n label=\"Clear selector\"\n disabled={picking}\n onClick={() => setSelector(\"\")}\n />\n )}\n <SettingsIconAction\n material=\"center_focus_strong\"\n label={picking ? \"Selecting element…\" : \"Pick element on website\"}\n disabled={!normalizedUrl || picking}\n onClick={() => {\n if (!normalizedUrl || picking) return;\n setPicking(true);\n setPickerError(false);\n void ipcRenderer\n .invoke(DASHBOARD_PICK_ELEMENT, { url: normalizedUrl })\n .then((result: DashboardPickerResult) => {\n if (result?.status === \"selected\") {\n const selected = normalizeDashboardSelector(result.selector);\n if (selected) setSelector(selected);\n else setPickerError(true);\n } else if (result?.status !== \"canceled\") setPickerError(true);\n })\n .catch(() => setPickerError(true))\n .finally(() => setPicking(false));\n }}\n />\n </div>\n {selectorInvalid && (\n <div role=\"alert\">Use at most {dashboardSelectorLimit} characters without control characters.</div>\n )}\n {pickerError && <div role=\"alert\">Could not select an element. Try again or enter a CSS selector.</div>}\n </div>\n </SettingsField>\n <SettingsField id={`${id}-size`} label=\"Card size\">\n <Select\n id={`${id}-size`}\n aria-label=\"Card size\"\n styles={{ menuPortal: (base) => ({ ...base, zIndex: 12010 }) }}\n options={sizeOptions}\n value={size}\n isSearchable={false}\n isClearable={false}\n onChange={(option) => {\n if (option) setSize(option.value);\n }}\n />\n </SettingsField>\n <SettingsField\n id={`${id}-autorefresh`}\n label={\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n Background refresh\n <Icon\n material=\"info_outline\"\n size={14}\n tooltip={{\n children: \"Refresh cached pages every 10 minutes while the dashboard is closed\",\n style: { zIndex: 12020 },\n }}\n />\n </span>\n }\n >\n <Checkbox {...{ id: `${id}-autorefresh` }} value={autoRefresh} onChange={setAutoRefresh} />\n </SettingsField>\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", gap: 12 }}>\n <Button label=\"Cancel\" onClick={onClose} />\n <Button primary label={card ? \"Save card\" : \"Add card\"} onClick={save} />\n </div>\n </SettingsModal>\n );\n}\n\nfunction WebsiteIcon({ url, favicon }: { url: string; favicon?: string }) {\n const source = favicon || new URL(\"/favicon.ico\", url).href;\n const [failedSource, setFailedSource] = useState<string>();\n return failedSource === source ? (\n <span aria-hidden=\"true\">🌐</span>\n ) : (\n <img\n src={source}\n alt=\"\"\n width={20}\n height={20}\n loading=\"lazy\"\n referrerPolicy=\"no-referrer\"\n onError={() => setFailedSource(source)}\n />\n );\n}\n\nexport const DashboardPreferences = observer(() => {\n const preferences = DashboardPreferencesStore.getInstanceOrCreate<DashboardPreferencesStore>();\n const [siteIcons, setSiteIcons] = useState<DashboardSiteIcon[]>([]);\n const cardIdentity = JSON.stringify(preferences.cards.map(({ id, url }) => ({ id, url })));\n useEffect(() => {\n let active = true;\n const refreshIcons = () =>\n void ipcRenderer\n .invoke(DASHBOARD_SITE_ICONS)\n .then((icons: DashboardSiteIcon[]) => {\n if (active && Array.isArray(icons)) setSiteIcons(icons);\n })\n .catch(() => {});\n refreshIcons();\n ipcRenderer.on(DASHBOARD_SITE_ICONS, refreshIcons);\n return () => {\n active = false;\n ipcRenderer.removeListener(DASHBOARD_SITE_ICONS, refreshIcons);\n };\n }, [cardIdentity]);\n const [editing, setEditing] = useState<DashboardCard | \"new\" | null>(null);\n const [draggingId, setDraggingId] = useState<string | null>(null);\n const [dropId, setDropId] = useState<string | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n\n function moveCard(card: DashboardCard, index: number) {\n preferences.moveCard(card.id, index);\n setAnnouncement(\n `${card.title} moved to position ${preferences.cards.findIndex((entry) => entry.id === card.id) + 1}`,\n );\n }\n\n function finishDrag() {\n setDraggingId(null);\n setDropId(null);\n }\n\n return (\n <div style={{ display: \"grid\", gap: 8 }}>\n <div className=\"power-settings-hint\">\n Display websites in responsive dashboard cards. Some websites block embedding.\n </div>\n <style>{`\n .power-dashboard-drag-handle { display: inline-flex; align-items: center; padding: 4px; border: 0; border-radius: 4px; background: transparent; color: var(--textColorSecondary); cursor: grab; flex-shrink: 0; }\n .power-dashboard-drag-handle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n .power-dashboard-drag-handle:active { cursor: grabbing; }\n `}</style>\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{ position: \"absolute\", width: 1, height: 1, overflow: \"hidden\", clipPath: \"inset(50%)\" }}\n >\n {announcement}\n </div>\n {preferences.cards.map((card, index) => (\n <div\n key={card.id}\n data-dashboard-card-id={card.id}\n onDragOver={(event) => {\n if (!draggingId || draggingId === card.id) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = \"move\";\n setDropId(card.id);\n }}\n onDrop={(event) => {\n if (!draggingId) return;\n event.preventDefault();\n const dragged = preferences.cards.find((entry) => entry.id === draggingId);\n if (dragged) moveCard(dragged, index);\n finishDrag();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n minWidth: 0,\n padding: \"8px 0\",\n borderBottom: \"1px solid var(--borderFaintColor)\",\n boxShadow:\n dropId === card.id && draggingId !== card.id\n ? `0 ${preferences.cards.findIndex((entry) => entry.id === draggingId) < index ? 2 : -2}px 0 var(--primary)`\n : undefined,\n opacity: draggingId === card.id ? 0.5 : 1,\n }}\n >\n <NativeTooltip title=\"Drag to reorder, or use the Up and Down arrow keys\">\n <button\n type=\"button\"\n className=\"power-dashboard-drag-handle\"\n draggable\n aria-label={`Reorder ${card.title}`}\n onDragStart={(event) => {\n event.dataTransfer.effectAllowed = \"move\";\n event.dataTransfer.setData(\"text/plain\", card.id);\n setDraggingId(card.id);\n }}\n onDragEnd={finishDrag}\n onKeyDown={(event) => {\n if (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n event.preventDefault();\n event.stopPropagation();\n moveCard(\n card,\n Math.max(0, Math.min(preferences.cards.length - 1, index + (event.key === \"ArrowUp\" ? -1 : 1))),\n );\n }}\n >\n <Icon material=\"drag_indicator\" />\n </button>\n </NativeTooltip>\n <WebsiteIcon\n key={card.url}\n url={card.url}\n favicon={\n siteIcons.find((icon) => icon.id === card.id && icon.pageUrl === normalizeDashboardUrl(card.url))?.dataUrl\n }\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <NativeTooltip title={card.title}>\n <div style={{ fontWeight: 600, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {card.title}\n </div>\n </NativeTooltip>\n <NativeTooltip title={card.url}>\n <div\n className=\"power-settings-hint\"\n style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", marginTop: 3 }}\n >\n {card.url}\n </div>\n </NativeTooltip>\n </div>\n <span\n aria-label={`Card size ${card.size.toUpperCase()}`}\n style={{\n flexShrink: 0,\n marginRight: 10,\n padding: \"3px 7px\",\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n fontSize: 11,\n fontFamily: \"var(--font-monospace, monospace)\",\n lineHeight: \"18px\",\n color: \"var(--textColorSecondary)\",\n }}\n >\n Size: {card.size.toUpperCase()}\n </span>\n <SettingsIconAction material=\"edit\" label={`Edit ${card.title}`} onClick={() => setEditing(card)} />\n <SettingsIconAction\n material=\"delete_outline\"\n label={`Remove ${card.title}`}\n onClick={() => preferences.removeCard(card.id)}\n />\n </div>\n ))}\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <Button\n primary\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => setEditing(\"new\")}\n >\n <Renderer.Component.Icon material=\"add\" size={16} />\n <span>Add card</span>\n </Button>\n </div>\n {editing && (\n <CardEditor\n card={editing === \"new\" ? undefined : editing}\n onSave={(value) => preferences.upsertCard(value)}\n onClose={() => setEditing(null)}\n />\n )}\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -179,7 +179,7 @@ var LogsPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
179
179
|
children: "Use Power Logs"
|
|
180
180
|
}), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
181
181
|
className: "power-settings-hint",
|
|
182
|
-
children: "Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled. Temporary captures follow the retention settings below and are deleted when Power Logs stops."
|
|
182
|
+
children: "Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled. Temporary captures follow the retention settings below and are deleted when Power Logs stops. Pinned snapshots remain until manually deleted."
|
|
183
183
|
})] }),
|
|
184
184
|
/* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
185
185
|
className: "power-settings-hint",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs-preferences.js","names":[],"sources":["../../../src/renderer/preferences/logs-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { POWER_LOGS_DEFAULT_LIMITS, type PowerLogsLimits } from \"../../common/power-logs\";\nimport { applyPowerLogsLimits } from \"../../common/power-logs-limits\";\nimport { LogsPreferencesStore } from \"../../common/store/logs-preferences-store\";\n\nconst MiB = 1024 * 1024;\ninterface LimitPreset {\n label: string;\n limits: Partial<PowerLogsLimits>;\n}\ninterface LimitSetting {\n key: keyof PowerLogsLimits;\n label: string;\n hint: string;\n presets: LimitPreset[];\n describe(limits: PowerLogsLimits): string;\n}\nconst settings: LimitSetting[] = [\n {\n key: \"liveRows\",\n label: \"Live buffer\",\n hint: \"Maximum rows and memory kept in the live log view.\",\n presets: [1000, 5000, 10000, 50000, 100000].map((liveRows, index) => ({\n label: `${liveRows.toLocaleString(\"en-US\")} rows / ${[2, 8, 16, 80, 160][index]} MiB`,\n limits: { liveRows, liveBytes: [2, 8, 16, 80, 160][index] * MiB },\n })),\n describe: (limits) => `${limits.liveRows.toLocaleString(\"en-US\")} rows / ${limits.liveBytes / MiB} MiB`,\n },\n {\n key: \"historyLines\",\n label: \"History per container\",\n hint: \"Maximum recent lines and data fetched for each container.\",\n presets: [500, 1000, 5000].map((historyLines, index) => ({\n label: `${historyLines.toLocaleString(\"en-US\")} lines / ${[0.5, 1, 5][index]} MiB`,\n limits: { historyLines, historyBytes: [0.5, 1, 5][index] * MiB },\n })),\n describe: (limits) => `${limits.historyLines.toLocaleString(\"en-US\")} lines / ${limits.historyBytes / MiB} MiB`,\n },\n {\n key: \"captureBytes\",\n label: \"Capture size\",\n hint: \"Maximum data stored in each temporary capture.\",\n presets: [64, 128, 256, 512].map((size) => ({\n label: `${size} MiB`,\n limits: { captureBytes: size * MiB },\n })),\n describe: (limits) => `${limits.captureBytes / MiB} MiB`,\n },\n {\n key: \"captures\",\n label: \"Saved captures\",\n hint: \"Maximum number of temporary captures retained.\",\n presets: [1, 3, 5, 10].map((captures) => ({\n label: `${captures} ${captures === 1 ? \"capture\" : \"captures\"}`,\n limits: { captures },\n })),\n describe: (limits) => `${limits.captures} captures`,\n },\n {\n key: \"ttlMs\",\n label: \"Retention\",\n hint: \"How long temporary captures remain available.\",\n presets: [30, 60, 360, 1440, 4320].map((minutes) => ({\n label:\n minutes >= 1440\n ? `${minutes / 1440} ${minutes === 1440 ? \"day\" : \"days\"}`\n : minutes < 60\n ? `${minutes} minutes`\n : `${minutes / 60} ${minutes === 60 ? \"hour\" : \"hours\"}`,\n limits: { ttlMs: minutes * 60000 },\n })),\n describe: (limits) => `${limits.ttlMs / 60000} minutes`,\n },\n];\n\nconst LogLimitSelect = observer(function LogLimitSelect({\n setting,\n preferences,\n}: {\n setting: LimitSetting;\n preferences: LogsPreferencesStore;\n}) {\n const selected = setting.presets.findIndex((preset) =>\n Object.entries(preset.limits).every(([key, value]) => preferences.limits[key as keyof PowerLogsLimits] === value),\n );\n const options = setting.presets.map((preset, index) => ({ value: String(index), label: preset.label }));\n if (selected === -1) options.push({ value: \"custom\", label: `Custom: ${setting.describe(preferences.limits)}` });\n const id = `freelens-power-logs-${setting.key}`;\n return (\n <div\n className=\"power-settings-row\"\n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 20 }}\n >\n <div>\n <label id={`${id}-label`} htmlFor={id}>\n {setting.label}\n </label>\n <div className=\"power-settings-hint\">{setting.hint}</div>\n </div>\n <div style={{ width: 260, maxWidth: \"100%\", flexShrink: 0 }}>\n <Renderer.Component.Select\n id={id}\n aria-labelledby={`${id}-label`}\n options={options}\n value={selected === -1 ? \"custom\" : String(selected)}\n isSearchable={false}\n isClearable={false}\n onChange={(option) => {\n if (!option || option.value === \"custom\") return;\n const preset = setting.presets[Number(option.value)];\n if (!preset) return;\n preferences.limits = { ...preferences.limits, ...preset.limits };\n applyPowerLogsLimits(preferences.limits);\n }}\n />\n </div>\n </div>\n );\n});\n\nexport const LogsPreferences = observer(() => {\n const preferences = LogsPreferencesStore.getInstanceOrCreate<LogsPreferencesStore>();\n return (\n <div style={{ display: \"grid\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Use Power Logs\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled.\n Temporary captures follow the retention settings below and are deleted when Power Logs stops.\n </div>\n </div>\n <div className=\"power-settings-hint\">\n Changes apply to new requests, captures and SQL queries. Existing captures retain their capacity and expiry.\n </div>\n {settings.map((setting) => (\n <LogLimitSelect key={setting.key} setting={setting} preferences={preferences} />\n ))}\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <Renderer.Component.Button\n onClick={() => {\n preferences.limits = { ...POWER_LOGS_DEFAULT_LIMITS };\n applyPowerLogsLimits(preferences.limits);\n }}\n >\n <Renderer.Component.Icon material=\"restore\" size={16} /> Reset log limits\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"logs-preferences.js","names":[],"sources":["../../../src/renderer/preferences/logs-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { POWER_LOGS_DEFAULT_LIMITS, type PowerLogsLimits } from \"../../common/power-logs\";\nimport { applyPowerLogsLimits } from \"../../common/power-logs-limits\";\nimport { LogsPreferencesStore } from \"../../common/store/logs-preferences-store\";\n\nconst MiB = 1024 * 1024;\ninterface LimitPreset {\n label: string;\n limits: Partial<PowerLogsLimits>;\n}\ninterface LimitSetting {\n key: keyof PowerLogsLimits;\n label: string;\n hint: string;\n presets: LimitPreset[];\n describe(limits: PowerLogsLimits): string;\n}\nconst settings: LimitSetting[] = [\n {\n key: \"liveRows\",\n label: \"Live buffer\",\n hint: \"Maximum rows and memory kept in the live log view.\",\n presets: [1000, 5000, 10000, 50000, 100000].map((liveRows, index) => ({\n label: `${liveRows.toLocaleString(\"en-US\")} rows / ${[2, 8, 16, 80, 160][index]} MiB`,\n limits: { liveRows, liveBytes: [2, 8, 16, 80, 160][index] * MiB },\n })),\n describe: (limits) => `${limits.liveRows.toLocaleString(\"en-US\")} rows / ${limits.liveBytes / MiB} MiB`,\n },\n {\n key: \"historyLines\",\n label: \"History per container\",\n hint: \"Maximum recent lines and data fetched for each container.\",\n presets: [500, 1000, 5000].map((historyLines, index) => ({\n label: `${historyLines.toLocaleString(\"en-US\")} lines / ${[0.5, 1, 5][index]} MiB`,\n limits: { historyLines, historyBytes: [0.5, 1, 5][index] * MiB },\n })),\n describe: (limits) => `${limits.historyLines.toLocaleString(\"en-US\")} lines / ${limits.historyBytes / MiB} MiB`,\n },\n {\n key: \"captureBytes\",\n label: \"Capture size\",\n hint: \"Maximum data stored in each temporary capture.\",\n presets: [64, 128, 256, 512].map((size) => ({\n label: `${size} MiB`,\n limits: { captureBytes: size * MiB },\n })),\n describe: (limits) => `${limits.captureBytes / MiB} MiB`,\n },\n {\n key: \"captures\",\n label: \"Saved captures\",\n hint: \"Maximum number of temporary captures retained.\",\n presets: [1, 3, 5, 10].map((captures) => ({\n label: `${captures} ${captures === 1 ? \"capture\" : \"captures\"}`,\n limits: { captures },\n })),\n describe: (limits) => `${limits.captures} captures`,\n },\n {\n key: \"ttlMs\",\n label: \"Retention\",\n hint: \"How long temporary captures remain available.\",\n presets: [30, 60, 360, 1440, 4320].map((minutes) => ({\n label:\n minutes >= 1440\n ? `${minutes / 1440} ${minutes === 1440 ? \"day\" : \"days\"}`\n : minutes < 60\n ? `${minutes} minutes`\n : `${minutes / 60} ${minutes === 60 ? \"hour\" : \"hours\"}`,\n limits: { ttlMs: minutes * 60000 },\n })),\n describe: (limits) => `${limits.ttlMs / 60000} minutes`,\n },\n];\n\nconst LogLimitSelect = observer(function LogLimitSelect({\n setting,\n preferences,\n}: {\n setting: LimitSetting;\n preferences: LogsPreferencesStore;\n}) {\n const selected = setting.presets.findIndex((preset) =>\n Object.entries(preset.limits).every(([key, value]) => preferences.limits[key as keyof PowerLogsLimits] === value),\n );\n const options = setting.presets.map((preset, index) => ({ value: String(index), label: preset.label }));\n if (selected === -1) options.push({ value: \"custom\", label: `Custom: ${setting.describe(preferences.limits)}` });\n const id = `freelens-power-logs-${setting.key}`;\n return (\n <div\n className=\"power-settings-row\"\n style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 20 }}\n >\n <div>\n <label id={`${id}-label`} htmlFor={id}>\n {setting.label}\n </label>\n <div className=\"power-settings-hint\">{setting.hint}</div>\n </div>\n <div style={{ width: 260, maxWidth: \"100%\", flexShrink: 0 }}>\n <Renderer.Component.Select\n id={id}\n aria-labelledby={`${id}-label`}\n options={options}\n value={selected === -1 ? \"custom\" : String(selected)}\n isSearchable={false}\n isClearable={false}\n onChange={(option) => {\n if (!option || option.value === \"custom\") return;\n const preset = setting.presets[Number(option.value)];\n if (!preset) return;\n preferences.limits = { ...preferences.limits, ...preset.limits };\n applyPowerLogsLimits(preferences.limits);\n }}\n />\n </div>\n </div>\n );\n});\n\nexport const LogsPreferences = observer(() => {\n const preferences = LogsPreferencesStore.getInstanceOrCreate<LogsPreferencesStore>();\n return (\n <div style={{ display: \"grid\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Use Power Logs\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Colored workload logs and temporary SQLite captures for SQL analysis. Native logs return when disabled.\n Temporary captures follow the retention settings below and are deleted when Power Logs stops. Pinned snapshots\n remain until manually deleted.\n </div>\n </div>\n <div className=\"power-settings-hint\">\n Changes apply to new requests, captures and SQL queries. Existing captures retain their capacity and expiry.\n </div>\n {settings.map((setting) => (\n <LogLimitSelect key={setting.key} setting={setting} preferences={preferences} />\n ))}\n <div style={{ display: \"flex\", justifyContent: \"flex-end\" }}>\n <Renderer.Component.Button\n onClick={() => {\n preferences.limits = { ...POWER_LOGS_DEFAULT_LIMITS };\n applyPowerLogsLimits(preferences.limits);\n }}\n >\n <Renderer.Component.Icon material=\"restore\" size={16} /> Reset log limits\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ const require_monitoring_history = require("../src/common/monitoring-history.js"
|
|
|
4
4
|
const require_monitoring_preferences_store = require("../src/common/store/monitoring-preferences-store.js");
|
|
5
5
|
const require__global_external_react = require("../_virtual/_global-external_react.js");
|
|
6
6
|
const require_jsx_runtime = require("../_virtual/_global-external_react/jsx-runtime.js");
|
|
7
|
+
const require_native_tooltip = require("../native-tooltip.js");
|
|
7
8
|
const require_monitoring_history$1 = require("../monitoring-history.js");
|
|
8
9
|
//#region src/renderer/preferences/monitoring-preferences.tsx
|
|
9
10
|
var MonitoringPreferences = require__global_external_mobx_react.observer(() => {
|
|
@@ -72,10 +73,12 @@ var MonitoringPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
72
73
|
preferences.historyEnabled = value;
|
|
73
74
|
},
|
|
74
75
|
children: "Keep local history"
|
|
75
|
-
}), /* @__PURE__ */ require_jsx_runtime.jsx(
|
|
76
|
-
className: "power-settings-hint",
|
|
76
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
77
77
|
title: "SQLite storage. Collects while the cluster view is active. Resolution: 30 seconds for 2 hours, 5 minutes for 24 hours, 30 minutes for 7 days. Disabling preserves saved history.",
|
|
78
|
-
children:
|
|
78
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("div", {
|
|
79
|
+
className: "power-settings-hint",
|
|
80
|
+
children: "Up to 7 days, limited to 100 MiB."
|
|
81
|
+
})
|
|
79
82
|
})] }),
|
|
80
83
|
/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
81
84
|
style: {
|
|
@@ -134,6 +137,7 @@ var MonitoringPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
134
137
|
})
|
|
135
138
|
]
|
|
136
139
|
}), /* @__PURE__ */ require_jsx_runtime.jsxs(require_extensions.Renderer.Component.Button, {
|
|
140
|
+
tooltip: "Delete locally collected metric history without changing other settings",
|
|
137
141
|
style: {
|
|
138
142
|
flexShrink: 0,
|
|
139
143
|
display: "inline-flex",
|
|
@@ -149,7 +153,6 @@ var MonitoringPreferences = require__global_external_mobx_react.observer(() => {
|
|
|
149
153
|
background: "var(--contentColor)",
|
|
150
154
|
color: "var(--textColorSecondary)"
|
|
151
155
|
},
|
|
152
|
-
title: "Delete locally collected metric history without changing other settings",
|
|
153
156
|
onClick: () => {
|
|
154
157
|
require_monitoring_history$1.monitoringHistory.clear().then(refresh).catch(() => setStatus((previous) => ({
|
|
155
158
|
available: previous?.available ?? false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitoring-preferences.js","names":[],"sources":["../../../src/renderer/preferences/monitoring-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { HISTORY_MAX_BYTES, type HistoryStatus } from \"../../common/monitoring-history\";\nimport { MonitoringPreferencesStore } from \"../../common/store/monitoring-preferences-store\";\nimport { monitoringHistory } from \"../monitoring-history\";\n\nexport const MonitoringPreferences = observer(() => {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const [status, setStatus] = useState<HistoryStatus>();\n const refresh = () => {\n void monitoringHistory\n .status()\n .then(setStatus)\n .catch(() =>\n setStatus({\n available: false,\n enabled: preferences.historyEnabled,\n bytes: 0,\n samples: 0,\n error: \"History service unavailable\",\n }),\n );\n };\n useEffect(refresh, [preferences.historyEnabled]);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.diagnosticsVisible}\n onChange={(value) => {\n preferences.diagnosticsVisible = value;\n }}\n >\n Show Diagnostics in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">Resource consumers, application events and Pending diagnostics.</div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.relationshipsVisible}\n onChange={(value) => {\n preferences.relationshipsVisible = value;\n }}\n >\n Show Relationships in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Focused resource connections from API evidence, with links to related objects.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.resourceSearchEnabled}\n onChange={(value) => {\n preferences.resourceSearchEnabled = value;\n }}\n >\n Enable resource search (Shift–Shift)\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Search resources with Shift–Shift. Turning this off stops keyboard search and background indexing.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Metrics-server monitoring\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n CPU/RAM charts for clusters, nodes and pods. Keeps 30 minutes of live samples.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.historyEnabled}\n onChange={(value) => {\n preferences.historyEnabled = value;\n }}\n >\n Keep local history\n </Renderer.Component.Switch>\n <
|
|
1
|
+
{"version":3,"file":"monitoring-preferences.js","names":[],"sources":["../../../src/renderer/preferences/monitoring-preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useState } from \"react\";\nimport { HISTORY_MAX_BYTES, type HistoryStatus } from \"../../common/monitoring-history\";\nimport { MonitoringPreferencesStore } from \"../../common/store/monitoring-preferences-store\";\nimport { monitoringHistory } from \"../monitoring-history\";\nimport { NativeTooltip } from \"../native-tooltip\";\n\nexport const MonitoringPreferences = observer(() => {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const [status, setStatus] = useState<HistoryStatus>();\n const refresh = () => {\n void monitoringHistory\n .status()\n .then(setStatus)\n .catch(() =>\n setStatus({\n available: false,\n enabled: preferences.historyEnabled,\n bytes: 0,\n samples: 0,\n error: \"History service unavailable\",\n }),\n );\n };\n useEffect(refresh, [preferences.historyEnabled]);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 20 }}>\n <div>\n <Renderer.Component.Switch\n checked={preferences.diagnosticsVisible}\n onChange={(value) => {\n preferences.diagnosticsVisible = value;\n }}\n >\n Show Diagnostics in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">Resource consumers, application events and Pending diagnostics.</div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.relationshipsVisible}\n onChange={(value) => {\n preferences.relationshipsVisible = value;\n }}\n >\n Show Relationships in sidebar\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Focused resource connections from API evidence, with links to related objects.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.resourceSearchEnabled}\n onChange={(value) => {\n preferences.resourceSearchEnabled = value;\n }}\n >\n Enable resource search (Shift–Shift)\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n Search resources with Shift–Shift. Turning this off stops keyboard search and background indexing.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.enabled}\n onChange={(value) => {\n preferences.enabled = value;\n }}\n >\n Metrics-server monitoring\n </Renderer.Component.Switch>\n <div className=\"power-settings-hint\">\n CPU/RAM charts for clusters, nodes and pods. Keeps 30 minutes of live samples.\n </div>\n </div>\n <div>\n <Renderer.Component.Switch\n checked={preferences.historyEnabled}\n onChange={(value) => {\n preferences.historyEnabled = value;\n }}\n >\n Keep local history\n </Renderer.Component.Switch>\n <NativeTooltip title=\"SQLite storage. Collects while the cluster view is active. Resolution: 30 seconds for 2 hours, 5 minutes for 24 hours, 30 minutes for 7 days. Disabling preserves saved history.\">\n <div className=\"power-settings-hint\">Up to 7 days, limited to 100 MiB.</div>\n </NativeTooltip>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 12 }}>\n <div style={{ flex: 1, minWidth: 0 }} role=\"status\">\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"baseline\", gap: 12 }}>\n <span>Local storage</span>\n <span style={{ fontVariantNumeric: \"tabular-nums\", color: \"var(--textColorSecondary)\" }}>\n {status?.available\n ? `${(status.bytes / 1024 / 1024).toFixed(2)} / ${HISTORY_MAX_BYTES / 1024 / 1024} MiB`\n : \"— / 100 MiB\"}\n </span>\n </div>\n {status?.available && (\n <div\n role=\"progressbar\"\n aria-label=\"Local history storage\"\n aria-valuemin={0}\n aria-valuemax={HISTORY_MAX_BYTES}\n aria-valuenow={status.bytes}\n aria-valuetext={`${(status.bytes / 1024 / 1024).toFixed(2)} of 100 MiB`}\n style={{ height: 4, marginTop: 8, borderRadius: 2, overflow: \"hidden\", background: \"var(--borderColor)\" }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, (status.bytes / HISTORY_MAX_BYTES) * 100))}%`,\n background: \"var(--primary)\",\n transition: \"width 180ms ease\",\n }}\n />\n </div>\n )}\n <div className=\"power-settings-hint\" style={{ marginTop: 6 }}>\n {status?.error ??\n (status?.available\n ? `${status.samples.toLocaleString()} metric buckets · 7-day retention`\n : \"Checking history storage…\")}\n </div>\n </div>\n <Renderer.Component.Button\n tooltip=\"Delete locally collected metric history without changing other settings\"\n style={{\n flexShrink: 0,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 6,\n height: 30,\n padding: \"0 10px\",\n fontSize: 12,\n lineHeight: \"16px\",\n border: \"1px solid var(--borderFaintColor)\",\n borderRadius: 6,\n background: \"var(--contentColor)\",\n color: \"var(--textColorSecondary)\",\n }}\n onClick={() => {\n void monitoringHistory\n .clear()\n .then(refresh)\n .catch(() =>\n setStatus((previous) => ({\n available: previous?.available ?? false,\n enabled: preferences.historyEnabled,\n bytes: previous?.bytes ?? 0,\n samples: previous?.samples ?? 0,\n error: \"Unable to clear local history. Try again.\",\n })),\n );\n }}\n >\n <Renderer.Component.Icon material=\"delete_outline\" size={14} />\n <span>Clear</span>\n </Renderer.Component.Button>\n </div>\n </div>\n );\n});\n"],"mappings":"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"}
|
|
@@ -124,9 +124,9 @@ var PowerPreferences = () => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
|
124
124
|
className: "power-preferences-section-links",
|
|
125
125
|
"aria-label": "Settings sections",
|
|
126
126
|
children: sectionLinks.map(({ id, title, icon }) => /* @__PURE__ */ require_jsx_runtime.jsxs(require_extensions.Renderer.Component.Button, {
|
|
127
|
+
tooltip: `Jump to ${title} settings`,
|
|
127
128
|
className: "power-settings-section-link",
|
|
128
129
|
"aria-label": title,
|
|
129
|
-
title: `Jump to ${title} settings`,
|
|
130
130
|
onClick: (event) => {
|
|
131
131
|
event.preventDefault();
|
|
132
132
|
require_section_navigation.focusPreferencesSection(id);
|
|
@@ -173,13 +173,13 @@ var PowerPreferences = () => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
|
173
173
|
marginTop: 20
|
|
174
174
|
},
|
|
175
175
|
children: /* @__PURE__ */ require_jsx_runtime.jsxs(require_extensions.Renderer.Component.Button, {
|
|
176
|
+
tooltip: "Create matching icons for your saved clusters",
|
|
176
177
|
style: {
|
|
177
178
|
display: "inline-flex",
|
|
178
179
|
alignItems: "center",
|
|
179
180
|
gap: 6
|
|
180
181
|
},
|
|
181
182
|
onClick: () => require_extensions.Renderer.Navigation.navigate(`/extension/${require_extension_info.EXTENSION_ID}/cluster-icons`),
|
|
182
|
-
title: "Create matching icons for your saved clusters",
|
|
183
183
|
children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
|
|
184
184
|
material: "palette",
|
|
185
185
|
size: 16
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { EXTENSION_ID } from \"../../common/extension-info\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { LogsPreferences } from \"./logs-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { focusPreferencesSection } from \"./section-navigation\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; container: power-preferences / inline-size; }\n .freelens-power-preferences .power-preferences-section-links {\n display:flex; align-items:center; width:100%; gap:8px; overflow-x:auto;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n flex:1 0 auto; width:auto; min-width:max-content; min-height:32px; padding:4px 2px;\n border: 0; border-radius: 4px; background: transparent; box-shadow: none;\n color: var(--textColorSecondary); text-transform: none; white-space: nowrap; cursor: pointer;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:hover {\n color: var(--primary); background: transparent; box-shadow: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link::before {\n content: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:focus-visible {\n color: var(--primary); background: transparent; box-shadow: none;\n outline: 2px solid var(--primary); outline-offset: 2px;\n }\n @container power-preferences (max-width:660px) { .power-preferences-section-links { font-size:12px; } }\n .freelens-power-preferences section[id] { scroll-margin-top: 16px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nconst sectionLinks = [\n { id: \"safety\", title: \"Safety\", icon: \"lock_outline\" },\n { id: \"appearance\", title: \"Appearance\", icon: \"palette\" },\n { id: \"monitoring\", title: \"Monitoring\", icon: \"show_chart\" },\n { id: \"logs\", title: \"Logs\", icon: \"subject\" },\n { id: \"shell\", title: \"Shell\", icon: \"vpn_key\" },\n { id: \"ai\", title: \"AI\", icon: \"chat_bubble_outline\" },\n { id: \"dashboard\", title: \"Dashboard\", icon: \"dashboard\" },\n];\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <nav className=\"power-preferences-section-links\" aria-label=\"Settings sections\">\n {sectionLinks.map(({ id, title, icon }) => (\n <Renderer.Component.Button\n key={id}\n className=\"power-settings-section-link\"\n aria-label={title}\n title={`Jump to ${title} settings`}\n onClick={(event) => {\n event.preventDefault();\n focusPreferencesSection(id);\n }}\n >\n <Renderer.Component.Icon material={icon} size={16} /> {title}\n </Renderer.Component.Button>\n ))}\n </nav>\n <section id=\"freelens-power-safety-section\" tabIndex={-1} aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section id=\"freelens-power-appearance-section\" tabIndex={-1} aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", marginTop: 20 }}>\n <Renderer.Component.Button\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => Renderer.Navigation.navigate(`/extension/${EXTENSION_ID}/cluster-icons`)}\n title=\"Create matching icons for your saved clusters\"\n >\n <Renderer.Component.Icon material=\"palette\" size={16} /> Cluster icons\n </Renderer.Component.Button>\n </div>\n </section>\n <section id=\"freelens-power-monitoring-section\" tabIndex={-1} aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section id=\"freelens-power-logs-section\" tabIndex={-1} aria-labelledby=\"freelens-power-logs-title\">\n <h3 id=\"freelens-power-logs-title\">\n <Renderer.Component.Icon material=\"subject\" size={20} /> Power Logs\n </h3>\n <LogsPreferences />\n </section>\n <section id=\"freelens-power-shell-section\" tabIndex={-1} aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section id=\"freelens-power-ai-section\" tabIndex={-1} aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section id=\"freelens-power-dashboard-section\" tabIndex={-1} aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preferences.js","names":[],"sources":["../../../src/renderer/preferences/preferences.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { EXTENSION_ID } from \"../../common/extension-info\";\nimport { AiPreferences } from \"./ai-preferences\";\nimport { AppearancePreferences } from \"./appearance-preferences\";\nimport { DashboardPreferences } from \"./dashboard-preferences\";\nimport { LogsPreferences } from \"./logs-preferences\";\nimport { MonitoringPreferences } from \"./monitoring-preferences\";\nimport { NodeShellPreferences } from \"./node-shell-preferences\";\nimport { PowerPreferencesToggle } from \"./power-preferences\";\nimport { ReadOnlyPreferences } from \"./read-only-preferences\";\nimport { focusPreferencesSection } from \"./section-navigation\";\nimport { SettingsExport } from \"./settings-export\";\n\nconst styles = `\n .power-preferences-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }\n .power-preferences-header-actions { display: inline-flex; margin-left: auto; flex-shrink: 0; }\n #freelens-power-settings > .SubTitle,\n #freelens-power-settings > .hint,\n #freelens-power-settings + hr { display: none; }\n .freelens-power-preferences { display: grid; gap: 24px; max-width: 760px; container: power-preferences / inline-size; }\n .freelens-power-preferences .power-preferences-section-links {\n display:flex; align-items:center; width:100%; gap:8px; overflow-x:auto;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link {\n display: inline-flex; align-items: center; justify-content: center; gap: 6px;\n flex:1 0 auto; width:auto; min-width:max-content; min-height:32px; padding:4px 2px;\n border: 0; border-radius: 4px; background: transparent; box-shadow: none;\n color: var(--textColorSecondary); text-transform: none; white-space: nowrap; cursor: pointer;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:hover {\n color: var(--primary); background: transparent; box-shadow: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link::before {\n content: none;\n }\n :root .freelens-power-preferences .power-preferences-section-links button.power-settings-section-link:focus-visible {\n color: var(--primary); background: transparent; box-shadow: none;\n outline: 2px solid var(--primary); outline-offset: 2px;\n }\n @container power-preferences (max-width:660px) { .power-preferences-section-links { font-size:12px; } }\n .freelens-power-preferences section[id] { scroll-margin-top: 16px; }\n .freelens-power-preferences section {\n padding: 24px; border: 1px solid var(--borderFaintColor);\n border-radius: 12px; background: var(--contentColor);\n }\n .freelens-power-preferences button, .freelens-power-preferences .Button { transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease; }\n :root .freelens-power-preferences button.power-settings-icon-action,\n :root .power-preferences-header-actions button.power-settings-icon-action {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; min-width: 32px; padding: 0; flex-shrink: 0;\n border: 0; border-radius: 6px; background: transparent; color: var(--textColorSecondary); cursor: pointer;\n transition: color 160ms ease, background-color 160ms ease;\n }\n :root .freelens-power-preferences button.power-settings-icon-action:not(:disabled):hover,\n :root .power-preferences-header-actions button.power-settings-icon-action:not(:disabled):hover {\n color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);\n }\n :root .freelens-power-preferences button.power-settings-icon-action:focus-visible,\n :root .power-preferences-header-actions button.power-settings-icon-action:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }\n :root .freelens-power-preferences button.power-settings-icon-action:disabled,\n :root .power-preferences-header-actions button.power-settings-icon-action:disabled { opacity: 0.4; cursor: default; }\n .freelens-power-preferences h3 {\n display: flex; align-items: center; gap: 10px; margin: 0 0 24px; font-size: 16px; font-weight: 600; color: var(--textColorAccent);\n }\n .freelens-power-preferences label[data-testid=\"switch\"] {\n display: flex; width: 100%; align-items: center; justify-content: space-between;\n }\n .freelens-power-preferences .power-settings-hint {\n margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--textColorSecondary);\n }\n @media (max-width: 760px) {\n .freelens-power-preferences section { padding: 18px; }\n .freelens-power-preferences .power-settings-row { flex-wrap: wrap; }\n }\n`;\n\nconst sectionLinks = [\n { id: \"safety\", title: \"Safety\", icon: \"lock_outline\" },\n { id: \"appearance\", title: \"Appearance\", icon: \"palette\" },\n { id: \"monitoring\", title: \"Monitoring\", icon: \"show_chart\" },\n { id: \"logs\", title: \"Logs\", icon: \"subject\" },\n { id: \"shell\", title: \"Shell\", icon: \"vpn_key\" },\n { id: \"ai\", title: \"AI\", icon: \"chat_bubble_outline\" },\n { id: \"dashboard\", title: \"Dashboard\", icon: \"dashboard\" },\n];\n\nexport const PowerPreferences = () => (\n <div className=\"freelens-power-preferences\">\n <style>{styles}</style>\n <SettingsExport />\n <section aria-label=\"Freelens Power\">\n <PowerPreferencesToggle />\n </section>\n <nav className=\"power-preferences-section-links\" aria-label=\"Settings sections\">\n {sectionLinks.map(({ id, title, icon }) => (\n <Renderer.Component.Button\n tooltip={`Jump to ${title} settings`}\n key={id}\n className=\"power-settings-section-link\"\n aria-label={title}\n onClick={(event) => {\n event.preventDefault();\n focusPreferencesSection(id);\n }}\n >\n <Renderer.Component.Icon material={icon} size={16} /> {title}\n </Renderer.Component.Button>\n ))}\n </nav>\n <section id=\"freelens-power-safety-section\" tabIndex={-1} aria-labelledby=\"freelens-power-safety-title\">\n <h3 id=\"freelens-power-safety-title\">\n <Renderer.Component.Icon material=\"lock_outline\" size={20} /> Read-only mode\n </h3>\n <ReadOnlyPreferences />\n </section>\n <section id=\"freelens-power-appearance-section\" tabIndex={-1} aria-labelledby=\"freelens-power-appearance-title\">\n <h3 id=\"freelens-power-appearance-title\">\n <Renderer.Component.Icon material=\"palette\" size={20} /> Appearance\n </h3>\n <AppearancePreferences />\n <div style={{ display: \"flex\", justifyContent: \"flex-end\", marginTop: 20 }}>\n <Renderer.Component.Button\n tooltip=\"Create matching icons for your saved clusters\"\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}\n onClick={() => Renderer.Navigation.navigate(`/extension/${EXTENSION_ID}/cluster-icons`)}\n >\n <Renderer.Component.Icon material=\"palette\" size={16} /> Cluster icons\n </Renderer.Component.Button>\n </div>\n </section>\n <section id=\"freelens-power-monitoring-section\" tabIndex={-1} aria-labelledby=\"freelens-power-monitoring-title\">\n <h3 id=\"freelens-power-monitoring-title\">\n <Renderer.Component.Icon material=\"show_chart\" size={20} /> Monitoring\n </h3>\n <MonitoringPreferences />\n </section>\n <section id=\"freelens-power-logs-section\" tabIndex={-1} aria-labelledby=\"freelens-power-logs-title\">\n <h3 id=\"freelens-power-logs-title\">\n <Renderer.Component.Icon material=\"subject\" size={20} /> Power Logs\n </h3>\n <LogsPreferences />\n </section>\n <section id=\"freelens-power-shell-section\" tabIndex={-1} aria-labelledby=\"freelens-power-shell-title\">\n <h3 id=\"freelens-power-shell-title\">\n <Renderer.Component.Icon material=\"vpn_key\" size={20} /> Secure Node Shell\n </h3>\n <NodeShellPreferences />\n </section>\n <section id=\"freelens-power-ai-section\" tabIndex={-1} aria-labelledby=\"freelens-power-ai-title\">\n <h3 id=\"freelens-power-ai-title\">\n <Renderer.Component.Icon material=\"chat_bubble_outline\" size={20} /> AI assistant\n </h3>\n <AiPreferences />\n </section>\n <section id=\"freelens-power-dashboard-section\" tabIndex={-1} aria-labelledby=\"freelens-power-dashboard-title\">\n <h3 id=\"freelens-power-dashboard-title\">\n <Renderer.Component.Icon material=\"dashboard\" size={20} /> Dashboard\n </h3>\n <DashboardPreferences />\n </section>\n </div>\n);\n"],"mappings":"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"}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
const require_extensions = require("../_virtual/_global-external_@freelensapp/extensions.js");
|
|
2
2
|
const require_jsx_runtime = require("../_virtual/_global-external_react/jsx-runtime.js");
|
|
3
|
+
const require_native_tooltip = require("../native-tooltip.js");
|
|
3
4
|
//#region src/renderer/preferences/settings-icon-action.tsx
|
|
4
5
|
function SettingsIconAction({ material, label, disabled = false, onClick }) {
|
|
5
|
-
return /* @__PURE__ */ require_jsx_runtime.jsx(
|
|
6
|
-
type: "button",
|
|
7
|
-
className: "power-settings-icon-action",
|
|
8
|
-
"aria-label": label,
|
|
6
|
+
return /* @__PURE__ */ require_jsx_runtime.jsx(require_native_tooltip.NativeTooltip, {
|
|
9
7
|
title: label,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
9
|
+
type: "button",
|
|
10
|
+
className: "power-settings-icon-action",
|
|
11
|
+
"aria-label": label,
|
|
12
|
+
disabled,
|
|
13
|
+
onClick,
|
|
14
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
|
|
15
|
+
material,
|
|
16
|
+
size: 18
|
|
17
|
+
})
|
|
17
18
|
})
|
|
18
19
|
});
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-icon-action.js","names":[],"sources":["../../../src/renderer/preferences/settings-icon-action.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\n\nexport function SettingsIconAction({\n material,\n label,\n disabled = false,\n onClick,\n}: {\n material: string;\n label: string;\n disabled?: boolean;\n onClick: () => void;\n}) {\n return (\n <button\n
|
|
1
|
+
{"version":3,"file":"settings-icon-action.js","names":[],"sources":["../../../src/renderer/preferences/settings-icon-action.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { NativeTooltip } from \"../native-tooltip\";\n\nexport function SettingsIconAction({\n material,\n label,\n disabled = false,\n onClick,\n}: {\n material: string;\n label: string;\n disabled?: boolean;\n onClick: () => void;\n}) {\n return (\n <NativeTooltip title={label}>\n <button\n type=\"button\"\n className=\"power-settings-icon-action\"\n aria-label={label}\n disabled={disabled}\n onClick={onClick}\n >\n <Renderer.Component.Icon material={material} size={18} />\n </button>\n </NativeTooltip>\n );\n}\n"],"mappings":";;;;AAGA,SAAgB,mBAAmB,EACjC,UACA,OACA,WAAW,OACX,WAMC;CACD,OACE,oCAAA,IAAC,uBAAA,eAAD;EAAe,OAAO;YACpB,oCAAA,IAAC,UAAD;GACE,MAAK;GACL,WAAU;GACV,cAAY;GACF;GACD;aAET,oCAAA,IAAC,mBAAA,SAAS,UAAU,MAApB;IAAmC;IAAU,MAAM;GAAK,CAAA;EAClD,CAAA;CACK,CAAA;AAEnB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/renderer/relationship-map-finding.ts
|
|
2
|
+
function relationshipMapFinding(clusterId, namespace, service, graph, hideUpstreams) {
|
|
3
|
+
const text = (value) => value.slice(0, 300);
|
|
4
|
+
const visible = graph.nodes.filter((node) => !hideUpstreams || node.role !== "upstream");
|
|
5
|
+
const nodes = visible.slice(0, 60);
|
|
6
|
+
const ids = new Set(nodes.map((node) => node.id));
|
|
7
|
+
const edges = graph.edges.filter((edge) => ids.has(edge.from) && ids.has(edge.to));
|
|
8
|
+
const snapshot = {
|
|
9
|
+
namespace,
|
|
10
|
+
service,
|
|
11
|
+
summary: text(graph.diagnostics.summary),
|
|
12
|
+
nodes: nodes.map(({ id, kind, name, role, detail, tone, inferred }) => ({
|
|
13
|
+
id: text(id),
|
|
14
|
+
kind,
|
|
15
|
+
name: text(name),
|
|
16
|
+
role,
|
|
17
|
+
detail: text(detail),
|
|
18
|
+
tone,
|
|
19
|
+
...inferred ? { inferred } : {}
|
|
20
|
+
})),
|
|
21
|
+
edges: edges.slice(0, 100).map(({ from, to, label }) => ({
|
|
22
|
+
from: text(from),
|
|
23
|
+
to: text(to),
|
|
24
|
+
label: text(label)
|
|
25
|
+
})),
|
|
26
|
+
gaps: graph.gaps.slice(0, 20).map(text),
|
|
27
|
+
omitted: graph.omitted + visible.length - nodes.length + Math.max(0, edges.length - 100),
|
|
28
|
+
upstreamsHidden: hideUpstreams,
|
|
29
|
+
scope: "Visible map snapshot from Kubernetes API evidence; does not prove network reachability"
|
|
30
|
+
};
|
|
31
|
+
let summary = JSON.stringify(snapshot);
|
|
32
|
+
while (summary.length > 8e3 && (snapshot.edges.length || snapshot.nodes.length)) {
|
|
33
|
+
if (snapshot.edges.length) snapshot.edges.pop();
|
|
34
|
+
else snapshot.nodes.pop();
|
|
35
|
+
snapshot.omitted++;
|
|
36
|
+
summary = JSON.stringify(snapshot);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
clusterId,
|
|
40
|
+
source: "relationships",
|
|
41
|
+
title: `Relationships · ${service}`,
|
|
42
|
+
resource: {
|
|
43
|
+
kind: "Service",
|
|
44
|
+
name: service,
|
|
45
|
+
namespace
|
|
46
|
+
},
|
|
47
|
+
summary
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
exports.relationshipMapFinding = relationshipMapFinding;
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=relationship-map-finding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-map-finding.js","names":[],"sources":["../../src/renderer/relationship-map-finding.ts"],"sourcesContent":["import type { buildResourceRelationships } from \"../common/resource-relationships\";\nimport type { DiagnosticFinding } from \"./ai-diagnostic-handoff\";\n\ntype RelationshipGraph = ReturnType<typeof buildResourceRelationships>;\n\nexport function relationshipMapFinding(\n clusterId: string,\n namespace: string,\n service: string,\n graph: RelationshipGraph,\n hideUpstreams: boolean,\n): DiagnosticFinding {\n const text = (value: string) => value.slice(0, 300);\n const visible = graph.nodes.filter((node) => !hideUpstreams || node.role !== \"upstream\");\n const nodes = visible.slice(0, 60);\n const ids = new Set(nodes.map((node) => node.id));\n const edges = graph.edges.filter((edge) => ids.has(edge.from) && ids.has(edge.to));\n const snapshot = {\n namespace,\n service,\n summary: text(graph.diagnostics.summary),\n nodes: nodes.map(({ id, kind, name, role, detail, tone, inferred }) => ({\n id: text(id),\n kind,\n name: text(name),\n role,\n detail: text(detail),\n tone,\n ...(inferred ? { inferred } : {}),\n })),\n edges: edges.slice(0, 100).map(({ from, to, label }) => ({ from: text(from), to: text(to), label: text(label) })),\n gaps: graph.gaps.slice(0, 20).map(text),\n omitted: graph.omitted + visible.length - nodes.length + Math.max(0, edges.length - 100),\n upstreamsHidden: hideUpstreams,\n scope: \"Visible map snapshot from Kubernetes API evidence; does not prove network reachability\",\n };\n let summary = JSON.stringify(snapshot);\n while (summary.length > 8000 && (snapshot.edges.length || snapshot.nodes.length)) {\n if (snapshot.edges.length) snapshot.edges.pop();\n else snapshot.nodes.pop();\n snapshot.omitted++;\n summary = JSON.stringify(snapshot);\n }\n return {\n clusterId,\n source: \"relationships\",\n title: `Relationships · ${service}`,\n resource: { kind: \"Service\", name: service, namespace },\n summary,\n };\n}\n"],"mappings":";AAKA,SAAgB,uBACd,WACA,WACA,SACA,OACA,eACmB;CACnB,MAAM,QAAQ,UAAkB,MAAM,MAAM,GAAG,GAAG;CAClD,MAAM,UAAU,MAAM,MAAM,QAAQ,SAAS,CAAC,iBAAiB,KAAK,SAAS,UAAU;CACvF,MAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE;CACjC,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC;CAChD,MAAM,QAAQ,MAAM,MAAM,QAAQ,SAAS,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,EAAE,CAAC;CACjF,MAAM,WAAW;EACf;EACA;EACA,SAAS,KAAK,MAAM,YAAY,OAAO;EACvC,OAAO,MAAM,KAAK,EAAE,IAAI,MAAM,MAAM,MAAM,QAAQ,MAAM,gBAAgB;GACtE,IAAI,KAAK,EAAE;GACX;GACA,MAAM,KAAK,IAAI;GACf;GACA,QAAQ,KAAK,MAAM;GACnB;GACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EACjC,EAAE;EACF,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,aAAa;GAAE,MAAM,KAAK,IAAI;GAAG,IAAI,KAAK,EAAE;GAAG,OAAO,KAAK,KAAK;EAAE,EAAE;EAChH,MAAM,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI;EACtC,SAAS,MAAM,UAAU,QAAQ,SAAS,MAAM,SAAS,KAAK,IAAI,GAAG,MAAM,SAAS,GAAG;EACvF,iBAAiB;EACjB,OAAO;CACT;CACA,IAAI,UAAU,KAAK,UAAU,QAAQ;CACrC,OAAO,QAAQ,SAAS,QAAS,SAAS,MAAM,UAAU,SAAS,MAAM,SAAS;EAChF,IAAI,SAAS,MAAM,QAAQ,SAAS,MAAM,IAAI;OACzC,SAAS,MAAM,IAAI;EACxB,SAAS;EACT,UAAU,KAAK,UAAU,QAAQ;CACnC;CACA,OAAO;EACL;EACA,QAAQ;EACR,OAAO,mBAAmB;EAC1B,UAAU;GAAE,MAAM;GAAW,MAAM;GAAS;EAAU;EACtD;CACF;AACF"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
//#region src/renderer/resource-relationships.css.ts
|
|
2
2
|
var resourceRelationshipsStyles = `
|
|
3
|
+
.power-relationships .graph-omitted-notice { display:flex; align-items:center; gap:8px; }
|
|
4
|
+
.graph-omitted-notice > span { flex:1; }
|
|
5
|
+
.graph-omitted-warning { color:var(--colorWarning); flex-shrink:0; }
|
|
6
|
+
.power-relationships .graph-show-all { display:inline-flex; padding:4px; border:0; background:transparent; color:inherit; }
|
|
7
|
+
.power-relationships .graph-show-all:hover, .power-relationships .graph-show-all:focus-visible { color:var(--primary); }
|
|
8
|
+
|
|
3
9
|
.power-relationships{height:100%;overflow:auto;box-sizing:border-box;min-width:0;padding:24px;max-width:1550px;margin:auto;color:var(--textColorPrimary)}.power-relationships h2{margin:0}.power-relationships .page-heading{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:8px}.power-relationships .intro{color:var(--textColorSecondary);max-width:900px;line-height:1.6}.power-relationships .controls{display:flex;gap:24px;align-items:end;flex-wrap:wrap;margin:24px 0}.power-relationships .control{min-width:200px;flex:1;max-width:340px}.power-relationships .control>span{display:block;font-size:12px;margin-bottom:8px;color:var(--textColorSecondary)}.power-relationships button{min-height:32px;cursor:pointer}.power-relationships .refresh{background:transparent;border:1px solid var(--borderColor);border-radius:5px;padding:5px 10px;color:var(--textColorPrimary);display:flex;align-items:center;gap:8px}.power-relationships .notice{padding:14px 16px;background:var(--contentColor);border:1px solid var(--borderColor);border-radius:7px;margin:16px 0;line-height:1.6}.power-relationships .warning{color:var(--colorWarning)}.power-relationships .healthy{color:var(--colorOk)}.power-relationships .neutral{color:var(--textColorSecondary)}.power-relationships .graph-scroll{min-width:0;max-width:100%;overflow:auto;margin-top:24px}.power-relationships .graph{min-width:1000px;display:grid;grid-template-columns:repeat(4,minmax(180px,1fr));column-gap:64px;row-gap:16px;position:relative;padding:6px 2px 56px}.power-relationships .graph.upstream-gutter{padding-left:42px}.power-relationships .gateway-evidence{font-size:11px}.power-relationships .gateway-evidence summary{min-height:24px}.power-relationships .graph.hide-upstreams{min-width:740px;grid-template-columns:repeat(3,minmax(180px,1fr))}.power-relationships .graph-option{display:inline-flex;align-items:center;justify-content:center;gap:8px;flex-shrink:0;min-height:32px;padding:5px 10px;border:1px solid var(--borderColor);border-radius:5px;background:transparent;color:var(--textColorPrimary);font:inherit;cursor:pointer;transition:background-color .15s,border-color .15s}.power-relationships .graph-option[aria-pressed="true"]{background:color-mix(in srgb,var(--primary) 14%,var(--contentColor));border-color:var(--primary);color:var(--primary)}.power-relationships .graph-option:hover,.power-relationships .refresh:hover{background:color-mix(in srgb,var(--primary) 10%,var(--contentColor))}.power-relationships .graph-option:focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-relationships .column{position:relative;min-width:0;display:grid;grid-row:1/-1;grid-template-rows:subgrid}.power-relationships .column>h3{font-size:13px;margin:0;color:var(--textColorSecondary);font-weight:500}.power-relationships .card{background:var(--contentColor);border:1px solid var(--borderColor);border-radius:8px;padding:14px;margin:0;position:relative;z-index:1;overflow-wrap:anywhere}.power-relationships .card-kind{display:flex;align-items:center;gap:7px;font-size:11px;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-name{font-size:14px;font-weight:600;color:var(--textColorPrimary);text-align:left;background:transparent;border:0;padding:0;max-width:100%}.power-relationships .resource-name:hover{color:var(--primary)}.power-relationships .card p{font-size:12px;line-height:1.5;margin:6px 0 0}.power-relationships .relation-label{font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--textColorSecondary);margin-bottom:6px}.power-relationships .resource-connections{position:absolute;inset:0;overflow:visible;pointer-events:none;color:var(--textColorSecondary)}.power-relationships .connection{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;opacity:.55;transition:opacity .15s,stroke .15s,stroke-width .15s}.power-relationships .connection.highlighted{opacity:1;stroke:var(--primary);stroke-width:2.5}.power-relationships .connection.dimmed{opacity:.12}.power-relationships .scope{max-width:68ch;margin-top:8px;color:var(--textColorSecondary);font-size:12px;line-height:1.6}.power-relationships .scope>span{display:block;margin-top:3px}.power-relationships details{margin-top:16px}.power-relationships summary{cursor:pointer;min-height:32px}.power-relationships .edge-list{columns:2;line-height:1.7;font-size:12px;list-style:none;padding:0}.power-relationships .empty{padding:28px;border:1px dashed var(--borderColor);border-radius:8px;color:var(--textColorSecondary);text-align:center}.power-relationships .relationship-summary{padding:16px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px 24px}.power-relationships .ports{margin-left:auto;justify-content:flex-end;display:flex;gap:12px;flex-wrap:wrap;font-size:12px}.power-relationships .ports span{padding:4px 8px;border-radius:4px;background:var(--contentColor);border:1px solid var(--borderColor)}@media(max-width:900px){.power-relationships{padding:16px}.power-relationships .controls{gap:16px}.power-relationships .edge-list{columns:1}}`;
|
|
4
10
|
//#endregion
|
|
5
11
|
exports.resourceRelationshipsStyles = resourceRelationshipsStyles;
|