import { PanelOptions, TableRowConfig } from '../types'; import { Table, Button, HorizontalGroup } from '@grafana/ui'; import { PanelProps, toDataFrame, FieldType, applyFieldOverrides, createTheme, DataFrame, DataLinkClickEvent } from '@grafana/data'; import React, { useState } from 'react'; import * as _ from 'lodash'; interface Props extends PanelProps { } export function Panel({ options, data, width, height, timeRange, onChangeTimeRange }: Props) { console.log('panel', data); const configs: TableRowConfig[] = []; const [tasks, setTasks] = useState(configs); const dataFrame = getDataFrameForTable(tasks, setTasks); function onAddTaskClick(): void { const configs = [...tasks, createConfigItem()]; setTasks(configs); } return (
); } function getDataFrameForTable(configs: TableRowConfig[], setTasks: any): DataFrame { const dataFrame = toDataFrame({ name: 'A', fields: [ { name: 'Time', type: FieldType.number, values: _.map(configs, config => convertTimestampToDate(config.timestamp)), }, { name: 'User', type: FieldType.string, values: _.map(configs, config => config.user), }, { name: 'Datasource', type: FieldType.string, values: _.map(configs, config => config.datasource), }, { name: 'Exported Rows', type: FieldType.number, values: _.map(configs, config => config.rowsCount), }, { name: 'Progress', type: FieldType.string, values: _.map(configs, config => `${config.progress}%`), }, { name: 'Status', type: FieldType.string, values: _.map(configs, config => config.status), }, { name: 'Download CSV', type: FieldType.string, values: _.map(configs, config => `data:image/png;base64,${DOWNLOAD_ICON_BASE_64}`), config: { custom: { filterable: false, displayMode: 'image', }, links: [ { targetBlank: false, title: 'CSV link', url: 'https://chartwerk.io/', }, ], }, }, { name: 'Delete task', type: FieldType.string, values: _.map(configs, config => `data:image/png;base64,${CLOSE_ICON_BASE_64}`), config: { custom: { filterable: false, displayMode: 'image', }, links: [ { targetBlank: false, title: 'Delete', url: '#', onClick: (event: DataLinkClickEvent) => onDeleteClick(event, configs, setTasks) }, ], }, }, ], }); const dataFrames = applyFieldOverrides({ data: [dataFrame], fieldConfig: { overrides: [], defaults: {}, }, theme: createTheme(), replaceVariables: (value: string) => value, }); return dataFrames[0]; } function onDeleteClick(e: DataLinkClickEvent, tasks: TableRowConfig[], setTasks: any): void { const rowIndex = e.origin.rowIndex; const filteredTasks = _.filter(tasks, (task, idx) => idx !== rowIndex); setTasks(filteredTasks); } function createConfigItem(): TableRowConfig { return { timestamp: Date.now(), user: 'admin', datasource: 'Prometheus', rowsCount: 3214, progress: 100, status: 'finished', } } function convertTimestampToDate(timestamp: number): string { const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }; return new Date(timestamp).toLocaleString('en-GB', options); } const CLOSE_ICON_BASE_64 = 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACJSURBVHgB7ZPRCcAgDESv0lWc0zhC53OIjmAVUpCSamL76YEoyfFIiAGWfldK6SwnKHyhep9xJ3iPcqgH5RyxV1VlBWYJypXVHMEiCaqBbRhAy3W3B76j954wq6ZSVZsOY+WXt6i9l2ymGTlUq0VpOcIqaQC96Zth01DN1zBBefVI4SNp9Za+6wLcH6DKFrfpxgAAAABJRU5ErkJggg=='; const DOWNLOAD_ICON_BASE_64 = 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADlSURBVHgB3ZPNDYJAEIVnN96lBA7A2RIsATuQiiwBSrAD7MAjCZBACXqFwPomMRtEwMVwgZeQhfn5mNnMEG1CaZoeiqKwTWJ3JkFCiEtVVU+8+r9iJRlKSrk3iqOFtWJglmXHf3yDwCRJbBxxnudh34cRYluMMbKGcgWNCIlnjEuIJ1JK2WzDWeKb7YHjONEsYBf6kTABY+mWuYX+3Xiex9UFU7D3FllfwLqueQvi/h8ZCtBprDLY703T6A0yWj2ArmSoxedQV4jSSz5xj4pmCi0/NKfrwNz5bdtaNENciOu6N1qNXhzZXHMb9Q+nAAAAAElFTkSuQmCC';