@64mb/freelens-power 1.6.1 → 2.0.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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/out/main/common/resource-search-kind-priority.js +23 -0
  3. package/out/main/common/resource-search-kind-priority.js.map +1 -0
  4. package/out/main/power-logs-query.js +1 -0
  5. package/out/main/power-logs-query.js.map +1 -1
  6. package/out/main/resource-search-database.js +7 -2
  7. package/out/main/resource-search-database.js.map +1 -1
  8. package/out/main/resource-search-worker.js +6 -2
  9. package/out/main/resource-search-worker.js.map +1 -1
  10. package/out/renderer/_virtual/_global-external_react.js +2 -1
  11. package/out/renderer/power-log-json-cell.js +74 -0
  12. package/out/renderer/power-log-json-cell.js.map +1 -0
  13. package/out/renderer/power-log-json-fields.js +144 -0
  14. package/out/renderer/power-log-json-fields.js.map +1 -0
  15. package/out/renderer/power-log-json.js +139 -20
  16. package/out/renderer/power-log-json.js.map +1 -1
  17. package/out/renderer/power-log-message-tokens.js +60 -0
  18. package/out/renderer/power-log-message-tokens.js.map +1 -0
  19. package/out/renderer/power-log-message.js +26 -0
  20. package/out/renderer/power-log-message.js.map +1 -0
  21. package/out/renderer/power-logs-sql-row.js +2 -2
  22. package/out/renderer/power-logs-sql-row.js.map +1 -1
  23. package/out/renderer/power-logs.css.js +31 -2
  24. package/out/renderer/power-logs.css.js.map +1 -1
  25. package/out/renderer/power-logs.js +212 -24
  26. package/out/renderer/power-logs.js.map +1 -1
  27. package/out/renderer/preferences/logs-preferences.js +159 -38
  28. package/out/renderer/preferences/logs-preferences.js.map +1 -1
  29. package/out/renderer/resource-search-model.js +2 -1
  30. package/out/renderer/resource-search-model.js.map +1 -1
  31. package/out/renderer/resource-search-sync.js +1 -1
  32. package/out/renderer/resource-search-sync.js.map +1 -1
  33. package/out/renderer/resource-search.js +84 -81
  34. package/out/renderer/resource-search.js.map +1 -1
  35. package/out/renderer/src/common/power-log-field-filters.js +92 -0
  36. package/out/renderer/src/common/power-log-field-filters.js.map +1 -0
  37. package/out/renderer/src/common/power-log-json-filter-sql.js +106 -0
  38. package/out/renderer/src/common/power-log-json-filter-sql.js.map +1 -0
  39. package/out/renderer/src/common/power-log-json-preset.js +36 -0
  40. package/out/renderer/src/common/power-log-json-preset.js.map +1 -0
  41. package/out/renderer/src/common/power-log-level.js +171 -0
  42. package/out/renderer/src/common/power-log-level.js.map +1 -0
  43. package/out/renderer/src/common/power-log-parser.js +7 -29
  44. package/out/renderer/src/common/power-log-parser.js.map +1 -1
  45. package/out/renderer/src/common/resource-search-kind-priority.js +28 -0
  46. package/out/renderer/src/common/resource-search-kind-priority.js.map +1 -0
  47. package/package.json +1 -1
@@ -8,8 +8,14 @@ const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runti
8
8
  const require_ai_diagnostic_handoff = require("./ai-diagnostic-handoff.js");
9
9
  const require_date_time = require("./src/common/date-time.js");
10
10
  const require_diagnostic_explain_button = require("./diagnostic-explain-button.js");
11
+ const require_power_log_field_filters = require("./src/common/power-log-field-filters.js");
12
+ const require_power_log_json_filter_sql = require("./src/common/power-log-json-filter-sql.js");
13
+ const require_power_log_json_preset = require("./src/common/power-log-json-preset.js");
11
14
  const require_power_logs_ai = require("./src/common/power-logs-ai.js");
15
+ const require_power_log_json_fields = require("./power-log-json-fields.js");
12
16
  const require_power_log_json = require("./power-log-json.js");
17
+ const require_power_log_message = require("./power-log-message.js");
18
+ const require_power_log_json_cell = require("./power-log-json-cell.js");
13
19
  const require_power_logs_css = require("./power-logs.css.js");
14
20
  const require_power_logs_client = require("./power-logs-client.js");
15
21
  const require_power_logs_collector = require("./power-logs-collector.js");
