@64mb/freelens-power 1.3.0 → 1.5.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/resource-search.js +61 -0
- package/out/main/common/resource-search.js.map +1 -0
- package/out/main/common/store/monitoring-preferences-store.js +10 -0
- package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
- package/out/main/index.js +2 -0
- package/out/main/index.js.map +1 -1
- package/out/main/resource-search-database.js +209 -0
- package/out/main/resource-search-database.js.map +1 -0
- package/out/main/resource-search-worker.js +56 -0
- package/out/main/resource-search-worker.js.map +1 -0
- package/out/main/resource-search.js +155 -0
- package/out/main/resource-search.js.map +1 -0
- package/out/renderer/appearance.js +1 -1
- package/out/renderer/appearance.js.map +1 -1
- package/out/renderer/details/resource-health-details.js +8 -4
- package/out/renderer/details/resource-health-details.js.map +1 -1
- package/out/renderer/diagnostics-state.js +7 -5
- package/out/renderer/diagnostics-state.js.map +1 -1
- package/out/renderer/diagnostics.css.js +2 -2
- package/out/renderer/diagnostics.css.js.map +1 -1
- package/out/renderer/diagnostics.js +127 -51
- package/out/renderer/diagnostics.js.map +1 -1
- package/out/renderer/gateway-relationships-client.js +107 -0
- package/out/renderer/gateway-relationships-client.js.map +1 -0
- package/out/renderer/index.js +2 -2
- package/out/renderer/index.js.map +1 -1
- package/out/renderer/monitoring.js +15 -0
- package/out/renderer/monitoring.js.map +1 -1
- package/out/renderer/preferences/monitoring-preferences.js +11 -1
- package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
- package/out/renderer/preferences/preferences.js +16 -6
- package/out/renderer/preferences/preferences.js.map +1 -1
- package/out/renderer/resource-relationships.css.js +1 -1
- package/out/renderer/resource-relationships.css.js.map +1 -1
- package/out/renderer/resource-relationships.js +71 -18
- package/out/renderer/resource-relationships.js.map +1 -1
- package/out/renderer/resource-search-client.js +116 -0
- package/out/renderer/resource-search-client.js.map +1 -0
- package/out/renderer/resource-search-discovery.js +79 -0
- package/out/renderer/resource-search-discovery.js.map +1 -0
- package/out/renderer/resource-search-model.js +2 -1
- package/out/renderer/resource-search-model.js.map +1 -1
- package/out/renderer/resource-search-routing.js +78 -0
- package/out/renderer/resource-search-routing.js.map +1 -0
- package/out/renderer/resource-search-sync.js +199 -0
- package/out/renderer/resource-search-sync.js.map +1 -0
- package/out/renderer/resource-search.js +279 -54
- package/out/renderer/resource-search.js.map +1 -1
- package/out/renderer/src/common/gateway-relationships.js +122 -0
- package/out/renderer/src/common/gateway-relationships.js.map +1 -0
- package/out/renderer/src/common/resource-relationships.js +8 -0
- package/out/renderer/src/common/resource-relationships.js.map +1 -1
- package/out/renderer/src/common/resource-search.js +6 -0
- package/out/renderer/src/common/resource-search.js.map +1 -0
- package/out/renderer/src/common/store/monitoring-preferences-store.js +10 -0
- package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-search-sync.js","names":[],"sources":["../../src/renderer/resource-search-sync.ts"],"sourcesContent":["import {\n collectionPath,\n discoverSearchCollections,\n type MetadataPage,\n projectMetadataPage,\n type SearchCollection,\n type SearchTransport,\n searchErrorStatus,\n} from \"./resource-search-discovery\";\n\nimport type { SearchDocument } from \"../common/resource-search\";\n\nexport interface SearchSink {\n begin(scope: string, scanId: string): Promise<unknown>;\n append(scope: string, scanId: string, documents: SearchDocument[]): Promise<unknown>;\n complete(scope: string, scanId: string): Promise<unknown>;\n invalidate(scope: string): Promise<unknown>;\n reconcile?(resources: string[]): Promise<unknown>;\n}\nexport interface SearchCoverage {\n scanned: number;\n discovered: number;\n denied: number;\n unavailable: number;\n unsupported: number;\n indexing: boolean;\n message?: string;\n kinds?: string[];\n namespaces?: string[];\n completedAt?: number;\n storageFull?: boolean;\n}\nexport const SEARCH_STORAGE_FULL_MESSAGE = \"Search storage is full; clear the local search cache to continue\";\nexport const isSearchStorageFull = (error: unknown): boolean =>\n error instanceof Error && error.message.endsWith(SEARCH_STORAGE_FULL_MESSAGE);\nconst metadataAccept = { Accept: \"application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1\" };\nexport function createSearchSynchronizer(options: {\n transport: SearchTransport;\n sink: SearchSink;\n signal: AbortSignal;\n onStatus(status: SearchCoverage): void;\n namespaces?: () => string[];\n delay?: (milliseconds: number) => Promise<void>;\n refreshMs?: number;\n}) {\n const { transport, sink, signal } = options;\n const status: SearchCoverage = {\n scanned: 0,\n discovered: 0,\n denied: 0,\n unavailable: 0,\n unsupported: 0,\n indexing: true,\n };\n const emit = () => options.onStatus({ ...status });\n const delay =\n options.delay ??\n ((milliseconds: number) =>\n new Promise<void>((resolve) => {\n if (signal.aborted) {\n resolve();\n return;\n }\n const done = () => {\n clearTimeout(timer);\n signal.removeEventListener(\"abort\", done);\n resolve();\n };\n const timer = setTimeout(done, milliseconds);\n signal.addEventListener(\"abort\", done, { once: true });\n }));\n let sequence = 0;\n let nextRequest = 0;\n const request = async <T>(\n path: string,\n query?: Record<string, string | number>,\n headers?: Record<string, string>,\n ): Promise<T> => {\n await delay(Math.max(0, nextRequest - Date.now()));\n if (signal.aborted) throw new Error(\"Search synchronization canceled\");\n nextRequest = Date.now() + 500;\n for (let attempt = 0; ; attempt++) {\n try {\n return await transport.get<T>(path, query, headers);\n } catch (error) {\n const code = searchErrorStatus(error);\n if (signal.aborted || attempt >= 3 || (code !== 429 && code < 500)) throw error;\n const retry = (error as { headers?: { get?(name: string): string | null }; retryAfter?: string }).retryAfter;\n const retryMilliseconds = retry\n ? /^\\d+$/.test(retry)\n ? Number(retry) * 1000\n : Date.parse(retry) - Date.now()\n : NaN;\n await delay(\n Number.isFinite(retryMilliseconds)\n ? Math.min(86400000, Math.max(0, retryMilliseconds))\n : Math.min(30000, 1000 * 2 ** attempt) + Math.random() * 250,\n );\n }\n }\n };\n const limited: SearchTransport = { get: request };\n const scan = async (type: SearchCollection, namespace?: string): Promise<void> => {\n const scope = `${type.group}/${type.resource}/${namespace ?? \"*\"}`;\n for (let restart = 0; restart < 2; restart++) {\n const scanId = `${Date.now()}-${++sequence}`;\n await sink.begin(scope, scanId);\n let continuation = \"\";\n let pageSize = 250;\n const seen = new Set<string>();\n try {\n do {\n let page: MetadataPage;\n for (;;) {\n const query = { limit: pageSize, ...(continuation ? { continue: continuation } : {}) };\n try {\n try {\n page = await request<MetadataPage>(collectionPath(type, namespace), query, metadataAccept);\n } catch (error) {\n if (searchErrorStatus(error) !== 406 || !type.group) throw error;\n page = await request<MetadataPage>(collectionPath(type, namespace), query, {\n Accept: \"application/json\",\n });\n }\n break;\n } catch (error) {\n if (!(error as { oversized?: boolean }).oversized || pageSize === 1) throw error;\n pageSize = Math.max(1, Math.floor(pageSize / 2));\n }\n }\n if (signal.aborted) return;\n const documents = projectMetadataPage(type, page);\n status.namespaces = [\n ...new Set([\n ...(status.namespaces ?? []),\n ...documents.flatMap((document) => (document.namespace ? [document.namespace] : [])),\n ]),\n ].sort();\n await sink.append(scope, scanId, documents);\n continuation = page.metadata?.continue ?? \"\";\n if (continuation && seen.has(continuation)) throw new Error(\"Repeated inventory continuation\");\n seen.add(continuation);\n } while (continuation);\n if (!signal.aborted) await sink.complete(scope, scanId);\n return;\n } catch (error) {\n const code = searchErrorStatus(error);\n if (code === 410 && restart === 0) continue;\n if (code === 403) await sink.invalidate(scope);\n throw error;\n }\n }\n };\n return {\n async run(): Promise<void> {\n try {\n while (!signal.aborted) {\n status.indexing = true;\n status.scanned = 0;\n status.denied = 0;\n status.unavailable = 0;\n status.unsupported = 0;\n status.message = undefined;\n emit();\n let discoveryFailures = 0;\n const collections = await discoverSearchCollections(limited, () => {\n discoveryFailures++;\n status.unavailable++;\n emit();\n });\n if (signal.aborted) return;\n if (discoveryFailures === 0)\n await sink.reconcile?.(collections.map((type) => `${type.group}/${type.resource}`));\n else status.message = \"API discovery incomplete; cached resource types may be stale\";\n status.kinds = [...new Set(collections.map((type) => type.kind))].sort();\n status.discovered = collections.length;\n emit();\n let fallbackNamespaces: string[] | undefined;\n for (const type of collections) {\n if (signal.aborted) return;\n try {\n await scan(type);\n } catch (error) {\n if (signal.aborted) return;\n if (isSearchStorageFull(error)) throw error;\n if (searchErrorStatus(error) === 403) {\n status.denied++;\n if (type.namespaced) {\n let namespaces = fallbackNamespaces ?? options.namespaces?.() ?? [];\n if (fallbackNamespaces === undefined) {\n try {\n const namespaceType: SearchCollection = {\n group: \"\",\n version: \"v1\",\n resource: \"namespaces\",\n kind: \"Namespace\",\n namespaced: false,\n aliases: [],\n };\n let token = \"\";\n let limit = 250;\n const seen = new Set<string>();\n do {\n let page: MetadataPage;\n for (;;) {\n try {\n page = await request<MetadataPage>(\n collectionPath(namespaceType),\n { limit, ...(token ? { continue: token } : {}) },\n metadataAccept,\n );\n break;\n } catch (error) {\n if (!(error as { oversized?: boolean }).oversized || limit === 1) throw error;\n limit = Math.max(1, Math.floor(limit / 2));\n }\n }\n namespaces = [\n ...new Set([\n ...namespaces,\n ...(page.items ?? []).flatMap((item) => (item.metadata?.name ? [item.metadata.name] : [])),\n ]),\n ];\n token = page.metadata?.continue ?? \"\";\n if (token && seen.has(token)) throw new Error(\"Repeated namespace continuation\");\n seen.add(token);\n } while (token);\n } catch {\n status.message = \"Namespace discovery denied or incomplete; add a known namespace to continue\";\n }\n fallbackNamespaces = namespaces;\n }\n for (const namespace of namespaces) {\n if (signal.aborted) return;\n try {\n await scan(type, namespace);\n } catch (failure) {\n if (isSearchStorageFull(failure)) throw failure;\n if (searchErrorStatus(failure) === 403) status.denied++;\n else status.unavailable++;\n }\n }\n }\n } else if (searchErrorStatus(error) === 406) status.unsupported++;\n else status.unavailable++;\n }\n status.scanned++;\n emit();\n }\n status.indexing = false;\n status.completedAt = Date.now();\n emit();\n await delay(options.refreshMs ?? 10 * 60 * 1000);\n }\n } catch (error) {\n if (!isSearchStorageFull(error)) throw error;\n status.indexing = false;\n status.storageFull = true;\n status.message = SEARCH_STORAGE_FULL_MESSAGE;\n emit();\n }\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
const require_extensions = require("./_virtual/_global-external_@freelensapp/extensions.js");
|
|
2
2
|
const require__global_external_mobx = require("./_virtual/_global-external_mobx.js");
|
|
3
|
+
const require__global_external_mobx_react = require("./_virtual/_global-external_mobx-react.js");
|
|
4
|
+
const require_monitoring_preferences_store = require("./src/common/store/monitoring-preferences-store.js");
|
|
3
5
|
const require__global_external_react = require("./_virtual/_global-external_react.js");
|
|
4
6
|
const require__global_external_react_dom = require("./_virtual/_global-external_react-dom.js");
|
|
5
7
|
const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
|
|
6
8
|
const require_ai_icon = require("./ai-icon.js");
|
|
7
9
|
const require_ai_diagnostic_handoff = require("./ai-diagnostic-handoff.js");
|
|
8
10
|
const require_diagnostic_explain_button = require("./diagnostic-explain-button.js");
|
|
11
|
+
const require_resource_search_client = require("./resource-search-client.js");
|
|
12
|
+
const require_resource_search_routing = require("./resource-search-routing.js");
|
|
9
13
|
const require_resource_search_fields = require("./resource-search-fields.js");
|
|
10
14
|
const require_resource_search_model = require("./resource-search-model.js");
|
|
15
|
+
const require_resource_search_sync = require("./resource-search-sync.js");
|
|
11
16
|
//#region src/renderer/resource-search.tsx
|
|
12
17
|
var OPEN = "power-resource-search";
|
|
13
18
|
var activeId = () => require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid;
|
|
@@ -74,16 +79,16 @@ var inventory = () => [
|
|
|
74
79
|
]
|
|
75
80
|
];
|
|
76
81
|
var icons = new Map(inventory().map(([kind, , icon]) => [kind, icon]));
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
}
|
|
82
|
+
require__global_external_mobx_react.observer(() => {
|
|
83
|
+
if (!require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate().resourceSearchEnabled) return null;
|
|
84
|
+
return /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
85
|
+
type: "button",
|
|
86
|
+
title: "Search resources (double Shift)",
|
|
87
|
+
"aria-label": "Search resources",
|
|
88
|
+
onClick: () => window.dispatchEvent(new Event(OPEN)),
|
|
89
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "search" })
|
|
90
|
+
});
|
|
91
|
+
});
|
|
87
92
|
function SearchSnippet({ field, query }) {
|
|
88
93
|
if (!field) return null;
|
|
89
94
|
const token = require_resource_search_model.queryTokens(query).find((token) => field.text.toLocaleLowerCase().includes(token));
|
|
@@ -104,9 +109,13 @@ function SearchSnippet({ field, query }) {
|
|
|
104
109
|
}
|
|
105
110
|
function SearchDialog({ close, clusterId }) {
|
|
106
111
|
const [query, setQuery] = require__global_external_react.useState("");
|
|
112
|
+
const [knownNamespace, setKnownNamespace] = require__global_external_react.useState("");
|
|
113
|
+
const [kindFilter, setKindFilter] = require__global_external_react.useState("");
|
|
114
|
+
const [namespaceFilter, setNamespaceFilter] = require__global_external_react.useState("");
|
|
107
115
|
const [resources, setResources] = require__global_external_react.useState([]);
|
|
108
116
|
const [loading, setLoading] = require__global_external_react.useState(true);
|
|
109
117
|
const [failed, setFailed] = require__global_external_react.useState(0);
|
|
118
|
+
const [cachedCount, setCachedCount] = require__global_external_react.useState();
|
|
110
119
|
const [selectedPath, setSelectedPath] = require__global_external_react.useState();
|
|
111
120
|
const [error, setError] = require__global_external_react.useState("");
|
|
112
121
|
const dialog = require__global_external_react.useRef(null);
|
|
@@ -114,55 +123,73 @@ function SearchDialog({ close, clusterId }) {
|
|
|
114
123
|
const searchIndex = require__global_external_react.useMemo(() => require_resource_search_model.createResourceSearchIndex(resources), [resources]);
|
|
115
124
|
const matches = searchIndex.search(query);
|
|
116
125
|
const selectedResource = matches.find((resource) => resource.path === selectedPath) ?? matches[0];
|
|
117
|
-
const results = matches
|
|
126
|
+
const results = matches;
|
|
118
127
|
if (selectedResource && !results.includes(selectedResource)) results[results.length - 1] = selectedResource;
|
|
119
128
|
const selected = results.findIndex((resource) => resource.path === selectedResource?.path);
|
|
120
129
|
require__global_external_react.useEffect(() => {
|
|
121
130
|
if (selectedPath !== void 0 && selectedPath !== selectedResource?.path) setSelectedPath(void 0);
|
|
122
131
|
}, [selectedPath, selectedResource?.path]);
|
|
132
|
+
const [coverage, setCoverage] = require__global_external_react.useState(currentCoverage);
|
|
133
|
+
const [limit, setLimit] = require__global_external_react.useState(100);
|
|
134
|
+
const [hasMore, setHasMore] = require__global_external_react.useState(false);
|
|
123
135
|
require__global_external_react.useEffect(() => {
|
|
124
136
|
const previous = document.activeElement;
|
|
125
137
|
input.current?.focus();
|
|
126
|
-
const
|
|
127
|
-
|
|
138
|
+
const update = () => setCoverage({ ...currentCoverage });
|
|
139
|
+
window.addEventListener("power-search-coverage", update);
|
|
140
|
+
return () => {
|
|
141
|
+
window.removeEventListener("power-search-coverage", update);
|
|
142
|
+
if (previous?.isConnected) previous.focus();
|
|
143
|
+
};
|
|
144
|
+
}, []);
|
|
145
|
+
require__global_external_react.useEffect(() => {
|
|
128
146
|
let live = true;
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
const client = require_resource_search_client.createResourceSearchClient(clusterId, require_resource_search_client.searchContextId());
|
|
148
|
+
const timer = window.setTimeout(() => {
|
|
149
|
+
client.query(query, limit, {
|
|
150
|
+
...kindFilter ? { kind: coverage.kinds?.find((kind) => kind.toLocaleLowerCase() === kindFilter.toLocaleLowerCase()) ?? kindFilter } : {},
|
|
151
|
+
...namespaceFilter ? { namespace: namespaceFilter === "(cluster)" ? "" : namespaceFilter } : {}
|
|
152
|
+
}).then((result) => {
|
|
153
|
+
if (!live || activeId() !== clusterId) return;
|
|
154
|
+
setResources(result.documents);
|
|
155
|
+
setHasMore(result.hasMore);
|
|
156
|
+
setLoading(false);
|
|
157
|
+
setFailed(0);
|
|
158
|
+
client.status?.().then((status) => {
|
|
159
|
+
if (live) setCachedCount(status.count);
|
|
160
|
+
}).catch(() => {});
|
|
161
|
+
}).catch(() => {
|
|
162
|
+
if (live) {
|
|
163
|
+
setFailed(1);
|
|
164
|
+
setLoading(false);
|
|
147
165
|
}
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
Promise.all([worker(), worker()]).then(() => {
|
|
151
|
-
if (live) setLoading(false);
|
|
152
|
-
});
|
|
166
|
+
});
|
|
167
|
+
}, 100);
|
|
153
168
|
return () => {
|
|
154
169
|
live = false;
|
|
155
|
-
window.clearTimeout(
|
|
156
|
-
controller.abort();
|
|
157
|
-
if (previous?.isConnected) previous.focus();
|
|
170
|
+
window.clearTimeout(timer);
|
|
158
171
|
};
|
|
159
|
-
}, [
|
|
172
|
+
}, [
|
|
173
|
+
clusterId,
|
|
174
|
+
query,
|
|
175
|
+
limit,
|
|
176
|
+
kindFilter,
|
|
177
|
+
namespaceFilter,
|
|
178
|
+
coverage.scanned,
|
|
179
|
+
coverage.indexing
|
|
180
|
+
]);
|
|
160
181
|
require__global_external_react.useEffect(() => {
|
|
161
182
|
document.getElementById(`power-resource-result-${selected}`)?.scrollIntoView?.({ block: "nearest" });
|
|
162
183
|
}, [selected, selectedResource?.path]);
|
|
184
|
+
const clearCache = () => {
|
|
185
|
+
require_resource_search_client.createResourceSearchClient(clusterId, require_resource_search_client.searchContextId()).clear().then(() => {
|
|
186
|
+
setResources([]);
|
|
187
|
+
restartSearchSync();
|
|
188
|
+
}).catch(() => setError("Could not clear the local search cache. Try again."));
|
|
189
|
+
};
|
|
163
190
|
const open = (resource) => {
|
|
164
191
|
if (activeId() !== clusterId) return;
|
|
165
|
-
Promise.resolve().then(() =>
|
|
192
|
+
Promise.resolve().then(() => require_resource_search_routing.openSearchResource(resource)).then(() => {
|
|
166
193
|
if (activeId() === clusterId) close();
|
|
167
194
|
}).catch(() => setError("Could not open this resource. Try again or refresh the inventory."));
|
|
168
195
|
};
|
|
@@ -186,7 +213,7 @@ function SearchDialog({ close, clusterId }) {
|
|
|
186
213
|
close();
|
|
187
214
|
}
|
|
188
215
|
if (event.key === "Tab") {
|
|
189
|
-
const controls = Array.from(dialog.current?.querySelectorAll("input, button:not(:disabled)") ?? []);
|
|
216
|
+
const controls = Array.from(dialog.current?.querySelectorAll("input, button:not(:disabled), select") ?? []);
|
|
190
217
|
const index = controls.indexOf(document.activeElement);
|
|
191
218
|
if (event.shiftKey && index <= 0) {
|
|
192
219
|
event.preventDefault();
|
|
@@ -211,11 +238,23 @@ function SearchDialog({ close, clusterId }) {
|
|
|
211
238
|
material: "search",
|
|
212
239
|
size: 18
|
|
213
240
|
}), "Search resources"]
|
|
214
|
-
}), /* @__PURE__ */ require_jsx_runtime.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
241
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
242
|
+
style: {
|
|
243
|
+
display: "flex",
|
|
244
|
+
gap: 4
|
|
245
|
+
},
|
|
246
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
247
|
+
type: "button",
|
|
248
|
+
"aria-label": "Refresh resource inventory",
|
|
249
|
+
title: "Refresh resource inventory",
|
|
250
|
+
onClick: () => restartSearchSync(),
|
|
251
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "refresh" })
|
|
252
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
253
|
+
type: "button",
|
|
254
|
+
"aria-label": "Close resource search",
|
|
255
|
+
onClick: close,
|
|
256
|
+
children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, { material: "close" })
|
|
257
|
+
})]
|
|
219
258
|
})]
|
|
220
259
|
}),
|
|
221
260
|
/* @__PURE__ */ require_jsx_runtime.jsx("input", {
|
|
@@ -240,14 +279,68 @@ function SearchDialog({ close, clusterId }) {
|
|
|
240
279
|
}
|
|
241
280
|
}
|
|
242
281
|
}),
|
|
282
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
283
|
+
className: "power-resource-search-filters",
|
|
284
|
+
style: {
|
|
285
|
+
display: "flex",
|
|
286
|
+
gap: 8,
|
|
287
|
+
flexWrap: "wrap"
|
|
288
|
+
},
|
|
289
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("input", {
|
|
290
|
+
list: "power-search-kinds",
|
|
291
|
+
"aria-label": "Filter by exact resource kind",
|
|
292
|
+
placeholder: "Kind (all types)",
|
|
293
|
+
value: kindFilter,
|
|
294
|
+
maxLength: 253,
|
|
295
|
+
onChange: (event) => {
|
|
296
|
+
setKindFilter(event.target.value);
|
|
297
|
+
setSelectedPath(void 0);
|
|
298
|
+
}
|
|
299
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("input", {
|
|
300
|
+
list: "power-search-namespaces",
|
|
301
|
+
"aria-label": "Filter by exact namespace",
|
|
302
|
+
placeholder: "Namespace (all)",
|
|
303
|
+
value: namespaceFilter,
|
|
304
|
+
maxLength: 253,
|
|
305
|
+
onChange: (event) => {
|
|
306
|
+
setNamespaceFilter(event.target.value);
|
|
307
|
+
setSelectedPath(void 0);
|
|
308
|
+
}
|
|
309
|
+
})]
|
|
310
|
+
}),
|
|
311
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("datalist", {
|
|
312
|
+
id: "power-search-kinds",
|
|
313
|
+
children: (coverage.kinds ?? []).map((kind) => /* @__PURE__ */ require_jsx_runtime.jsx("option", { value: kind }, kind))
|
|
314
|
+
}),
|
|
315
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("datalist", {
|
|
316
|
+
id: "power-search-namespaces",
|
|
317
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("option", {
|
|
318
|
+
value: "(cluster)",
|
|
319
|
+
children: "Cluster scoped"
|
|
320
|
+
}), (coverage.namespaces ?? []).map((namespace) => /* @__PURE__ */ require_jsx_runtime.jsx("option", { value: namespace }, namespace))]
|
|
321
|
+
}),
|
|
243
322
|
/* @__PURE__ */ require_jsx_runtime.jsxs("p", {
|
|
244
323
|
role: "status",
|
|
245
324
|
children: [
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
325
|
+
coverage.indexing ? `Indexing ${coverage.scanned}/${coverage.discovered} types` : coverage.completedAt ? `Updated ${new Date(coverage.completedAt).toLocaleTimeString([], {
|
|
326
|
+
hour: "2-digit",
|
|
327
|
+
minute: "2-digit"
|
|
328
|
+
})}` : "Cached inventory",
|
|
329
|
+
cachedCount !== void 0 && ` · ${cachedCount.toLocaleString()} resources`,
|
|
330
|
+
coverage.denied > 0 && ` · ${coverage.denied} restricted scopes`,
|
|
331
|
+
coverage.unavailable + coverage.unsupported > 0 && ` · ${coverage.unavailable + coverage.unsupported} APIs unavailable`,
|
|
332
|
+
failed > 0 && " · Search cache unavailable"
|
|
249
333
|
]
|
|
250
334
|
}),
|
|
335
|
+
(coverage.message || coverage.denied > 0 || coverage.unavailable + coverage.unsupported > 0) && /* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Inventory coverage" }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: coverage.message ?? "Results include the resources your current permissions and available APIs allow." })] }),
|
|
336
|
+
coverage.storageFull && /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
337
|
+
role: "alert",
|
|
338
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Local search storage is full. Cached results are partial; indexing is paused." }), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
339
|
+
type: "button",
|
|
340
|
+
onClick: clearCache,
|
|
341
|
+
children: "Clear local search cache"
|
|
342
|
+
})]
|
|
343
|
+
}),
|
|
251
344
|
error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
|
|
252
345
|
role: "alert",
|
|
253
346
|
children: error
|
|
@@ -289,7 +382,7 @@ function SearchDialog({ close, clusterId }) {
|
|
|
289
382
|
require_ai_diagnostic_handoff.explainDiagnosticFinding({
|
|
290
383
|
clusterId,
|
|
291
384
|
title: `${resource.kind}: ${resource.name}`,
|
|
292
|
-
summary: `Resource selected from search.
|
|
385
|
+
summary: `Resource selected from search. API group: ${resource.group || "core"}; version: ${resource.version}; resource: ${resource.resource}; kind: ${resource.kind}; namespace: ${resource.namespace ?? "cluster scoped"}; name: ${resource.name}; UID: ${resource.uid ?? "unknown"}; path: ${resource.path}. No live diagnostic data was collected.`,
|
|
293
386
|
resource: {
|
|
294
387
|
kind: resource.kind,
|
|
295
388
|
name: resource.name,
|
|
@@ -301,7 +394,43 @@ function SearchDialog({ close, clusterId }) {
|
|
|
301
394
|
})]
|
|
302
395
|
}, resource.path)), !results.length && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: loading ? "Searching…" : "No matching resources in the available inventory" })]
|
|
303
396
|
}),
|
|
304
|
-
|
|
397
|
+
hasMore && /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
398
|
+
type: "button",
|
|
399
|
+
disabled: limit >= 1e3,
|
|
400
|
+
onClick: () => setLimit((value) => Math.min(1e3, value + 100)),
|
|
401
|
+
children: "Show more matches"
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [
|
|
404
|
+
/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Search options" }),
|
|
405
|
+
/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
|
|
406
|
+
style: {
|
|
407
|
+
display: "flex",
|
|
408
|
+
gap: 8,
|
|
409
|
+
flexWrap: "wrap"
|
|
410
|
+
},
|
|
411
|
+
children: [/* @__PURE__ */ require_jsx_runtime.jsx("input", {
|
|
412
|
+
"aria-label": "Known namespace for restricted access",
|
|
413
|
+
placeholder: "Known namespace",
|
|
414
|
+
value: knownNamespace,
|
|
415
|
+
maxLength: 63,
|
|
416
|
+
onChange: (event) => setKnownNamespace(event.target.value)
|
|
417
|
+
}), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
418
|
+
type: "button",
|
|
419
|
+
disabled: !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(knownNamespace),
|
|
420
|
+
onClick: () => {
|
|
421
|
+
extraNamespaces.add(knownNamespace);
|
|
422
|
+
restartSearchSync();
|
|
423
|
+
},
|
|
424
|
+
children: "Index namespace"
|
|
425
|
+
})]
|
|
426
|
+
}),
|
|
427
|
+
hasMore && limit >= 1e3 && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Showing up to 1000 candidates. Refine the name, type or namespace to continue." }),
|
|
428
|
+
!coverage.storageFull && /* @__PURE__ */ require_jsx_runtime.jsx("button", {
|
|
429
|
+
type: "button",
|
|
430
|
+
onClick: clearCache,
|
|
431
|
+
children: "Clear local search cache"
|
|
432
|
+
})
|
|
433
|
+
] }),
|
|
305
434
|
/* @__PURE__ */ require_jsx_runtime.jsx("p", {
|
|
306
435
|
className: "power-resource-search-shortcuts",
|
|
307
436
|
children: "↑↓ Navigate · Enter Open · Esc Close"
|
|
@@ -310,10 +439,98 @@ function SearchDialog({ close, clusterId }) {
|
|
|
310
439
|
})
|
|
311
440
|
});
|
|
312
441
|
}
|
|
442
|
+
var currentCoverage = {
|
|
443
|
+
scanned: 0,
|
|
444
|
+
discovered: 0,
|
|
445
|
+
denied: 0,
|
|
446
|
+
unavailable: 0,
|
|
447
|
+
unsupported: 0,
|
|
448
|
+
indexing: true
|
|
449
|
+
};
|
|
450
|
+
var restartSearchSync = () => {};
|
|
451
|
+
var extraNamespaces = /* @__PURE__ */ new Set();
|
|
313
452
|
function startResourceSearch() {
|
|
453
|
+
const preferences = require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate();
|
|
454
|
+
let stop = preferences.resourceSearchEnabled ? startEnabledResourceSearch() : void 0;
|
|
455
|
+
const dispose = require__global_external_mobx.reaction(() => preferences.resourceSearchEnabled, (enabled) => {
|
|
456
|
+
stop?.();
|
|
457
|
+
stop = enabled ? startEnabledResourceSearch() : void 0;
|
|
458
|
+
});
|
|
459
|
+
return () => {
|
|
460
|
+
dispose();
|
|
461
|
+
stop?.();
|
|
462
|
+
stop = void 0;
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function startEnabledResourceSearch() {
|
|
466
|
+
let syncAbort;
|
|
467
|
+
const sync = () => {
|
|
468
|
+
syncAbort?.abort();
|
|
469
|
+
require_resource_search_routing.closeSearchResourceFallback();
|
|
470
|
+
const clusterId = activeId();
|
|
471
|
+
if (!clusterId || window.top === window) return;
|
|
472
|
+
const phase = require_extensions.Renderer.Catalog.activeCluster.get()?.status?.phase;
|
|
473
|
+
if (phase && phase !== "connected") {
|
|
474
|
+
currentCoverage = {
|
|
475
|
+
...currentCoverage,
|
|
476
|
+
indexing: false,
|
|
477
|
+
message: "Cluster disconnected; cached results may be stale"
|
|
478
|
+
};
|
|
479
|
+
window.dispatchEvent(new Event("power-search-coverage"));
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
const controller = new AbortController();
|
|
483
|
+
syncAbort = controller;
|
|
484
|
+
const client = require_resource_search_client.createResourceSearchClient(clusterId, require_resource_search_client.searchContextId());
|
|
485
|
+
const liveStores = new Map(inventory().map(([kind, store]) => [kind, store]));
|
|
486
|
+
const liveObjects = /* @__PURE__ */ new Map();
|
|
487
|
+
const sink = {
|
|
488
|
+
...client,
|
|
489
|
+
append: (scope, scanId, documents) => client.append(scope, scanId, documents.map((item) => {
|
|
490
|
+
const store = liveStores.get(item.kind);
|
|
491
|
+
if (!store) return item;
|
|
492
|
+
let objects = liveObjects.get(item.kind);
|
|
493
|
+
if (!objects) {
|
|
494
|
+
objects = new Map(store.items.map((object) => [object.selfLink, object]));
|
|
495
|
+
liveObjects.set(item.kind, objects);
|
|
496
|
+
}
|
|
497
|
+
const object = objects.get(item.path);
|
|
498
|
+
return object ? {
|
|
499
|
+
...item,
|
|
500
|
+
fields: require_resource_search_fields.projectSearchFields(item.kind, object)
|
|
501
|
+
} : item;
|
|
502
|
+
}))
|
|
503
|
+
};
|
|
504
|
+
let wasIndexing = false;
|
|
505
|
+
require_resource_search_sync.createSearchSynchronizer({
|
|
506
|
+
transport: require_resource_search_client.createResourceSearchTransport(clusterId, controller.signal),
|
|
507
|
+
sink,
|
|
508
|
+
signal: controller.signal,
|
|
509
|
+
namespaces: () => [.../* @__PURE__ */ new Set([...require_extensions.Renderer.Catalog.activeCluster.get()?.spec?.accessibleNamespaces ?? [], ...extraNamespaces])],
|
|
510
|
+
onStatus: (status) => {
|
|
511
|
+
if (!controller.signal.aborted) {
|
|
512
|
+
if (status.indexing && !wasIndexing) liveObjects.clear();
|
|
513
|
+
wasIndexing = status.indexing;
|
|
514
|
+
currentCoverage = status;
|
|
515
|
+
window.dispatchEvent(new Event("power-search-coverage"));
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}).run().catch(() => {
|
|
519
|
+
if (!controller.signal.aborted) {
|
|
520
|
+
currentCoverage = {
|
|
521
|
+
...currentCoverage,
|
|
522
|
+
indexing: false,
|
|
523
|
+
unavailable: currentCoverage.unavailable + 1
|
|
524
|
+
};
|
|
525
|
+
window.dispatchEvent(new Event("power-search-coverage"));
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
};
|
|
529
|
+
restartSearchSync = sync;
|
|
530
|
+
sync();
|
|
314
531
|
const container = document.createElement("div");
|
|
315
532
|
const style = document.createElement("style");
|
|
316
|
-
style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:
|
|
533
|
+
style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px}.power-resource-search-dialog{width:680px;max-width:100%;max-height:75vh;display:flex;flex-direction:column;padding:20px;gap:12px;background:var(--mainBackground,#222);color:var(--textColorPrimary,#eee);border:1px solid var(--borderColor,#555);border-radius:8px;box-shadow:0 16px 60px #0008}.power-resource-search-heading{display:flex;align-items:center;justify-content:space-between}.power-resource-search-filters input{flex:1;min-width:180px}.power-resource-search-dialog input{padding:12px;font-size:16px;background:var(--inputControlBackground,#333);color:inherit;border:1px solid var(--borderColor,#666);border-radius:4px}.power-resource-search-dialog p{margin:0;font-size:12px;color:var(--textColorSecondary,#bbb)}.power-resource-search-results{overflow:auto;min-height:180px;flex:1}.power-resource-search-row{display:flex;align-items:center;gap:12px;padding:4px;border-radius:4px}.power-resource-search-row{border-left:3px solid transparent}.power-resource-search-row.selected{background:color-mix(in srgb,var(--primary,#668fff) 16%,var(--mainBackground,#222));color:var(--tableSelectedRowColor,var(--textColorPrimary,#eee));border-left-color:var(--primary,#668fff)}.power-resource-search-row.selected .Icon{color:var(--primary,#8daaff)}.power-resource-search-row:hover{background:var(--tableBgcSelected,var(--contentColor,#292d32))}.power-resource-search-dialog button:hover:not(:disabled){background:#ffffff12;border-radius:4px}.power-resource-search-row>button:last-child{border:1px solid var(--borderColor,#555);border-radius:4px}.power-resource-search-shortcuts{padding-top:8px;border-top:1px solid var(--borderColor,#555)}.power-resource-search-dialog button{min-width:32px;min-height:32px;padding:6px;color:inherit;background:transparent;border:0;cursor:pointer}.power-resource-search-dialog button:disabled{opacity:.45;cursor:default}.power-resource-search-open{display:flex;align-items:center;gap:12px;flex:1;text-align:left;min-width:0}.power-resource-search-open span{min-width:0}.power-resource-search-open strong,.power-resource-search-open small{display:block;overflow-wrap:anywhere}.power-resource-search-open small{opacity:.7}.power-resource-search-row>button.power-resource-search-ai{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;min-width:34px;padding:0;background:var(--contentColor,#292d32);border:1px solid var(--borderColor,#666)}.power-resource-search-row.selected>button.power-resource-search-ai{background:var(--mainBackground,#202326);border-color:color-mix(in srgb,var(--textColorPrimary,#ddd) 55%,var(--borderColor,#666));box-shadow:0 1px 3px #0002}.power-resource-search-row.selected>button.power-resource-search-ai .Icon{color:var(--textColorAccent,#eee)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled){background:var(--contentColor,#30343a);border-color:var(--primary,#8daaff);color:var(--primary,#8daaff)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled) .Icon{color:inherit}.power-resource-search-dialog button:focus-visible{outline:2px solid var(--primary,#668fff)}`;
|
|
317
534
|
document.head.append(style);
|
|
318
535
|
document.body.append(container);
|
|
319
536
|
let visible = false;
|
|
@@ -347,9 +564,17 @@ function startResourceSearch() {
|
|
|
347
564
|
window.addEventListener("keydown", key);
|
|
348
565
|
window.addEventListener("keyup", key);
|
|
349
566
|
window.addEventListener(OPEN, show);
|
|
350
|
-
const dispose = require__global_external_mobx.reaction(
|
|
567
|
+
const dispose = require__global_external_mobx.reaction(() => `${require_resource_search_client.searchContextId()}/${require_extensions.Renderer.Catalog.activeCluster.get()?.status?.phase}`, () => {
|
|
568
|
+
close();
|
|
569
|
+
extraNamespaces.clear();
|
|
570
|
+
sync();
|
|
571
|
+
});
|
|
351
572
|
return () => {
|
|
352
573
|
close();
|
|
574
|
+
syncAbort?.abort();
|
|
575
|
+
require_resource_search_routing.closeSearchResourceFallback();
|
|
576
|
+
restartSearchSync = () => {};
|
|
577
|
+
extraNamespaces.clear();
|
|
353
578
|
dispose();
|
|
354
579
|
window.removeEventListener("blur", resetShift);
|
|
355
580
|
window.removeEventListener("keydown", key);
|