@perses-dev/logs-table-plugin 0.3.0-beta.1 → 0.3.0-beta.3

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 (103) hide show
  1. package/__mf/js/LogsTable.c9a77ac4.js +7 -0
  2. package/__mf/js/async/1570.1c819a66.js +3 -0
  3. package/__mf/js/async/1603.89bfb1ad.js +2 -0
  4. package/__mf/js/async/1616.c3be409a.js +1 -0
  5. package/__mf/js/async/2043.dba84aa4.js +2 -0
  6. package/__mf/js/async/2842.7c7a1b3f.js +1 -0
  7. package/__mf/js/async/304.21c30c64.js +37 -0
  8. package/__mf/js/async/392.5cb44640.js +2 -0
  9. package/__mf/js/async/4077.32e3919d.js +1 -0
  10. package/__mf/js/async/4121.d4c9b3e3.js +2 -0
  11. package/__mf/js/async/4401.e12938b2.js +7 -0
  12. package/__mf/js/async/4869.80345aa7.js +1 -0
  13. package/__mf/js/async/5002.1d6e3559.js +1 -0
  14. package/__mf/js/async/5071.be3352f1.js +1 -0
  15. package/__mf/js/async/5587.9e49a823.js +1 -0
  16. package/__mf/js/async/6274.fe68ed99.js +2 -0
  17. package/__mf/js/async/6458.de33906b.js +1 -0
  18. package/__mf/js/async/7177.8dd90707.js +1 -0
  19. package/__mf/js/async/7192.017cbe40.js +1 -0
  20. package/__mf/js/async/7250.05494519.js +1 -0
  21. package/__mf/js/async/7413.c2661694.js +1 -0
  22. package/__mf/js/async/{7445.73c38e72.js → 7445.009cf084.js} +2 -2
  23. package/__mf/js/async/7968.ec249f6f.js +1 -0
  24. package/__mf/js/async/7978.026a8b19.js +1 -0
  25. package/__mf/js/async/8356.f736e620.js +1 -0
  26. package/__mf/js/async/8470.f0bbed7d.js +2 -0
  27. package/__mf/js/async/8542.aa0c5fe3.js +1 -0
  28. package/__mf/js/async/8608.618e49dc.js +1 -0
  29. package/__mf/js/async/8634.231e1601.js +2 -0
  30. package/__mf/js/async/8634.231e1601.js.LICENSE.txt +1 -0
  31. package/__mf/js/async/873.4fd8a061.js +1 -0
  32. package/__mf/js/async/9126.32822d59.js +22 -0
  33. package/__mf/js/async/9235.b68f4586.js +1 -0
  34. package/__mf/js/async/{9293.77eed9f0.js → 9293.ee3265d4.js} +1 -1
  35. package/__mf/js/async/941.ad1062bb.js +2 -0
  36. package/__mf/js/async/9588.b214b983.js +1 -0
  37. package/__mf/js/async/973.3b37ba1a.js +2 -0
  38. package/__mf/js/async/__federation_expose_LogsTable.46e67e99.js +1 -0
  39. package/__mf/js/async/lib-router.c5e3aef3.js +2 -0
  40. package/__mf/js/main.cdde92fa.js +7 -0
  41. package/lib/LogsTable.d.ts.map +1 -1
  42. package/lib/LogsTable.js +5 -0
  43. package/lib/LogsTable.js.map +1 -1
  44. package/lib/LogsTableCsvExportAction.d.ts +6 -0
  45. package/lib/LogsTableCsvExportAction.d.ts.map +1 -0
  46. package/lib/LogsTableCsvExportAction.js +100 -0
  47. package/lib/LogsTableCsvExportAction.js.map +1 -0
  48. package/lib/cjs/LogsTable.js +5 -0
  49. package/lib/cjs/LogsTableCsvExportAction.js +124 -0
  50. package/mf-manifest.json +47 -47
  51. package/mf-stats.json +47 -47
  52. package/package.json +5 -5
  53. package/__mf/js/LogsTable.9bbaab2b.js +0 -7
  54. package/__mf/js/async/1616.1b9a06fe.js +0 -1
  55. package/__mf/js/async/2043.956cdbbb.js +0 -2
  56. package/__mf/js/async/2220.0a7924e7.js +0 -22
  57. package/__mf/js/async/2842.4aad5bc1.js +0 -1
  58. package/__mf/js/async/304.8985bacb.js +0 -37
  59. package/__mf/js/async/392.f9cb0cfc.js +0 -2
  60. package/__mf/js/async/4077.e9103d7c.js +0 -1
  61. package/__mf/js/async/4121.c9ef0518.js +0 -2
  62. package/__mf/js/async/4602.b1cacfe1.js +0 -2
  63. package/__mf/js/async/4602.b1cacfe1.js.LICENSE.txt +0 -1
  64. package/__mf/js/async/4693.125f8180.js +0 -2
  65. package/__mf/js/async/4869.940da5d7.js +0 -1
  66. package/__mf/js/async/5002.1fe02654.js +0 -1
  67. package/__mf/js/async/5071.87183f5a.js +0 -1
  68. package/__mf/js/async/5587.c7e5a39c.js +0 -1
  69. package/__mf/js/async/5652.e6029fc8.js +0 -2
  70. package/__mf/js/async/6090.90cb2be2.js +0 -3
  71. package/__mf/js/async/6274.940dee19.js +0 -2
  72. package/__mf/js/async/6458.b2359789.js +0 -1
  73. package/__mf/js/async/6661.3acf3c47.js +0 -7
  74. package/__mf/js/async/7177.44516b97.js +0 -1
  75. package/__mf/js/async/7192.84e9432b.js +0 -1
  76. package/__mf/js/async/7250.78e3cd06.js +0 -1
  77. package/__mf/js/async/7413.581476fb.js +0 -1
  78. package/__mf/js/async/7968.aaf8a8bc.js +0 -1
  79. package/__mf/js/async/7978.35e0aa88.js +0 -1
  80. package/__mf/js/async/8356.355b4afe.js +0 -1
  81. package/__mf/js/async/8470.878f89da.js +0 -2
  82. package/__mf/js/async/8542.e30a008f.js +0 -1
  83. package/__mf/js/async/8608.072381d3.js +0 -1
  84. package/__mf/js/async/873.a4b44e41.js +0 -1
  85. package/__mf/js/async/9235.33a97899.js +0 -1
  86. package/__mf/js/async/941.c74117a1.js +0 -2
  87. package/__mf/js/async/9588.4e751733.js +0 -1
  88. package/__mf/js/async/__federation_expose_LogsTable.cbd5bfda.js +0 -1
  89. package/__mf/js/async/lib-router.12781636.js +0 -2
  90. package/__mf/js/main.142c22e6.js +0 -7
  91. /package/__mf/css/async/{6661.85c2cbf6.css → 4401.85c2cbf6.css} +0 -0
  92. /package/__mf/js/async/{4693.125f8180.js.LICENSE.txt → 1603.89bfb1ad.js.LICENSE.txt} +0 -0
  93. /package/__mf/js/async/{2043.956cdbbb.js.LICENSE.txt → 2043.dba84aa4.js.LICENSE.txt} +0 -0
  94. /package/__mf/js/async/{392.f9cb0cfc.js.LICENSE.txt → 392.5cb44640.js.LICENSE.txt} +0 -0
  95. /package/__mf/js/async/{4121.c9ef0518.js.LICENSE.txt → 4121.d4c9b3e3.js.LICENSE.txt} +0 -0
  96. /package/__mf/js/async/{6661.3acf3c47.js.LICENSE.txt → 4401.e12938b2.js.LICENSE.txt} +0 -0
  97. /package/__mf/js/async/{6274.940dee19.js.LICENSE.txt → 6274.fe68ed99.js.LICENSE.txt} +0 -0
  98. /package/__mf/js/async/{7445.73c38e72.js.LICENSE.txt → 7445.009cf084.js.LICENSE.txt} +0 -0
  99. /package/__mf/js/async/{8470.878f89da.js.LICENSE.txt → 8470.f0bbed7d.js.LICENSE.txt} +0 -0
  100. /package/__mf/js/async/{2220.0a7924e7.js.LICENSE.txt → 9126.32822d59.js.LICENSE.txt} +0 -0
  101. /package/__mf/js/async/{941.c74117a1.js.LICENSE.txt → 941.ad1062bb.js.LICENSE.txt} +0 -0
  102. /package/__mf/js/async/{5652.e6029fc8.js.LICENSE.txt → 973.3b37ba1a.js.LICENSE.txt} +0 -0
  103. /package/__mf/js/async/{lib-router.12781636.js.LICENSE.txt → lib-router.c5e3aef3.js.LICENSE.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/LogsTable.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { PanelPlugin } from '@perses-dev/plugin-system';\nimport { LogsTableComponent } from './LogsTableComponent';\nimport { LogsTableItemSelectionActionsEditor } from './LogsTableItemSelectionActionsEditor';\nimport { LogsTableSettingsEditor } from './LogsTableSettingsEditor';\nimport { LogsTableOptions, LogsTableProps } from './model';\nimport { LogsTableExportAction } from './LogsTableExportAction';\n\nexport const LogsTable: PanelPlugin<LogsTableOptions, LogsTableProps> = {\n PanelComponent: LogsTableComponent,\n panelOptionsEditorComponents: [\n { label: 'Settings', content: LogsTableSettingsEditor },\n { label: 'Item Actions', content: LogsTableItemSelectionActionsEditor },\n ],\n supportedQueryTypes: ['LogQuery'],\n createInitialOptions: () => ({\n showTime: true,\n allowWrap: true,\n enableDetails: true,\n }),\n actions: [{ component: LogsTableExportAction, location: 'header' }],\n};\n"],"names":["LogsTableComponent","LogsTableItemSelectionActionsEditor","LogsTableSettingsEditor","LogsTableExportAction","LogsTable","PanelComponent","panelOptionsEditorComponents","label","content","supportedQueryTypes","createInitialOptions","showTime","allowWrap","enableDetails","actions","component","location"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,SAASA,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,mCAAmC,QAAQ,wCAAwC;AAC5F,SAASC,uBAAuB,QAAQ,4BAA4B;AAEpE,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,OAAO,MAAMC,YAA2D;IACtEC,gBAAgBL;IAChBM,8BAA8B;QAC5B;YAAEC,OAAO;YAAYC,SAASN;QAAwB;QACtD;YAAEK,OAAO;YAAgBC,SAASP;QAAoC;KACvE;IACDQ,qBAAqB;QAAC;KAAW;IACjCC,sBAAsB,IAAO,CAAA;YAC3BC,UAAU;YACVC,WAAW;YACXC,eAAe;QACjB,CAAA;IACAC,SAAS;QAAC;YAAEC,WAAWZ;YAAuBa,UAAU;QAAS;KAAE;AACrE,EAAE"}