@@ -39,7 +45,7 @@ var examples = [
39
45
  ["Recent", "SELECT message, level, container, pod, timestamp FROM logs ORDER BY timestamp DESC NULLS LAST LIMIT 200"],
40
46
  ["Errors", "SELECT pod, container, count(*) AS errors FROM logs WHERE level IN ('error','fatal') GROUP BY pod, container ORDER BY errors DESC"],
41
47
  ["Timeline", "SELECT strftime('%Y-%m-%d %H:%M', timestamp / 1000, 'unixepoch') AS minute, level, count(*) AS lines FROM logs GROUP BY minute, level ORDER BY minute"],
42
- ["JSON", "SELECT pod, json_extract(fieldsJson, '$.message') AS message FROM logs WHERE fieldsJson IS NOT NULL LIMIT 100"]
48
+ ["JSON", "SELECT fieldsJson FROM logs WHERE fieldsJson IS NOT NULL LIMIT 100"]
43
49
  ];
44
50
  var sqlColumnWidth = (column) => column === "message" || column === "fieldsJson" ? 360 : column === "level" ? 90 : 200;
45
51
  function initialTarget() {
@@ -228,22 +234,19 @@ function LogRows({ records, loading, selected, onSelect, follow, setFollow, comp
228
234
  record.pod
229
235
  ]
230
236
  }),
231
- /* @__PURE__ */ require_jsx_runtime.jsx("span", { children: record.message })
237
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_power_log_message.LogMessage, { text: record.message })
232
238
  ]
233
239
  }, record.key))
234
240
  })
235
241
  })
236
242
  });
237
243
  }
238
- function LogDetails({ record, jsonColumn, onClose }) {
244
+ function LogDetails({ record, jsonColumn, onClose, onFilter }) {
239
245
  const structuredFields = require__global_external_react.useMemo(() => {
240
246
  if (!record?.fieldsJson) return "";
241
- try {
242
- return JSON.stringify(JSON.parse(record.fieldsJson), null, 2);
243
- } catch {
244
- return record.fieldsJson;
245
- }
247
+ return require_power_log_json_fields.formatJsonLiteral(record.fieldsJson);
246
248
  }, [record?.fieldsJson]);
249
+ const fieldsEnabled = require__global_external_react.useMemo(() => !require_power_log_json_fields.jsonHasDuplicateKeys(record.fieldsJson ?? ""), [record.fieldsJson]);
247
250
  const [copyFeedback, setCopyFeedback] = require__global_external_react.useState("");
248
251
  require__global_external_react.useEffect(() => setCopyFeedback(""), [structuredFields]);
249
252
  return /* @__PURE__ */ require_jsx_runtime.jsxs("aside", {
@@ -264,7 +267,7 @@ function LogDetails({ record, jsonColumn, onClose }) {
264
267
  className: "power-logs-muted",
265
268
  children: [record.pod && sourceKey(record), record.level].filter(Boolean).join(" · ")
266
269
  }),
267
- record.message && /* @__PURE__ */ require_jsx_runtime.jsx("pre", { children: record.message }),
270
+ record.message && /* @__PURE__ */ require_jsx_runtime.jsx("pre", { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_power_log_message.LogMessage, { text: record.message }) }),
268
271
  record.fieldsJson && /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
269
272
  className: "power-logs-structured-heading",
270
273
  children: [
@@ -293,10 +296,41 @@ function LogDetails({ record, jsonColumn, onClose }) {
293
296
  children: copyFeedback
294
297
  })
295
298
  ]
296
- }), /* @__PURE__ */ require_jsx_runtime.jsx(require_power_log_json.LogJson, { text: structuredFields })] })
299
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(require_power_log_json.LogJson, {
300
+ text: structuredFields,
301
+ fieldsEnabled,
302
+ Icon,
303
+ onFilter
304
+ })] })
297
305
  ]
298
306
  });
299
307
  }
