diff --git a/web-console/src/components/table-cell-unparseable/__snapshots__/table-cell-unparseable.spec.tsx.snap b/web-console/src/components/table-cell-unparseable/__snapshots__/table-cell-unparseable.spec.tsx.snap new file mode 100644 index 00000000000..203a442e225 --- /dev/null +++ b/web-console/src/components/table-cell-unparseable/__snapshots__/table-cell-unparseable.spec.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`table cell unparseable matches snapshot not timestamp 1`] = ` +
+ unparseable +
+`; + +exports[`table cell unparseable matches snapshot timestamp 1`] = ` +
+ unparseable timestamp +
+`; diff --git a/web-console/src/components/table-cell-unparseable/table-cell-unparseable.scss b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.scss new file mode 100644 index 00000000000..43efe5085bf --- /dev/null +++ b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.scss @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.table-cell-unparseable { + color: #9e2b0e; +} diff --git a/web-console/src/components/table-cell-unparseable/table-cell-unparseable.spec.tsx b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.spec.tsx new file mode 100644 index 00000000000..0fdd45a23f8 --- /dev/null +++ b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.spec.tsx @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; + +import { TableCellUnparseable } from './table-cell-unparseable'; + +describe('table cell unparseable', () => { + it('matches snapshot not timestamp', () => { + const tableCellUnparseable = ; + + const { container } = render(tableCellUnparseable); + expect(container.firstChild).toMatchSnapshot(); + }); + + it('matches snapshot timestamp', () => { + const tableCellUnparseable = ; + + const { container } = render(tableCellUnparseable); + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/web-console/src/components/table-cell-unparseable/table-cell-unparseable.tsx b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.tsx new file mode 100644 index 00000000000..c6c067caf9d --- /dev/null +++ b/web-console/src/components/table-cell-unparseable/table-cell-unparseable.tsx @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; + +import './table-cell-unparseable.scss'; + +export interface TableCellUnparseableProps { + timestamp?: boolean; +} + +export const TableCellUnparseable = React.memo(function TableCellUnparseable( + props: TableCellUnparseableProps, +) { + const { timestamp } = props; + + return ( +
+ {timestamp ? 'unparseable timestamp' : 'unparseable'} +
+ ); +}); diff --git a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap index 7f1eebb4df2..435939ae3a4 100644 --- a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap +++ b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap @@ -49,11 +49,11 @@ exports[`table cell matches snapshot null 1`] = ` `; -exports[`table cell matches snapshot null timestamp 1`] = ` +exports[`table cell matches snapshot object 1`] = ` - unparseable timestamp + {"hello":"world"} `; @@ -69,13 +69,13 @@ exports[`table cell matches snapshot truncate 1`] = ` - testtesttesttesttesttes + test_test_test_test_tes - ...363 omitted... + ...462 omitted... - sttesttest + test_test_ `; + +exports[`table cell matches snapshot unlimited (absolute max) 1`] = ` + + test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_... + +`; + +exports[`table cell matches snapshot unlimited 1`] = ` + + test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_test_ + +`; diff --git a/web-console/src/components/table-cell/table-cell.scss b/web-console/src/components/table-cell/table-cell.scss index 3671b7d9afc..3b3ded93d4a 100644 --- a/web-console/src/components/table-cell/table-cell.scss +++ b/web-console/src/components/table-cell/table-cell.scss @@ -21,10 +21,6 @@ font-style: italic; } - &.unparseable { - color: #9e2b0e; - } - &.timestamp { font-weight: bold; } diff --git a/web-console/src/components/table-cell/table-cell.spec.tsx b/web-console/src/components/table-cell/table-cell.spec.tsx index 1c5f220bbac..08b9de10f30 100644 --- a/web-console/src/components/table-cell/table-cell.spec.tsx +++ b/web-console/src/components/table-cell/table-cell.spec.tsx @@ -23,49 +23,59 @@ import { TableCell } from './table-cell'; describe('table cell', () => { it('matches snapshot null', () => { - const tableCell = ; - - const { container } = render(tableCell); - expect(container.firstChild).toMatchSnapshot(); - }); - - it('matches snapshot null timestamp', () => { - const tableCell = ; + const tableCell = ; const { container } = render(tableCell); expect(container.firstChild).toMatchSnapshot(); }); it('matches snapshot simple', () => { - const tableCell = ; + const tableCell = ; const { container } = render(tableCell); expect(container.firstChild).toMatchSnapshot(); }); it('matches snapshot array short', () => { - const tableCell = ; + const tableCell = ; const { container } = render(tableCell); expect(container.firstChild).toMatchSnapshot(); }); it('matches snapshot array long', () => { - const tableCell = ( - i)} - unparseable={false} - timestamp={false} - /> - ); + const tableCell = i)} />; + + const { container } = render(tableCell); + expect(container.firstChild).toMatchSnapshot(); + }); + + it('matches snapshot object', () => { + const tableCell = ; const { container } = render(tableCell); expect(container.firstChild).toMatchSnapshot(); }); it('matches snapshot truncate', () => { - const longString = new Array(100).join('test'); - const tableCell = ; + const longString = new Array(100).join('test_'); + const tableCell = ; + + const { container } = render(tableCell); + expect(container.firstChild).toMatchSnapshot(); + }); + + it('matches snapshot unlimited', () => { + const longString = new Array(100).join('test_'); + const tableCell = ; + + const { container } = render(tableCell); + expect(container.firstChild).toMatchSnapshot(); + }); + + it('matches snapshot unlimited (absolute max)', () => { + const longString = new Array(5000).join('test_'); + const tableCell = ; const { container } = render(tableCell); expect(container.firstChild).toMatchSnapshot(); diff --git a/web-console/src/components/table-cell/table-cell.tsx b/web-console/src/components/table-cell/table-cell.tsx index e252cc9cc34..0ec500a7fb0 100644 --- a/web-console/src/components/table-cell/table-cell.tsx +++ b/web-console/src/components/table-cell/table-cell.tsx @@ -25,6 +25,7 @@ import { ActionIcon } from '../action-icon/action-icon'; import './table-cell.scss'; const MAX_CHARS_TO_SHOW = 50; +const ABSOLUTE_MAX_CHARS_TO_SHOW = 5000; interface ShortParts { prefix: string; @@ -46,13 +47,12 @@ function shortenString(str: string): ShortParts { } export interface TableCellProps { - value?: any; - timestamp?: boolean; - unparseable?: boolean; + value: any; + unlimited?: boolean; } export const TableCell = React.memo(function TableCell(props: TableCellProps) { - const { value, timestamp, unparseable } = props; + const { value, unlimited } = props; const [showValue, setShowValue] = useState(); function renderShowValueDialog(): JSX.Element | undefined { @@ -62,7 +62,19 @@ export const TableCell = React.memo(function TableCell(props: TableCellProps) { } function renderTruncated(str: string): JSX.Element { - if (str.length <= MAX_CHARS_TO_SHOW) return {str}; + if (str.length <= MAX_CHARS_TO_SHOW) { + return {str}; + } + + if (unlimited) { + return ( + + {str.length < ABSOLUTE_MAX_CHARS_TO_SHOW + ? str + : `${str.substr(0, ABSOLUTE_MAX_CHARS_TO_SHOW)}...`} + + ); + } const { prefix, omitted, suffix } = shortenString(str); return ( @@ -76,25 +88,21 @@ export const TableCell = React.memo(function TableCell(props: TableCellProps) { ); } - if (unparseable) { - return error; - } else if (value !== '' && value != null) { - if (timestamp) { + if (value !== '' && value != null) { + if (value instanceof Date) { return ( - - {new Date(value).toISOString()} + + {value.toISOString()} ); } else if (Array.isArray(value)) { return renderTruncated(`[${value.join(', ')}]`); + } else if (typeof value === 'object') { + return renderTruncated(JSON.stringify(value)); } else { return renderTruncated(String(value)); } } else { - if (timestamp) { - return unparseable timestamp; - } else { - return null; - } + return null; } }); diff --git a/web-console/src/views/load-data-view/filter-table/filter-table.tsx b/web-console/src/views/load-data-view/filter-table/filter-table.tsx index ef45fc9120e..89f380f44c7 100644 --- a/web-console/src/views/load-data-view/filter-table/filter-table.tsx +++ b/web-console/src/views/load-data-view/filter-table/filter-table.tsx @@ -92,7 +92,7 @@ export const FilterTable = React.memo(function FilterTable(props: FilterTablePro className: columnClassName, id: String(i), accessor: (row: SampleEntry) => (row.parsed ? row.parsed[columnName] : null), - Cell: row => , + Cell: row => , }; })} defaultPageSize={50} diff --git a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx index 053c7a1202e..f51503d1054 100644 --- a/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx +++ b/web-console/src/views/load-data-view/parse-data-table/parse-data-table.tsx @@ -21,6 +21,7 @@ import React from 'react'; import ReactTable from 'react-table'; import { TableCell } from '../../../components'; +import { TableCellUnparseable } from '../../../components/table-cell-unparseable/table-cell-unparseable'; import { caseInsensitiveContains, filterMap, parseJson } from '../../../utils'; import { FlattenField } from '../../../utils/ingestion-spec'; import { HeaderAndRows, SampleEntry } from '../../../utils/sampler'; @@ -74,7 +75,7 @@ export const ParseDataTable = React.memo(function ParseDataTable(props: ParseDat accessor: (row: SampleEntry) => (row.parsed ? row.parsed[columnName] : null), Cell: row => { if (row.original.unparseable) { - return ; + return ; } return ; }, diff --git a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx index 9fc6ba2c1eb..6a5e12f1b79 100644 --- a/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx +++ b/web-console/src/views/load-data-view/parse-time-table/parse-time-table.tsx @@ -21,6 +21,7 @@ import React from 'react'; import ReactTable from 'react-table'; import { TableCell } from '../../../components'; +import { TableCellUnparseable } from '../../../components/table-cell-unparseable/table-cell-unparseable'; import { caseInsensitiveContains, filterMap } from '../../../utils'; import { possibleDruidFormatForValues } from '../../../utils/druid-time'; import { @@ -122,9 +123,9 @@ export const ParseTimeTable = React.memo(function ParseTimeTable(props: ParseTim return ; } if (row.original.unparseable) { - return ; + return ; } - return ; + return ; }, minWidth: timestamp ? 200 : 100, resizable: !timestamp, diff --git a/web-console/src/views/load-data-view/schema-table/schema-table.tsx b/web-console/src/views/load-data-view/schema-table/schema-table.tsx index 0a782ca19d8..c334d8aaefe 100644 --- a/web-console/src/views/load-data-view/schema-table/schema-table.tsx +++ b/web-console/src/views/load-data-view/schema-table/schema-table.tsx @@ -147,7 +147,7 @@ export const SchemaTable = React.memo(function SchemaTable(props: SchemaTablePro className: columnClassName, id: String(i), accessor: (row: SampleEntry) => (row.parsed ? row.parsed[columnName] : null), - Cell: row => , + Cell: row => , }; } })} diff --git a/web-console/src/views/load-data-view/transform-table/transform-table.tsx b/web-console/src/views/load-data-view/transform-table/transform-table.tsx index 399f0cdb685..76dc1bf63ac 100644 --- a/web-console/src/views/load-data-view/transform-table/transform-table.tsx +++ b/web-console/src/views/load-data-view/transform-table/transform-table.tsx @@ -101,7 +101,7 @@ export const TransformTable = React.memo(function TransformTable(props: Transfor className: columnClassName, id: String(i), accessor: (row: SampleEntry) => (row.parsed ? row.parsed[columnName] : null), - Cell: row => , + Cell: row => , }; })} defaultPageSize={50} diff --git a/web-console/src/views/query-view/query-output/__snapshots__/query-output.spec.tsx.snap b/web-console/src/views/query-view/query-output/__snapshots__/query-output.spec.tsx.snap index e5a679fa368..f2696f9180a 100644 --- a/web-console/src/views/query-view/query-output/__snapshots__/query-output.spec.tsx.snap +++ b/web-console/src/views/query-view/query-output/__snapshots__/query-output.spec.tsx.snap @@ -146,7 +146,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - +
+ + + + null + + + +
-
6881 -
+
@@ -181,11 +195,11 @@ exports[`query output matches snapshot 1`] = ` -
1 -
+
@@ -195,7 +209,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - 0 +
+ + + + 0 + + + +
@@ -219,11 +247,11 @@ exports[`query output matches snapshot 1`] = ` -
JavaScript -
+
@@ -240,11 +268,11 @@ exports[`query output matches snapshot 1`] = ` -
166 -
+
@@ -261,11 +289,11 @@ exports[`query output matches snapshot 1`] = ` -
1 -
+
@@ -275,7 +303,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - 0 +
+ + + + 0 + + + +
@@ -299,11 +341,11 @@ exports[`query output matches snapshot 1`] = ` -
Python -
+
@@ -320,11 +362,11 @@ exports[`query output matches snapshot 1`] = ` -
62 -
+
@@ -341,11 +383,11 @@ exports[`query output matches snapshot 1`] = ` -
1 -
+
@@ -355,7 +397,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - 0 +
+ + + + 0 + + + +
@@ -379,11 +435,11 @@ exports[`query output matches snapshot 1`] = ` -
HTML -
+
@@ -400,11 +456,11 @@ exports[`query output matches snapshot 1`] = ` -
46 -
+
@@ -421,11 +477,11 @@ exports[`query output matches snapshot 1`] = ` -
1 -
+
@@ -435,7 +491,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - 0 +
+ + + + 0 + + + +
@@ -459,11 +529,11 @@ exports[`query output matches snapshot 1`] = ` -
- Java -
+ null +
@@ -480,11 +550,11 @@ exports[`query output matches snapshot 1`] = ` -
- 42 -
+ null +
@@ -501,11 +571,11 @@ exports[`query output matches snapshot 1`] = ` -
- 1 -
+ null +
@@ -515,7 +585,21 @@ exports[`query output matches snapshot 1`] = ` role="gridcell" style="flex: 100 0 auto; width: 100px;" > - 0 +
+ + + + null + + + +
@@ -524,7 +608,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- C++ -
-
-
-
+ +   +
-
- - -
- 28 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -604,7 +654,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Go -
-
-
-
+ +   +
-
- - -
- 24 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -684,7 +700,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Ruby -
-
-
-
+ +   +
-
- - -
- 20 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -764,7 +746,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- C# -
-
-
-
+ +   +
-
- - -
- 14 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -844,7 +792,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- C -
-
-
-
+ +   +
-
- - -
- 13 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -924,7 +838,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- CSS -
-
-
-
+ +   +
-
- - -
- 13 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1004,7 +884,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Shell -
-
-
-
+ +   +
-
- - -
- 12 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1084,7 +930,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Makefile -
-
-
-
+ +   +
-
- - -
- 10 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1164,7 +976,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- PHP -
-
-
-
+ +   +
-
- - -
- 9 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1244,7 +1022,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Scala -
-
-
-
+ +   +
-
- - -
- 8 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1324,7 +1068,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- HCL -
-
-
-
+ +   +
-
- - -
- 6 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1404,7 +1114,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Jupyter Notebook -
-
-
-
+ +   +
-
- - -
- 6 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1484,7 +1160,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Smarty -
-
-
-
+ +   +
-
- - -
- 4 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1564,7 +1206,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Elm -
-
-
-
+ +   +
-
- - -
- 4 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1644,7 +1252,7 @@ exports[`query output matches snapshot 1`] = ` role="rowgroup" >
-
- - -
- Roff -
-
-
-
+ +   +
-
- - -
- 3 -
-
-
-
+ +   +
-
- - -
- 1 -
-
-
-
+ +   +
- 0 + +   +
@@ -1761,7 +1335,7 @@ exports[`query output matches snapshot 1`] = ` - 2 + 1