Pasting table from Kibana into GitLab doesn't format as a table
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
We have this neat copy from spreadsheet and paste in Markdown feature: https://docs.gitlab.com/ee/user/markdown.html#copy-from-spreadsheet-and-paste-in-markdown
This works great from spreadsheets (as documented) but not so well from Kibana. For instance, this table: https://log.gprd.gitlab.net/goto/91e630283d5b4b7da3e1bdfd67967b88
In Firefox, pastes like:
Time
json.tag
Jun 15, 2020 @ 08:42:13.210rails.application
Jun 15, 2020 @ 08:42:12.931rails.application
Jun 15, 2020 @ 08:42:12.681rails.production
Jun 15, 2020 @ 08:42:12.498rails.graphql
And in Chrome, pastes like:
Time json.tag
Jun 15, 2020 @ 08:53:44.994 rails.application
Jun 15, 2020 @ 08:53:44.686 rails.production
Jun 15, 2020 @ 08:53:44.667 rails.api
Jun 15, 2020 @ 08:53:44.638 rails.production
Jun 15, 2020 @ 08:53:44.630 rails.api
Using https://evercoder.github.io/clipboard-inspector/, it looks like the HTML data looks like:
<table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><thead kbn-table-header="" columns="columns" index-pattern="indexPattern" sort-order="sorting" on-change-sort-order="onChangeSortOrder" on-move-column="onMoveColumn" on-remove-column="onRemoveColumn"><tr data-test-subj="docTableHeader" class="kbnDocTableHeader"><th style="width: 24px;"></th><th data-test-subj="docTableHeaderField"><span data-test-subj="docTableHeader-json.time">Time<span class="euiToolTipAnchor"></span></span></th></tr></thead></table><span data-test-subj="docTableHeader-json.tag">json.tag<span class="euiToolTipAnchor"></span></span><table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><tbody>
<tr ng-repeat="row in hits|limitTo:limit track by row._index+row._type+row._id+row._score+row._version+row._routing" kbn-table-row="row" columns="columns" sorting="sorting" index-pattern="indexPattern" filter="filter" filters="filters" class="kbnDocTable__row" ng-class="{'kbnDocTable__row--highlight': row['$$_isAnchor']}" data-test-subj="docTableRow" on-add-column="onAddColumn" on-remove-column="onRemoveColumn"><td ng-click="toggleRow()" data-test-subj="docTableExpandToggleColumn" class="kbnDocTableCell__toggleDetails">
</td></tr></tbody></table><table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><tbody><tr ng-repeat="row in hits|limitTo:limit track by row._index+row._type+row._id+row._score+row._version+row._routing" kbn-table-row="row" columns="columns" sorting="sorting" index-pattern="indexPattern" filter="filter" filters="filters" class="kbnDocTable__row" ng-class="{'kbnDocTable__row--highlight': row['$$_isAnchor']}" data-test-subj="docTableRow" on-add-column="onAddColumn" on-remove-column="onRemoveColumn"><td ng-click="toggleRow()" data-test-subj="docTableExpandToggleColumn" class="kbnDocTableCell__toggleDetails">
</td><td class="eui-textNoWrap" data-test-subj="docTableField" width="1%"><span ng-non-bindable="">Jun 15, 2020 @ 08:42:13.210</span><span class="kbnDocTableCell__filter"></span></td></tr></tbody></table><div class="truncate-by-height"><span ng-non-bindable="">rails.application</span></div><span class="kbnDocTableCell__filter"></span><table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><tbody><tr ng-repeat="row in hits|limitTo:limit track by row._index+row._type+row._id+row._score+row._version+row._routing" kbn-table-row="row" columns="columns" sorting="sorting" index-pattern="indexPattern" filter="filter" filters="filters" class="kbnDocTable__row" ng-class="{'kbnDocTable__row--highlight': row['$$_isAnchor']}" data-test-subj="docTableRow" on-add-column="onAddColumn" on-remove-column="onRemoveColumn"><td ng-click="toggleRow()" data-test-subj="docTableExpandToggleColumn" class="kbnDocTableCell__toggleDetails">
</td></tr></tbody></table><span ng-non-bindable="">Jun 15, 2020 @ 08:42:12.931</span><span class="kbnDocTableCell__filter"></span><div class="truncate-by-height"><span ng-non-bindable="">rails.application</span></div><span class="kbnDocTableCell__filter"></span><table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><tbody><tr data-test-subj="docTableDetailsRow" class="kbnDocTableDetails__row"></tr><tr ng-repeat="row in hits|limitTo:limit track by row._index+row._type+row._id+row._score+row._version+row._routing" kbn-table-row="row" columns="columns" sorting="sorting" index-pattern="indexPattern" filter="filter" filters="filters" class="kbnDocTable__row" ng-class="{'kbnDocTable__row--highlight': row['$$_isAnchor']}" data-test-subj="docTableRow" on-add-column="onAddColumn" on-remove-column="onRemoveColumn"><td ng-click="toggleRow()" data-test-subj="docTableExpandToggleColumn" class="kbnDocTableCell__toggleDetails">
</td></tr></tbody></table><span ng-non-bindable="">Jun 15, 2020 @ 08:42:12.681</span><span class="kbnDocTableCell__filter"></span><div class="truncate-by-height"><span ng-non-bindable="">rails.production</span></div><span class="kbnDocTableCell__filter"></span><table ng-if="infiniteScroll" class="kbn-table table" data-test-subj="docTable"><tbody><tr data-test-subj="docTableDetailsRow" class="kbnDocTableDetails__row"></tr><tr ng-repeat="row in hits|limitTo:limit track by row._index+row._type+row._id+row._score+row._version+row._routing" kbn-table-row="row" columns="columns" sorting="sorting" index-pattern="indexPattern" filter="filter" filters="filters" class="kbnDocTable__row" ng-class="{'kbnDocTable__row--highlight': row['$$_isAnchor']}" data-test-subj="docTableRow" on-add-column="onAddColumn" on-remove-column="onRemoveColumn"><td ng-click="toggleRow()" data-test-subj="docTableExpandToggleColumn" class="kbnDocTableCell__toggleDetails">
</td></tr></tbody></table><span ng-non-bindable="">Jun 15, 2020 @ 08:42:12.498</span><span class="kbnDocTableCell__filter"></span><div class="truncate-by-height"><span ng-non-bindable="">rails.graphql</span></div>
Which has more than one table. https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/behaviors/markdown/paste_markdown_table.js specifically says:
// We're only looking for exactly one table. If there happens to be
// multiple tables, it's possible an application copied data into
// the clipboard that is not related to a simple table. It may also be
// complicated converting multiple tables into Markdown.
Which is fair enough.