308
+ var sameFieldFilter = (a, b) => a.operator === b.operator && a.path.length === b.path.length && a.path.every((part, index) => part === b.path[index]) && require_power_log_field_filters.jsonValuesEqual(a.value, b.value);
309
+ var fieldFilterLabel = (filter) => `${filter.path.reduce((path, part) => `${path}[${typeof part === "number" ? part : JSON.stringify(part)}]`, "$")} ${filter.operator === "eq" ? "=" : "!="} ${JSON.stringify(filter.value)}`;
310
+ function FieldFilters({ filters, sql = false, disabled = false, onRemove }) {
311
+ if (!filters.length) return null;
312
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
313
+ className: "power-logs-field-filters",
314
+ "aria-label": sql ? "SQL JSON filters" : "Live JSON filters",
315
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("span", {
316
+ className: "power-logs-muted",
317
+ children: [sql ? "Result filters" : "JSON filters", " · AND"]
318
+ }), filters.map((filter, index) => {
319
+ const label = `${filter.column ? `${filter.column} ` : ""}${fieldFilterLabel(filter)}`;
320
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
321
+ type: "button",
322
+ disabled,
323
+ title: label,
324
+ "aria-label": `Remove JSON filter ${label}`,
325
+ onClick: () => onRemove(index),
326
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: label }), /* @__PURE__ */ require_jsx_runtime.jsx(Icon, {
327
+ material: "close",
328
+ size: 14
329
+ })]
330
+ }, index);
331
+ })]
332
+ });
333
+ }
300
334
  function Workspace({ clusterId, contextId }) {
301
335
  const client = require__global_external_react.useMemo(() => require_power_logs_client.createPowerLogsClient({
302
336
  clusterId,
@@ -312,6 +346,10 @@ function Workspace({ clusterId, contextId }) {
312
346
  const [text, setText] = require__global_external_react.useState("");
313
347
  const [level, setLevel] = require__global_external_react.useState("");
314
348
  const [source, setSource] = require__global_external_react.useState(initialSource);
349
+ const [fieldFilters, setFieldFilters] = require__global_external_react.useState([]);
350
+ const matchFields = require__global_external_react.useMemo(() => require_power_log_field_filters.compileJsonFilters(fieldFilters), [fieldFilters]);
351
+ const parsedFields = require__global_external_react.useRef(/* @__PURE__ */ new WeakMap());
352
+ const [sqlFieldFilters, setSqlFieldFilters] = require__global_external_react.useState();
315
353
  const preferences = require_logs_preferences_store.LogsPreferencesStore.getInstanceOrCreate();
316
354
  const limits = require_power_logs_limits.normalizePowerLogsLimits(preferences.limits);
317
355
  require__global_external_react.useEffect(() => {
@@ -325,16 +363,30 @@ function Workspace({ clusterId, contextId }) {
325
363
  const [follow, setFollow] = require__global_external_react.useState(true);
326
364
  const [busy, setBusy] = require__global_external_react.useState(() => Boolean(initialTarget()));
327
365
  const [captures, setCaptures] = require__global_external_react.useState([]);
328
- const [captureId, setCaptureId] = require__global_external_react.useState("");
366
+ const [captureId, updateCaptureId] = require__global_external_react.useState("");
329
367
  const captureSelection = require__global_external_react.useRef(captureId);
330
368
  captureSelection.current = captureId;
369
+ const setCaptureId = (id) => {
370
+ captureSelection.current = id;
371
+ updateCaptureId(id);
372
+ };
331
373
  const deleting = require__global_external_react.useRef(/* @__PURE__ */ new Set());
332
374
  const [deletingCount, setDeletingCount] = require__global_external_react.useState(0);
333
375
  const [capturing, setCapturing] = require__global_external_react.useState();
334
376
  const [capturePending, setCapturePending] = require__global_external_react.useState(false);
335
377
  const [captureMinutes, setCaptureMinutes] = require__global_external_react.useState(15);
336
378
  const [previous, setPrevious] = require__global_external_react.useState(false);
337
- const [sql, setSql] = require__global_external_react.useState(examples[0][1]);
379
+ const [sql, updateSql] = require__global_external_react.useState(examples[0][1]);
380
+ const sqlDraft = require__global_external_react.useRef(sql);
381
+ sqlDraft.current = sql;
382
+ const setSql = (query) => {
383
+ sqlDraft.current = query;
384
+ updateSql(query);
385
+ };
386
+ const captureKeys = require__global_external_react.useRef(/* @__PURE__ */ new Map());
387
+ require__global_external_react.useEffect(() => {
388
+ setSqlFieldFilters((current) => current && (current.rendered !== sql || current.captureId !== captureId) ? void 0 : current);
389
+ }, [sql, captureId]);
338
390
  const [result, setResult] = require__global_external_react.useState();
339
391
  const [resultEvidence, setResultEvidence] = require__global_external_react.useState();
340
392
  const [resultPage, setResultPage] = require__global_external_react.useState(0);
@@ -479,6 +531,7 @@ function Workspace({ clusterId, contextId }) {
479
531
  };
480
532
  require__global_external_react.useEffect(() => {
481
533
  setText("");
534
+ setFieldFilters([]);
482
535
  setSources([]);
483
536
  setTab("live");
484
537
  readHistory();
@@ -613,7 +666,7 @@ function Workspace({ clusterId, contextId }) {
613
666
  setCaptures((items) => [saved, ...items.filter((item) => item.id !== saved.id)]);
614
667
  setTab("captures");
615
668
  setSql(examples[0][1]);
616
- runQuery(saved, examples[0][1]);
669
+ applyPreset("Recent", saved, true);
617
670
  }
618
671
  } catch {
619
672
  if (alive.current) setError("The temporary capture could not be finalized");
@@ -655,11 +708,115 @@ function Workspace({ clusterId, contextId }) {
655
708
  }
656
709
  }
657
710
  };
658
- const filtered = require__global_external_react.useMemo(() => records.filter((record) => (!text || record.message.toLocaleLowerCase().includes(text.toLocaleLowerCase())) && (!level || record.level === level) && (!source || (source.startsWith("container:") ? record.container === source.slice(10) : sourceKey(record) === source))), [
711
+ const applyPreset = async (title, selectedCapture, execute = false) => {
712
+ const captured = selectedCapture ?? captures.find((item) => item.id === captureId);
713
+ if (queryRef.current || !selectedCapture && captureController.current || !captured || captured.state === "collecting" || deleting.current.has(captured.id)) return;
714
+ const draft = execute ? examples[0][1] : sqlDraft.current;
715
+ const id = (0, node_crypto.randomUUID)();
716
+ queryRef.current = id;
717
+ setQueryId(id);
718
+ setError("");
719
+ let prepared;
720
+ try {
721
+ let keys = captureKeys.current.get(captured.id);
722
+ if (!keys) {
723
+ const schema = await client.query(captured.id, id, require_power_log_json_preset.JSON_KEY_DISCOVERY_SQL);
724
+ if (schema.error) throw new Error(schema.error);
725
+ const keyColumn = schema.columns.indexOf("key");
726
+ keys = schema.truncated ? ["\0"] : keyColumn < 0 ? [] : schema.rows.map((row) => row[keyColumn]).filter((key) => typeof key === "string");
727
+ captureKeys.current.set(captured.id, keys);
728
+ if (captureKeys.current.size > 10) captureKeys.current.delete(captureKeys.current.keys().next().value);
729
+ }
730
+ if (!alive.current || queryRef.current !== id || captureSelection.current !== captured.id) return;
731
+ if (sqlDraft.current !== draft) {
732
+ setError("SQL draft changed while detecting JSON fields. Select the preset again to replace it.");
733
+ return;
734
+ }
735
+ prepared = require_power_log_json_preset.buildJsonProjectionSql(keys, { recent: title === "Recent" });
736
+ setSql(prepared);
737
+ setSelectedSqlRow(void 0);
738
+ } catch {
739
+ if (alive.current) setError("Could not detect JSON fields for this snapshot. Try the preset again.");
740
+ } finally {
741
+ if (queryRef.current === id) {
742
+ queryRef.current = "";
743
+ if (alive.current) setQueryId("");
744
+ }
745
+ }
746
+ if (prepared && execute && alive.current) runQuery(captured, prepared);
747
+ };
748
+ const addLiveFilter = (filter) => {
749
+ if (!require_power_log_field_filters.jsonValuesEqual(filter.value, filter.value)) {
750
+ setError("This JSON value is too large or unsupported for filtering");
751
+ return;
752
+ }
753
+ if (fieldFilters.some((current) => sameFieldFilter(current, filter))) return;
754
+ if (fieldFilters.length >= 32) {
755
+ setError("Up to 32 JSON filters can be combined");
756
+ return;
757
+ }
758
+ setFieldFilters([...fieldFilters, filter]);
759
+ };
760
+ const activeSqlFilters = sqlFieldFilters?.rendered === sql && sqlFieldFilters.captureId === captureId ? sqlFieldFilters : void 0;
761
+ const sqlFilteringDisabled = Boolean(queryId || capturePending || deleting.current.has(captureId) || !captures.some((capture) => capture.id === captureId && capture.state !== "collecting"));
762
+ const applySqlFilters = (filters) => {
763
+ if (queryRef.current || captureController.current || sqlFilteringDisabled) return;
764
+ if (!resultEvidence || resultEvidence.sql !== sql) {
765
+ setError("Run the edited SQL query before filtering its results");
766
+ return;
767
+ }
768
+ try {
769
+ const base = activeSqlFilters?.base ?? sql;
770
+ const query = require_power_log_json_filter_sql.buildJsonFilterSql(base, filters);
771
+ setSqlFieldFilters({
772
+ base,
773
+ rendered: query,
774
+ captureId,
775
+ filters
776
+ });
777
+ setSql(query);
778
+ runQuery(void 0, query);
779
+ } catch {
780
+ setError("This JSON filter cannot be added to the query. Check the field path and value size.");
781
+ }
782
+ };
783
+ const addSqlFilter = (column, filter) => {
784
+ const columnNames = result?.columns.map((name) => name.replace(/[A-Z]/g, (letter) => letter.toLowerCase())) ?? [];
785
+ if (!result?.columns.includes(column) || new Set(columnNames).size !== columnNames.length) {
786
+ setError("JSON filters require unique result column names, ignoring case");
787
+ return;
788
+ }
789
+ const filters = activeSqlFilters?.filters ?? [];
790
+ if (filters.some((current) => current.column === column && sameFieldFilter(current, filter))) return;
791
+ if (filters.length >= 32) {
792
+ setError("Up to 32 JSON filters can be combined");
793
+ return;
794
+ }
795
+ applySqlFilters([...filters, {
796
+ ...filter,
797
+ column
798
+ }]);
799
+ };
800
+ const matchesRecordFields = (record) => {
801
+ if (!fieldFilters.length) return true;
802
+ if (!parsedFields.current.has(record)) {
803
+ let fields;
804
+ try {
805
+ fields = JSON.parse(record.fieldsJson ?? "null");
806
+ } catch {
807
+ fields = void 0;
808
+ }
809
+ parsedFields.current.set(record, fields);
810
+ }
811
+ return matchFields(parsedFields.current.get(record));
812
+ };
813
+ const filtered = require__global_external_react.useMemo(() => records.filter((record) => (!text || record.message.toLocaleLowerCase().includes(text.toLocaleLowerCase())) && (!level || record.level === level) && (!source || (source.startsWith("container:") ? record.container === source.slice(10) : sourceKey(record) === source)) && matchesRecordFields(record)), [
659
814
  records,
660
815
  text,
661
816
  level,
662
- source
817
+ source,
818
+ fieldFilters,
819
+ matchFields
663
820
  ]);
664
821
  const chosenCapture = captures.find((item) => item.id === captureId);
665
822
  const collectionNotes = tab === "live" ? [.../* @__PURE__ */ new Set([...notes, ...live ? liveCoverage?.notes ?? [] : []])] : [];
@@ -796,7 +953,7 @@ function Workspace({ clusterId, contextId }) {
796
953
  if (!captureId && latest && !capturePending) {
797
954
  setCaptureId(latest.id);
798
955
  setSql(examples[0][1]);
799
- runQuery(latest, examples[0][1]);
956
+ applyPreset("Recent", latest, true);
800
957
  }
801
958
  refreshCaptures();
802
959
  },
@@ -1036,6 +1193,10 @@ function Workspace({ clusterId, contextId }) {
1036
1193
  })
1037
1194
  ]
1038
1195
  }),
1196
+ /* @__PURE__ */ require_jsx_runtime.jsx(FieldFilters, {
1197
+ filters: fieldFilters,
1198
+ onRemove: (index) => setFieldFilters(fieldFilters.filter((_, item) => item !== index))
1199
+ }),
1039
1200
  /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
1040
1201
  className: "power-logs-muted power-logs-status",
1041
1202
  role: "status",
@@ -1064,7 +1225,8 @@ function Workspace({ clusterId, contextId }) {
1064
1225
  compact
1065
1226
  }), selected && /* @__PURE__ */ require_jsx_runtime.jsx(LogDetails, {
1066
1227
  record: selected,
1067
- onClose: () => setSelected(void 0)
1228
+ onClose: () => setSelected(void 0),
1229
+ onFilter: addLiveFilter
1068
1230
  })]
1069
1231
  })
1070
1232
  ] }) : /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
