xref: /aosp_15_r20/external/pigweed/pw_web/log-viewer/src/utils/download.ts (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://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, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15import { LogEntry } from '../shared/interfaces';
16import { titleCaseToKebabCase } from './strings';
17
18/**
19 * Download .txt file of log files
20 * @param logs logs to be downloaded
21 * @param headers headers of logs
22 * @param viewTitle optional title parameter
23 */
24export function downloadTextLogs(
25  logs: LogEntry[],
26  headers: string[],
27  viewTitle = 'logs',
28) {
29  const maxWidths = headers.map((header) => header.length);
30  const fileName = titleCaseToKebabCase(viewTitle);
31
32  logs.forEach((log) => {
33    log.fields.forEach((field) => {
34      const columnIndex = headers.indexOf(field.key);
35      maxWidths[columnIndex] = Math.max(
36        maxWidths[columnIndex],
37        field.value ? field.value.toString().length : 0,
38      );
39    });
40  });
41
42  const headerRow = headers
43    .map((header, columnIndex) => header.padEnd(maxWidths[columnIndex]))
44    .join('\t');
45  const separator = '';
46  const logRows = logs.map((log) => {
47    const values = new Array(headers.length).fill('');
48    log.fields.forEach((field) => {
49      const columnIndex = headers.indexOf(field.key);
50      values[columnIndex] = field.value ? field.value.toString() : '';
51    });
52    values.forEach((_value, index) => {
53      values[index] = values[index].padEnd(maxWidths[index]);
54    });
55    return values.join('\t');
56  });
57
58  const formattedLogs = [headerRow, separator, ...logRows].join('\n');
59  const blob = new Blob([formattedLogs], { type: 'text/plain' });
60  const downloadLink = document.createElement('a');
61  downloadLink.href = URL.createObjectURL(blob);
62  downloadLink.download = `${fileName}.txt`;
63  downloadLink.click();
64
65  URL.revokeObjectURL(downloadLink.href);
66}
67