1
+ {"version":3,"sources":["../../src/LogsTable.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { PanelPlugin } from '@perses-dev/plugin-system';\nimport { LogsTableComponent } from './LogsTableComponent';\nimport { LogsTableItemSelectionActionsEditor } from './LogsTableItemSelectionActionsEditor';\nimport { LogsTableSettingsEditor } from './LogsTableSettingsEditor';\nimport { LogsTableOptions, LogsTableProps } from './model';\nimport { LogsTableCsvExportAction } from './LogsTableCsvExportAction';\nimport { LogsTableExportAction } from './LogsTableExportAction';\n\nexport const LogsTable: PanelPlugin<LogsTableOptions, LogsTableProps> = {\n PanelComponent: LogsTableComponent,\n panelOptionsEditorComponents: [\n { label: 'Settings', content: LogsTableSettingsEditor },\n { label: 'Item Actions', content: LogsTableItemSelectionActionsEditor },\n ],\n supportedQueryTypes: ['LogQuery'],\n createInitialOptions: () => ({\n showTime: true,\n allowWrap: true,\n enableDetails: true,\n }),\n actions: [\n { component: LogsTableExportAction, location: 'header' },\n { component: LogsTableCsvExportAction, location: 'header' },\n ],\n};\n"],"names":["LogsTableComponent","LogsTableItemSelectionActionsEditor","LogsTableSettingsEditor","LogsTableCsvExportAction","LogsTableExportAction","LogsTable","PanelComponent","panelOptionsEditorComponents","label","content","supportedQueryTypes","createInitialOptions","showTime","allowWrap","enableDetails","actions","component","location"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAGjC,SAASA,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,mCAAmC,QAAQ,wCAAwC;AAC5F,SAASC,uBAAuB,QAAQ,4BAA4B;AAEpE,SAASC,wBAAwB,QAAQ,6BAA6B;AACtE,SAASC,qBAAqB,QAAQ,0BAA0B;AAEhE,OAAO,MAAMC,YAA2D;IACtEC,gBAAgBN;IAChBO,8BAA8B;QAC5B;YAAEC,OAAO;YAAYC,SAASP;QAAwB;QACtD;YAAEM,OAAO;YAAgBC,SAASR;QAAoC;KACvE;IACDS,qBAAqB;QAAC;KAAW;IACjCC,sBAAsB,IAAO,CAAA;YAC3BC,UAAU;YACVC,WAAW;YACXC,eAAe;QACjB,CAAA;IACAC,SAAS;QACP;YAAEC,WAAWZ;YAAuBa,UAAU;QAAS;QACvD;YAAED,WAAWb;YAA0Bc,UAAU;QAAS;KAC3D;AACH,EAAE"}
@@ -0,0 +1,6 @@
1
+ import { LogEntry } from '@perses-dev/spec';
2
+ import { LogsTableProps } from './model';
3
+ export declare function collectLabelKeys(entries: LogEntry[]): string[];
4
+ export declare function buildLogsCsvString(entries: LogEntry[]): string;
5
+ export declare const LogsTableCsvExportAction: React.FC<LogsTableProps>;
6
+ //# sourceMappingURL=LogsTableCsvExportAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogsTableCsvExportAction.d.ts","sourceRoot":"","sources":["../../src/LogsTableCsvExportAction.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAQ9D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAc9D;AAED,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAuC7D,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // Copyright The Perses Authors
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { InfoTooltip } from '@perses-dev/components';
15
+ import { IconButton } from '@mui/material';
16
+ import FileDelimitedOutline from 'mdi-material-ui/FileDelimitedOutline';
17
+ import { escapeCsvValue, formatTimestampISO, sanitizeFilename } from '@perses-dev/plugin-system';
18
+ import { useCallback, useMemo } from 'react';
19
+ import { stripAnsi } from './utils/ansi';
20
+ export function collectLabelKeys(entries) {
21
+ const keys = new Set();
22
+ for (const entry of entries){
23
+ for (const key of Object.keys(entry.labels)){
24
+ keys.add(key);
25
+ }
26
+ }
27
+ return Array.from(keys).sort();
28
+ }
29
+ export function buildLogsCsvString(entries) {
30
+ const labelKeys = collectLabelKeys(entries);
31
+ const headerColumns = [
32
+ 'timestamp',
33
+ 'body',
34
+ ...labelKeys
35
+ ];
36
+ const headerRow = headerColumns.map(escapeCsvValue).join(',');
37
+ const dataRows = entries.map((entry)=>{
38
+ const timestamp = escapeCsvValue(formatTimestampISO(entry.timestamp));
39
+ const body = escapeCsvValue(stripAnsi(entry.line));
40
+ const labels = labelKeys.map((key)=>escapeCsvValue(entry.labels[key] ?? ''));
41
+ return [
42
+ timestamp,
43
+ body,
44
+ ...labels
45
+ ].join(',');
46
+ });
47
+ return [
48
+ headerRow,
49
+ ...dataRows
50
+ ].join('\n') + '\n';
51
+ }
52
+ export const LogsTableCsvExportAction = ({ queryResults, definition })=>{
53
+ const entries = useMemo(()=>{
54
+ return queryResults.flatMap((q)=>q.data?.logs?.entries ?? []);
55
+ }, [
56
+ queryResults
57
+ ]);
58
+ const isDisabled = !entries.length;
59
+ const handleDownload = useCallback(()=>{
60
+ if (isDisabled) return;
61
+ try {
62
+ const csvString = buildLogsCsvString(entries);
63
+ const blob = new Blob([
64
+ csvString
65
+ ], {
66
+ type: 'text/csv;charset=utf-8'
67
+ });
68
+ const url = URL.createObjectURL(blob);
69
+ const link = document.createElement('a');
70
+ link.href = url;
71
+ const title = definition?.spec?.display?.name || 'Logs Table Data';
72
+ const baseFilename = sanitizeFilename(title);
73
+ link.download = `${baseFilename}_data.csv`;
74
+ document.body.appendChild(link);
75
+ link.click();
76
+ document.body.removeChild(link);
77
+ URL.revokeObjectURL(url);
78
+ } catch (error) {
79
+ console.error('Logs table CSV export failed:', error);
80
+ }
81
+ }, [
82
+ definition,
83
+ entries,
84
+ isDisabled
85
+ ]);
86
+ return /*#__PURE__*/ _jsx(InfoTooltip, {
87
+ description: isDisabled ? 'No data to export' : 'Export as CSV',
88
+ children: /*#__PURE__*/ _jsx(IconButton, {
89
+ disabled: isDisabled,
90
+ size: "small",
91
+ onClick: handleDownload,
92
+ "aria-label": "Export Logs Table Data as CSV",
93
+ children: /*#__PURE__*/ _jsx(FileDelimitedOutline, {
94
+ fontSize: "inherit"
95
+ })
96
+ })
97
+ });
98
+ };
99
+
100
+ //# sourceMappingURL=LogsTableCsvExportAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/LogsTableCsvExportAction.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { InfoTooltip } from '@perses-dev/components';\nimport { IconButton } from '@mui/material';\nimport FileDelimitedOutline from 'mdi-material-ui/FileDelimitedOutline';\nimport { escapeCsvValue, formatTimestampISO, sanitizeFilename } from '@perses-dev/plugin-system';\nimport { LogEntry } from '@perses-dev/spec';\nimport { useCallback, useMemo } from 'react';\nimport { LogsTableProps } from './model';\nimport { stripAnsi } from './utils/ansi';\n\nexport function collectLabelKeys(entries: LogEntry[]): string[] {\n const keys = new Set<string>();\n for (const entry of entries) {\n for (const key of Object.keys(entry.labels)) {\n keys.add(key);\n }\n }\n return Array.from(keys).sort();\n}\n\nexport function buildLogsCsvString(entries: LogEntry[]): string {\n const labelKeys = collectLabelKeys(entries);\n\n const headerColumns = ['timestamp', 'body', ...labelKeys];\n const headerRow = headerColumns.map(escapeCsvValue).join(',');\n\n const dataRows = entries.map((entry) => {\n const timestamp = escapeCsvValue(formatTimestampISO(entry.timestamp));\n const body = escapeCsvValue(stripAnsi(entry.line));\n const labels = labelKeys.map((key) => escapeCsvValue(entry.labels[key] ?? ''));\n return [timestamp, body, ...labels].join(',');\n });\n\n return [headerRow, ...dataRows].join('\\n') + '\\n';\n}\n\nexport const LogsTableCsvExportAction: React.FC<LogsTableProps> = ({ queryResults, definition }) => {\n const entries = useMemo(() => {\n return queryResults.flatMap((q) => q.data?.logs?.entries ?? []);\n }, [queryResults]);\n\n const isDisabled = !entries.length;\n\n const handleDownload = useCallback((): void => {\n if (isDisabled) return;\n try {\n const csvString = buildLogsCsvString(entries);\n const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n const title = definition?.spec?.display?.name || 'Logs Table Data';\n const baseFilename = sanitizeFilename(title);\n link.download = `${baseFilename}_data.csv`;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n } catch (error) {\n console.error('Logs table CSV export failed:', error);\n }\n }, [definition, entries, isDisabled]);\n\n return (\n <InfoTooltip description={isDisabled ? 'No data to export' : 'Export as CSV'}>\n <IconButton\n disabled={isDisabled}\n size=\"small\"\n onClick={handleDownload}\n aria-label=\"Export Logs Table Data as CSV\"\n >\n <FileDelimitedOutline fontSize=\"inherit\" />\n </IconButton>\n </InfoTooltip>\n );\n};\n"],"names":["InfoTooltip","IconButton","FileDelimitedOutline","escapeCsvValue","formatTimestampISO","sanitizeFilename","useCallback","useMemo","stripAnsi","collectLabelKeys","entries","keys","Set","entry","key","Object","labels","add","Array","from","sort","buildLogsCsvString","labelKeys","headerColumns","headerRow","map","join","dataRows","timestamp","body","line","LogsTableCsvExportAction","queryResults","definition","flatMap","q","data","logs","isDisabled","length","handleDownload","csvString","blob","Blob","type","url","URL","createObjectURL","link","document","createElement","href","title","spec","display","name","baseFilename","download","appendChild","click","removeChild","revokeObjectURL","error","console","description","disabled","size","onClick","aria-label","fontSize"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,WAAW,QAAQ,yBAAyB;AACrD,SAASC,UAAU,QAAQ,gBAAgB;AAC3C,OAAOC,0BAA0B,uCAAuC;AACxE,SAASC,cAAc,EAAEC,kBAAkB,EAAEC,gBAAgB,QAAQ,4BAA4B;AAEjG,SAASC,WAAW,EAAEC,OAAO,QAAQ,QAAQ;AAE7C,SAASC,SAAS,QAAQ,eAAe;AAEzC,OAAO,SAASC,iBAAiBC,OAAmB;IAClD,MAAMC,OAAO,IAAIC;IACjB,KAAK,MAAMC,SAASH,QAAS;QAC3B,KAAK,MAAMI,OAAOC,OAAOJ,IAAI,CAACE,MAAMG,MAAM,EAAG;YAC3CL,KAAKM,GAAG,CAACH;QACX;IACF;IACA,OAAOI,MAAMC,IAAI,CAACR,MAAMS,IAAI;AAC9B;AAEA,OAAO,SAASC,mBAAmBX,OAAmB;IACpD,MAAMY,YAAYb,iBAAiBC;IAEnC,MAAMa,gBAAgB;QAAC;QAAa;WAAWD;KAAU;IACzD,MAAME,YAAYD,cAAcE,GAAG,CAACtB,gBAAgBuB,IAAI,CAAC;IAEzD,MAAMC,WAAWjB,QAAQe,GAAG,CAAC,CAACZ;QAC5B,MAAMe,YAAYzB,eAAeC,mBAAmBS,MAAMe,SAAS;QACnE,MAAMC,OAAO1B,eAAeK,UAAUK,MAAMiB,IAAI;QAChD,MAAMd,SAASM,UAAUG,GAAG,CAAC,CAACX,MAAQX,eAAeU,MAAMG,MAAM,CAACF,IAAI,IAAI;QAC1E,OAAO;YAACc;YAAWC;eAASb;SAAO,CAACU,IAAI,CAAC;IAC3C;IAEA,OAAO;QAACF;WAAcG;KAAS,CAACD,IAAI,CAAC,QAAQ;AAC/C;AAEA,OAAO,MAAMK,2BAAqD,CAAC,EAAEC,YAAY,EAAEC,UAAU,EAAE;IAC7F,MAAMvB,UAAUH,QAAQ;QACtB,OAAOyB,aAAaE,OAAO,CAAC,CAACC,IAAMA,EAAEC,IAAI,EAAEC,MAAM3B,WAAW,EAAE;IAChE,GAAG;QAACsB;KAAa;IAEjB,MAAMM,aAAa,CAAC5B,QAAQ6B,MAAM;IAElC,MAAMC,iBAAiBlC,YAAY;QACjC,IAAIgC,YAAY;QAChB,IAAI;YACF,MAAMG,YAAYpB,mBAAmBX;YACrC,MAAMgC,OAAO,IAAIC,KAAK;gBAACF;aAAU,EAAE;gBAAEG,MAAM;YAAyB;YACpE,MAAMC,MAAMC,IAAIC,eAAe,CAACL;YAChC,MAAMM,OAAOC,SAASC,aAAa,CAAC;YACpCF,KAAKG,IAAI,GAAGN;YACZ,MAAMO,QAAQnB,YAAYoB,MAAMC,SAASC,QAAQ;YACjD,MAAMC,eAAenD,iBAAiB+C;YACtCJ,KAAKS,QAAQ,GAAG,GAAGD,aAAa,SAAS,CAAC;YAC1CP,SAASpB,IAAI,CAAC6B,WAAW,CAACV;YAC1BA,KAAKW,KAAK;YACVV,SAASpB,IAAI,CAAC+B,WAAW,CAACZ;YAC1BF,IAAIe,eAAe,CAAChB;QACtB,EAAE,OAAOiB,OAAO;YACdC,QAAQD,KAAK,CAAC,iCAAiCA;QACjD;IACF,GAAG;QAAC7B;QAAYvB;QAAS4B;KAAW;IAEpC,qBACE,KAACtC;QAAYgE,aAAa1B,aAAa,sBAAsB;kBAC3D,cAAA,KAACrC;YACCgE,UAAU3B;YACV4B,MAAK;YACLC,SAAS3B;YACT4B,cAAW;sBAEX,cAAA,KAAClE;gBAAqBmE,UAAS;;;;AAIvC,EAAE"}
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "LogsTable", {
23
23
  const _LogsTableComponent = require("./LogsTableComponent");
24
24
  const _LogsTableItemSelectionActionsEditor = require("./LogsTableItemSelectionActionsEditor");
25
25
  const _LogsTableSettingsEditor = require("./LogsTableSettingsEditor");
26
+ const _LogsTableCsvExportAction = require("./LogsTableCsvExportAction");
26
27
  const _LogsTableExportAction = require("./LogsTableExportAction");
27
28
  const LogsTable = {
28
29
  PanelComponent: _LogsTableComponent.LogsTableComponent,
@@ -48,6 +49,10 @@ const LogsTable = {
48
49
  {
49
50
  component: _LogsTableExportAction.LogsTableExportAction,
50
51
  location: 'header'
52
+ },
53
+ {
54
+ component: _LogsTableCsvExportAction.LogsTableCsvExportAction,
55
+ location: 'header'
51
56
  }
52
57
  ]
53
58
  };
@@ -0,0 +1,124 @@
1
+ // Copyright The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ function _export(target, all) {
18
+ for(var name in all)Object.defineProperty(target, name, {
19
+ enumerable: true,
20
+ get: Object.getOwnPropertyDescriptor(all, name).get
21
+ });
22
+ }
23
+ _export(exports, {
24
+ get LogsTableCsvExportAction () {
25
+ return LogsTableCsvExportAction;
26
+ },
27
+ get buildLogsCsvString () {
28
+ return buildLogsCsvString;
29
+ },
30
+ get collectLabelKeys () {
31
+ return collectLabelKeys;
32
+ }
33
+ });
34
+ const _jsxruntime = require("react/jsx-runtime");
35
+ const _components = require("@perses-dev/components");
36
+ const _material = require("@mui/material");
37
+ const _FileDelimitedOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/FileDelimitedOutline"));
38
+ const _pluginsystem = require("@perses-dev/plugin-system");
39
+ const _react = require("react");
40
+ const _ansi = require("./utils/ansi");
41
+ function _interop_require_default(obj) {
42
+ return obj && obj.__esModule ? obj : {
43
+ default: obj
44
+ };
45
+ }
46
+ function collectLabelKeys(entries) {
47
+ const keys = new Set();
48
+ for (const entry of entries){
49
+ for (const key of Object.keys(entry.labels)){
50
+ keys.add(key);
51
+ }
52
+ }
53
+ return Array.from(keys).sort();
54
+ }
55
+ function buildLogsCsvString(entries) {
56
+ const labelKeys = collectLabelKeys(entries);
57
+ const headerColumns = [
58
+ 'timestamp',
59
+ 'body',
60
+ ...labelKeys
61
+ ];
62
+ const headerRow = headerColumns.map(_pluginsystem.escapeCsvValue).join(',');
63
+ const dataRows = entries.map((entry)=>{
64
+ const timestamp = (0, _pluginsystem.escapeCsvValue)((0, _pluginsystem.formatTimestampISO)(entry.timestamp));
65
+ const body = (0, _pluginsystem.escapeCsvValue)((0, _ansi.stripAnsi)(entry.line));
66
+ const labels = labelKeys.map((key)=>(0, _pluginsystem.escapeCsvValue)(entry.labels[key] ?? ''));
67
+ return [
68
+ timestamp,
69
+ body,
70
+ ...labels
71
+ ].join(',');
72
+ });
73
+ return [
74
+ headerRow,
75
+ ...dataRows
76
+ ].join('\n') + '\n';
77
+ }
78
+ const LogsTableCsvExportAction = ({ queryResults, definition })=>{
79
+ const entries = (0, _react.useMemo)(()=>{
80
+ return queryResults.flatMap((q)=>q.data?.logs?.entries ?? []);
81
+ }, [
82
+ queryResults
83
+ ]);
84
+ const isDisabled = !entries.length;
85
+ const handleDownload = (0, _react.useCallback)(()=>{
86
+ if (isDisabled) return;
87
+ try {
88
+ const csvString = buildLogsCsvString(entries);
89
+ const blob = new Blob([
90
+ csvString
91
+ ], {
92
+ type: 'text/csv;charset=utf-8'
93
+ });
94
+ const url = URL.createObjectURL(blob);
95
+ const link = document.createElement('a');
96
+ link.href = url;
97
+ const title = definition?.spec?.display?.name || 'Logs Table Data';
98
+ const baseFilename = (0, _pluginsystem.sanitizeFilename)(title);
99
+ link.download = `${baseFilename}_data.csv`;
100
+ document.body.appendChild(link);
101
+ link.click();
102
+ document.body.removeChild(link);
103
+ URL.revokeObjectURL(url);
104
+ } catch (error) {
105
+ console.error('Logs table CSV export failed:', error);
106
+ }
107
+ }, [
108
+ definition,
109
+ entries,
110
+ isDisabled
111
+ ]);
112
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
113
+ description: isDisabled ? 'No data to export' : 'Export as CSV',
114
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.IconButton, {
115
+ disabled: isDisabled,
116
+ size: "small",
117
+ onClick: handleDownload,
118
+ "aria-label": "Export Logs Table Data as CSV",
119
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_FileDelimitedOutline.default, {
120
+ fontSize: "inherit"
121
+ })
122
+ })
123
+ });
124
+ };
package/mf-manifest.json CHANGED
@@ -5,11 +5,11 @@
5
5
  "name": "LogsTable",