@@ -1133,7 +1295,7 @@ function Workspace({ clusterId, contextId }) {
1133
1295
  const snapshot = captures.find((item) => item.id === value);
1134
1296
  if (snapshot) {
1135
1297
  setSql(examples[0][1]);
1136
- runQuery(snapshot, examples[0][1]);
1298
+ applyPreset("Recent", snapshot, true);
1137
1299
  }
1138
1300
  },
1139
1301
  options: [{
@@ -1193,7 +1355,8 @@ function Workspace({ clusterId, contextId }) {
1193
1355
  }),
1194
1356
  examples.map(([title, query]) => /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
1195
1357
  type: "button",
1196
- onClick: () => setSql(query),
1358
+ disabled: !!queryId || capturePending,
1359
+ onClick: () => title === "JSON" || title === "Recent" ? void applyPreset(title) : setSql(query),
1197
1360
  children: [
1198
1361
  /* @__PURE__ */ require_jsx_runtime.jsx(Icon, {
1199
1362
  material: title === "Recent" ? "history" : title === "Errors" ? "error_outline" : title === "Timeline" ? "timeline" : "data_object",
@@ -1206,13 +1369,36 @@ function Workspace({ clusterId, contextId }) {
1206
1369
  }, title))
1207
1370
  ]
1208
1371
  }),
