|
1 | 1 | import _ from 'lodash';
|
2 | 2 | import html from 'ui/doc_table/doc_table.html';
|
3 | 3 | import { getSort } from 'ui/doc_table/lib/get_sort';
|
| 4 | +import { saveAs } from '@elastic/filesaver'; |
4 | 5 | import 'ui/doc_table/doc_table.less';
|
5 | 6 | import 'ui/directives/truncated';
|
6 | 7 | import 'ui/directives/infinite_scroll';
|
7 | 8 | import 'ui/doc_table/components/table_header';
|
8 | 9 | import 'ui/doc_table/components/table_row';
|
9 | 10 | import { uiModules } from 'ui/modules';
|
| 11 | +import { RegistryFieldFormatsProvider } from 'ui/registry/field_formats'; |
| 12 | + |
10 | 13 |
|
11 | 14 | import { getLimitedSearchResultsMessage } from './doc_table_strings';
|
12 | 15 |
|
13 | 16 | uiModules.get('kibana')
|
14 |
| -.directive('docTable', function (config, Notifier, getAppState, pagerFactory, $filter) { |
| 17 | +.directive('docTable', function (config, Notifier, getAppState, pagerFactory, $filter, Private) { |
| 18 | + const fieldFormats = Private(RegistryFieldFormatsProvider); |
15 | 19 | return {
|
16 | 20 | restrict: 'E',
|
17 | 21 | template: html,
|
@@ -140,6 +144,77 @@ uiModules.get('kibana')
|
140 | 144 | $scope.shouldShowLimitedResultsWarning = () => (
|
141 | 145 | !$scope.pager.hasNextPage && $scope.pager.totalItems < $scope.totalHitCount
|
142 | 146 | );
|
| 147 | + |
| 148 | + $scope.exportAsCsv = function (formatted) { |
| 149 | + var csv = { |
| 150 | + separator: config.get('csv:separator'), |
| 151 | + quoteValues: config.get('csv:quoteValues') |
| 152 | + }; |
| 153 | + |
| 154 | + var rows = $scope.hits; |
| 155 | + var columns = $scope.columns; |
| 156 | + if ($scope.indexPattern.timeFieldName) { |
| 157 | + columns = [$scope.indexPattern.timeFieldName].concat(columns); |
| 158 | + } |
| 159 | + var nonAlphaNumRE = /[^a-zA-Z0-9]/; |
| 160 | + var allDoubleQuoteRE = /"/g; |
| 161 | + |
| 162 | + function escape(val) { |
| 163 | + if (_.isObject(val)) val = val.valueOf(); |
| 164 | + val = String(val); |
| 165 | + if (csv.quoteValues && nonAlphaNumRE.test(val)) { |
| 166 | + val = '"' + val.replace(allDoubleQuoteRE, '""') + '"'; |
| 167 | + } |
| 168 | + return val; |
| 169 | + } |
| 170 | + |
| 171 | + function formatField(value, name) { |
| 172 | + var field = $scope.indexPattern.fields.byName[name]; |
| 173 | + if (!field) return value; |
| 174 | + var defaultFormat = fieldFormats.getDefaultType(field.type); |
| 175 | + var formatter = (field && field.format) ? field.format : defaultFormat; |
| 176 | + |
| 177 | + return formatter.convert(value); |
| 178 | + } |
| 179 | + |
| 180 | + function formatRow(row) { |
| 181 | + $scope.indexPattern.flattenHit(row); |
| 182 | + row.$$_formatted = row.$$_formatted || _.mapValues(row.$$_flattened, formatField); |
| 183 | + return row.$$_formatted; |
| 184 | + } |
| 185 | + |
| 186 | + // get column values for each row |
| 187 | + var csvRows = rows.map(function (row, i) { |
| 188 | + return columns.map(function (column, j) { |
| 189 | + var val; |
| 190 | + |
| 191 | + if (formatted) { |
| 192 | + val = (row.$$_formatted || formatRow(row))[column]; |
| 193 | + } else { |
| 194 | + val = (row.$$_flattened || formatRow(row))[column]; |
| 195 | + } |
| 196 | + |
| 197 | + val = (val == null) ? '' : val; |
| 198 | + |
| 199 | + return val; |
| 200 | + }); |
| 201 | + }); |
| 202 | + |
| 203 | + // escape each cell in each row |
| 204 | + csvRows = csvRows.map(function (row, i) { |
| 205 | + return row.map(escape); |
| 206 | + }); |
| 207 | + |
| 208 | + // add the columns to the rows |
| 209 | + csvRows.unshift(columns.map(escape)); |
| 210 | + |
| 211 | + var data = csvRows.map(function (row) { |
| 212 | + return row.join(csv.separator) + '\r\n'; |
| 213 | + }).join(''); |
| 214 | + |
| 215 | + saveAs(new Blob([data], { type: 'text/plain' }), 'export.csv'); |
| 216 | + }; |
| 217 | + |
143 | 218 | }
|
144 | 219 | };
|
145 | 220 | });
|
0 commit comments