| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import * as constant from '../src/constants'; |
| import { State } from '../src/state'; |
| import { LogField } from '../src/fields'; |
| |
| export class LogHeader { |
| private tableHeader: Element; |
| private maxWidths = {} as Record<string, number>; |
| |
| constructor(private state: State) { |
| const fields = this.state.currentFields; |
| const keys = Object.keys(fields); |
| this.tableHeader = this.initTableHeader(); |
| for (let i = 0; i < keys.length; i++) { |
| const header = keys[i] as LogField; |
| const headerCell = document.createElement('div'); |
| this.maxWidths[header] = 0; |
| headerCell.id = header; |
| headerCell.style.width = fields[header].width; |
| headerCell.innerText = fields[header].displayName; |
| this.tableHeader.appendChild(headerCell); |
| if (i === keys.length - 1) { |
| break; |
| } |
| const headerDiv = document.createElement('div'); |
| headerDiv.classList.add('column-resize'); |
| headerCell.appendChild(headerDiv); |
| createResizableColumn(this.state, this.maxWidths, headerCell, headerDiv); |
| } |
| } |
| |
| /** |
| * Returns the core element. |
| */ |
| get element() { |
| return this.tableHeader; |
| } |
| |
| /** |
| * Initializes the header element. |
| * |
| * @return the header element. |
| */ |
| private initTableHeader(): HTMLDivElement { |
| const tableHeader = document.createElement('div'); |
| tableHeader.id = 'logs-table-header'; |
| return tableHeader; |
| } |
| |
| public setMaxCellWidth(id: LogField, maxWidth: number): void { |
| this.maxWidths[id] = maxWidth; |
| }; |
| } |
| |
| /** |
| * Creates resizable element in header to determine column size. |
| * @param header identify which header is active. |
| * @param cell header cell of the column. |
| * @param resizer element in the header cell that handles the resizing. |
| */ |
| function createResizableColumn(state: State, maxWidths: Record<string, number>, |
| cell: HTMLElement, resizer: HTMLElement) { |
| |
| let header = cell.id as LogField; |
| let w = 0; |
| let x = 0; |
| |
| const mouseDoubleClickHandler = function () { |
| cell.style.width = `${maxWidths[header]}px`; |
| state.setHeaderWidth(header, cell.style.width); |
| }; |
| |
| const mouseDownHandler = function (e: MouseEvent) { |
| x = e.clientX; |
| w = cell.clientWidth; |
| |
| document.addEventListener('mousemove', mouseMoveHandler); |
| document.addEventListener('mouseup', mouseUpHandler); |
| |
| resizer.classList.add('resizing'); |
| }; |
| |
| const mouseMoveHandler = function (e: MouseEvent) { |
| const dx = e.clientX - x; |
| if ((w + dx) > constant.COL_MINWIDTH) { |
| cell.style.width = `${w + dx}px`; |
| state.setHeaderWidth(header, cell.style.width); |
| } |
| }; |
| |
| const mouseUpHandler = function () { |
| resizer.classList.remove('resizing'); |
| document.removeEventListener('mousemove', mouseMoveHandler); |
| document.removeEventListener('mouseup', mouseUpHandler); |
| }; |
| |
| resizer.addEventListener('mousedown', mouseDownHandler); |
| resizer.addEventListener('dblclick', mouseDoubleClickHandler); |
| } |
| |