1372
+ /* @__PURE__ */ require_jsx_runtime.jsx(FieldFilters, {
1373
+ sql: true,
1374
+ filters: activeSqlFilters?.filters ?? [],
1375
+ disabled: sqlFilteringDisabled,
1376
+ onRemove: (index) => applySqlFilters((activeSqlFilters?.filters ?? []).filter((_, item) => item !== index))
1377
+ }),
1209
1378
  /* @__PURE__ */ require_jsx_runtime.jsx("textarea", {
1210
1379
  rows: 2,
1211
1380
  id: "power-logs-sql",
1212
1381
  value: sql,
1213
1382
  maxLength: 65536,
1214
1383
  onChange: (event) => setSql(event.target.value),
1215
- spellCheck: false
1384
+ spellCheck: false,
1385
+ onClick: (event) => {
1386
+ event.stopPropagation();
1387
+ if (event.detail >= 3) {
1388
+ event.preventDefault();
1389
+ window.getSelection()?.removeAllRanges();
1390
+ event.currentTarget.select();
1391
+ }
1392
+ },
1393
+ onMouseDown: (event) => {
1394
+ event.stopPropagation();
1395
+ if (event.detail >= 3) {
1396
+ event.preventDefault();
1397
+ window.getSelection()?.removeAllRanges();
1398
+ event.currentTarget.focus();
1399
+ event.currentTarget.select();
1400
+ }
1401
+ }
1216
1402
  }),