6
6
  "type": "app",
7
7
  "buildInfo": {
8
- "buildVersion": "0.3.0-beta.1",
8
+ "buildVersion": "0.3.0-beta.3",
9
9
  "buildName": "@perses-dev/logs-table-plugin"
10
10
  },
11
11
  "remoteEntry": {
12
- "name": "__mf/js/LogsTable.9bbaab2b.js",
12
+ "name": "__mf/js/LogsTable.c9a77ac4.js",
13
13
  "path": "",
14
14
  "type": "global"
15
15
  },
@@ -20,7 +20,7 @@
20
20
  "api": ""
21
21
  },
22
22
  "globalName": "LogsTable",
23
- "pluginVersion": "2.5.1",
23
+ "pluginVersion": "2.6.0",
24
24
  "getPublicPath": "function() { const prefix = window.PERSES_PLUGIN_ASSETS_PATH || window.PERSES_APP_CONFIG?.api_prefix || \"\"; return prefix + \"/plugins/LogsTable/\"; }"
25
25
  },
26
26
  "shared": [
@@ -34,7 +34,7 @@
34
34
  "js": {
35
35
  "async": [],
36
36
  "sync": [
37
- "__mf/js/async/6274.940dee19.js"
37
+ "__mf/js/async/6274.fe68ed99.js"
38
38
  ]
39
39
  },
40
40
  "css": {
@@ -54,8 +54,8 @@
54
54
  "js": {
55
55
  "async": [],
56
56
  "sync": [
57
- "__mf/js/async/1616.1b9a06fe.js",
58
- "__mf/js/async/9235.33a97899.js"
57
+ "__mf/js/async/1616.c3be409a.js",
58
+ "__mf/js/async/9235.b68f4586.js"
59
59
  ]
60
60
  },
61
61
  "css": {
@@ -75,8 +75,8 @@
75
75
  "js": {
76
76
  "async": [],
77
77
  "sync": [
78
- "__mf/js/async/5587.c7e5a39c.js",
79
- "__mf/js/async/7968.aaf8a8bc.js"
78
+ "__mf/js/async/5587.9e49a823.js",
79
+ "__mf/js/async/7968.ec249f6f.js"
80
80
  ]
81
81
  },
82
82
  "css": {
@@ -89,20 +89,20 @@
89
89
  {
90
90
  "id": "LogsTable:@perses-dev/components",
91
91
  "name": "@perses-dev/components",
92
- "version": "0.54.0-beta.8",
92
+ "version": "0.54.0-beta.11",
93
93
  "singleton": true,
94
- "requiredVersion": "^0.54.0-beta.8",
94
+ "requiredVersion": "^0.54.0-beta.11",
95
95
  "assets": {
96
96
  "js": {
97
97
  "async": [],
98
98
  "sync": [
99
- "__mf/js/async/6661.3acf3c47.js"
99
+ "__mf/js/async/4401.e12938b2.js"
100
100
  ]
101
101
  },
102
102
  "css": {
103
103
  "async": [],
104
104
  "sync": [
105
- "__mf/css/async/6661.85c2cbf6.css"
105
+ "__mf/css/async/4401.85c2cbf6.css"
106
106
  ]
107
107
  }
108
108
  },
@@ -111,14 +111,14 @@
111
111
  {
112
112
  "id": "LogsTable:@perses-dev/dashboards",
113
113
  "name": "@perses-dev/dashboards",
114
- "version": "0.54.0-beta.8",
114
+ "version": "0.54.0-beta.11",
115
115
  "singleton": true,
116
- "requiredVersion": "^0.54.0-beta.8",
116
+ "requiredVersion": "^0.54.0-beta.11",
117
117
  "assets": {
118
118
  "js": {
119
119
  "async": [],
120
120
  "sync": [
121
- "__mf/js/async/2220.0a7924e7.js"
121
+ "__mf/js/async/9126.32822d59.js"
122
122
  ]
123
123
  },
124
124
  "css": {
@@ -131,14 +131,14 @@
131
131
  {
132
132
  "id": "LogsTable:@perses-dev/plugin-system",
133
133
  "name": "@perses-dev/plugin-system",
134
- "version": "0.54.0-beta.8",
134
+ "version": "0.54.0-beta.11",
135
135
  "singleton": true,
136
- "requiredVersion": "^0.54.0-beta.8",
136
+ "requiredVersion": "^0.54.0-beta.11",
137
137
  "assets": {
138
138
  "js": {
139
139
  "async": [],
140
140
  "sync": [
141
- "__mf/js/async/6090.90cb2be2.js"
141
+ "__mf/js/async/1570.1c819a66.js"
142
142
  ]
143
143
  },
144
144
  "css": {
@@ -158,7 +158,7 @@
158
158
  "js": {
159
159
  "async": [],
160
160
  "sync": [
161
- "__mf/js/async/2842.4aad5bc1.js"
161
+ "__mf/js/async/2842.7c7a1b3f.js"
162
162
  ]
163
163
  },
164
164
  "css": {
@@ -171,14 +171,14 @@
171
171
  {
172
172
  "id": "LogsTable:date-fns",
173
173
  "name": "date-fns",
174
- "version": "4.1.0",
174
+ "version": "4.4.0",
175
175
  "singleton": true,
176
- "requiredVersion": "^4.1.0",
176
+ "requiredVersion": "^4.4.0",
177
177
  "assets": {
178
178
  "js": {
179
179
  "async": [],
180
180
  "sync": [
181
- "__mf/js/async/7192.84e9432b.js"
181
+ "__mf/js/async/7192.017cbe40.js"
182
182
  ]
183
183
  },
184
184
  "css": {
@@ -198,7 +198,7 @@
198
198
  "js": {
199
199
  "async": [],
200
200
  "sync": [
201
- "__mf/js/async/873.a4b44e41.js"
201
+ "__mf/js/async/873.4fd8a061.js"
202
202
  ]
203
203
  },
204
204
  "css": {
@@ -218,7 +218,7 @@
218
218
  "js": {
219
219
  "async": [],
220
220
  "sync": [
221
- "__mf/js/async/392.f9cb0cfc.js"
221
+ "__mf/js/async/392.5cb44640.js"
222
222
  ]
223
223
  },
224
224
  "css": {
@@ -238,7 +238,7 @@
238
238
  "js": {
239
239
  "async": [],
240
240
  "sync": [
241
- "__mf/js/async/8470.878f89da.js"
241
+ "__mf/js/async/8470.f0bbed7d.js"
242
242
  ]
243
243
  },
244
244
  "css": {
@@ -258,7 +258,7 @@
258
258
  "js": {
259
259
  "async": [],
260
260
  "sync": [
261
- "__mf/js/async/4121.c9ef0518.js"
261
+ "__mf/js/async/4121.d4c9b3e3.js"
262
262
  ]
263
263
  },
264
264
  "css": {
@@ -278,8 +278,8 @@
278
278
  "js": {
279
279
  "async": [],
280
280
  "sync": [
281
- "__mf/js/async/4077.e9103d7c.js",
282
- "__mf/js/async/6458.b2359789.js"
281
+ "__mf/js/async/4077.32e3919d.js",
282
+ "__mf/js/async/6458.de33906b.js"
283
283
  ]
284
284
  },
285
285
  "css": {
@@ -299,7 +299,7 @@
299
299
  "js": {
300
300
  "async": [],
301
301
  "sync": [
302
- "__mf/js/async/7978.35e0aa88.js"
302
+ "__mf/js/async/7978.026a8b19.js"
303
303
  ]
304
304
  },
305
305
  "css": {
@@ -318,25 +318,25 @@
318
318
  "assets": {
319
319
  "js": {
320
320
  "sync": [
321
- "__mf/js/async/9293.77eed9f0.js",
322
- "__mf/js/async/7445.73c38e72.js",
323
- "__mf/js/async/8608.072381d3.js",
324
- "__mf/js/async/4602.b1cacfe1.js",
325
- "__mf/js/async/__federation_expose_LogsTable.cbd5bfda.js"
321
+ "__mf/js/async/9293.ee3265d4.js",
322
+ "__mf/js/async/7445.009cf084.js",
323
+ "__mf/js/async/8608.618e49dc.js",
324
+ "__mf/js/async/8634.231e1601.js",
325
+ "__mf/js/async/__federation_expose_LogsTable.46e67e99.js"
326
326
  ],
327
327
  "async": [
328
- "__mf/js/async/lib-router.12781636.js",
329
- "__mf/js/async/8356.355b4afe.js",
330
- "__mf/js/async/8542.e30a008f.js",
331
- "__mf/js/async/304.8985bacb.js",
332
- "__mf/js/async/4693.125f8180.js",
333
- "__mf/js/async/5652.e6029fc8.js",
334
- "__mf/js/async/9588.4e751733.js",
335
- "__mf/js/async/5071.87183f5a.js",
336
- "__mf/js/async/2043.956cdbbb.js",
337
- "__mf/js/async/7413.581476fb.js",
338
- "__mf/js/async/4869.940da5d7.js",
339
- "__mf/js/async/7177.44516b97.js"
328
+ "__mf/js/async/lib-router.c5e3aef3.js",
329
+ "__mf/js/async/8356.f736e620.js",
330
+ "__mf/js/async/8542.aa0c5fe3.js",
331
+ "__mf/js/async/304.21c30c64.js",
332
+ "__mf/js/async/1603.89bfb1ad.js",
333
+ "__mf/js/async/973.3b37ba1a.js",
334
+ "__mf/js/async/9588.b214b983.js",
335
+ "__mf/js/async/5071.be3352f1.js",
336
+ "__mf/js/async/2043.dba84aa4.js",
337
+ "__mf/js/async/7413.c2661694.js",
338
+ "__mf/js/async/4869.80345aa7.js",
339
+ "__mf/js/async/7177.8dd90707.js"
340
340
  ]
341
341
  },
342
342
  "css": {
@@ -344,7 +344,7 @@
344
344
  "__mf/css/async/__federation_expose_LogsTable.eedb54d8.css"
345
345
  ],
346
346
  "async": [
347
- "__mf/css/async/6661.85c2cbf6.css"
347
+ "__mf/css/async/4401.85c2cbf6.css"
348
348
  ]
349
349
  }
350
350
  },