1217
1403
  result ? /* @__PURE__ */ require_jsx_runtime.jsxs(require_jsx_runtime.Fragment, { children: [
1218
1404
  /* @__PURE__ */ require_jsx_runtime.jsx("div", {
@@ -1260,10 +1446,11 @@ function Workspace({ clusterId, contextId }) {
1260
1446
  children: row.map((cell, j) => /* @__PURE__ */ require_jsx_runtime.jsx("td", {
1261
1447
  "data-column": result.columns[j],
1262
1448
  "data-level": result.columns[j] === "level" ? String(cell) : void 0,
1263
- children: /* @__PURE__ */ require_jsx_runtime.jsx("span", {
1264
- className: "power-logs-cell",
1265
- title: cell === null ? "NULL" : String(cell),
1266
- children: cell === null ? "NULL" : String(cell)
1449
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_power_log_json_cell.LogJsonCell, {
1450
+ value: cell === null ? null : String(cell),
1451
+ message: result.columns[j] === "message",
1452
+ Icon,
1453
+ onFilter: sqlFilteringDisabled ? void 0 : (filter) => addSqlFilter(result.columns[j], filter)
1267
1454
  })
1268
1455
  }, j))
1269
1456
  }, i)) })
@@ -1275,6 +1462,7 @@ function Workspace({ clusterId, contextId }) {
1275
1462
  }), selectedSqlRow && /* @__PURE__ */ require_jsx_runtime.jsx(LogDetails, {
1276
1463
  record: selectedSqlRow.record,
1277
1464
  jsonColumn: selectedSqlRow.jsonColumn,
1465
+ onFilter: !sqlFilteringDisabled && selectedSqlRow.jsonColumn ? (filter) => addSqlFilter(selectedSqlRow.jsonColumn, filter) : void 0,
1278
1466
  onClose: () => setSelectedSqlRow(void 0)
1279
1467
  })]
1280
1468
  }),