Skip to content

Commit

Permalink
Initial migration of kbnTableHeader to react
Browse files Browse the repository at this point in the history
  • Loading branch information
kertal committed Jul 16, 2019
1 parent 4b803f7 commit a7d7aaa
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,24 @@

import _ from 'lodash';
import { i18n } from '@kbn/i18n';
import { wrapInI18nContext } from 'ui/i18n';
import { shortenDottedString } from '../../../../common/utils/shorten_dotted_string';
import headerHtml from './table_header.html';
import { uiModules } from 'ui/modules';
import { TableHeader } from './table_header/table_header';
const module = uiModules.get('app/discover');

module.directive('kbnTableHeader', function (reactDirective, config) {
return reactDirective(
wrapInI18nContext(TableHeader),
undefined,
{ restrict: 'A' },
{
hideTimeColumn: config.get('doc_table:hideTimeColumn'),
isShortDots: config.get('shortDots:enable'),
}
);

module.directive('kbnTableHeader', function () {
return {
restrict: 'A',
scope: {
Expand All @@ -47,9 +58,9 @@ module.directive('kbnTableHeader', function () {

$scope.isSortableColumn = function isSortableColumn(columnName) {
return (
!!$scope.indexPattern
&& _.isFunction($scope.onChangeSortOrder)
&& _.get($scope, ['indexPattern', 'fields', 'byName', columnName, 'sortable'], false)
!!$scope.indexPattern &&
_.isFunction($scope.onChangeSortOrder) &&
_.get($scope, ['indexPattern', 'fields', 'byName', columnName, 'sortable'], false)
);
};

Expand All @@ -63,23 +74,20 @@ module.directive('kbnTableHeader', function () {
};

$scope.canMoveColumnLeft = function canMoveColumn(columnName) {
return (
_.isFunction($scope.onMoveColumn)
&& $scope.columns.indexOf(columnName) > 0
);
return _.isFunction($scope.onMoveColumn) && $scope.columns.indexOf(columnName) > 0;
};

$scope.canMoveColumnRight = function canMoveColumn(columnName) {
return (
_.isFunction($scope.onMoveColumn)
&& $scope.columns.indexOf(columnName) < $scope.columns.length - 1
_.isFunction($scope.onMoveColumn) &&
$scope.columns.indexOf(columnName) < $scope.columns.length - 1
);
};

$scope.canRemoveColumn = function canRemoveColumn(columnName) {
return (
_.isFunction($scope.onRemoveColumn)
&& (columnName !== '_source' || $scope.columns.length > 1)
_.isFunction($scope.onRemoveColumn) &&
(columnName !== '_source' || $scope.columns.length > 1)
);
};

Expand Down Expand Up @@ -119,11 +127,8 @@ module.directive('kbnTableHeader', function () {
}

const [currentColumnName, currentDirection = 'asc'] = $scope.sortOrder;
const newDirection = (
(columnName === currentColumnName && currentDirection === 'asc')
? 'desc'
: 'asc'
);
const newDirection =
columnName === currentColumnName && currentDirection === 'asc' ? 'desc' : 'asc';

$scope.onChangeSortOrder(columnName, newDirection);
};
Expand All @@ -132,7 +137,7 @@ module.directive('kbnTableHeader', function () {
if (!$scope.isSortableColumn(name)) return null;

const [currentColumnName, currentDirection = 'asc'] = $scope.sortOrder;
if(name === currentColumnName && currentDirection === 'asc') {
if (name === currentColumnName && currentDirection === 'asc') {
return i18n.translate('kbn.docTable.tableHeader.sortByColumnDescendingAriaLabel', {
defaultMessage: 'Sort {columnName} descending',
values: { columnName: name },
Expand All @@ -143,6 +148,6 @@ module.directive('kbnTableHeader', function () {
values: { columnName: name },
});
};
}
},
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. 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 { i18n } from '@kbn/i18n';

export type SortOrder = [string, string];

export function getAriaSortLabel(columnName: string, sortOrder: SortOrder) {
const [currentColumnName, currentDirection = 'asc'] = sortOrder;
if (name === currentColumnName && currentDirection === 'asc') {
return i18n.translate('kbn.docTable.tableHeader.sortByColumnDescendingAriaLabel', {
defaultMessage: 'Sort {columnName} descending',
values: { columnName },
});
}
return i18n.translate('kbn.docTable.tableHeader.sortByColumnAscendingAriaLabel', {
defaultMessage: 'Sort {columnName} ascending',
values: { columnName },
});
}

export function getSortHeaderClass(columnName: string, sortOrder: SortOrder) {
const defaultClass = ['fa', 'fa-sort-up', 'kbnDocTableHeader__sortChange'];

if (!sortOrder || columnName !== sortOrder[0]) return defaultClass.join(' ');
return ['fa', sortOrder[1] === 'asc' ? 'fa-sort-up' : 'fa-sort-down'].join(' ');
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,127 +17,79 @@
* under the License.
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import _ from 'lodash';
import { isFunction, get } from 'lodash';
// @ts-ignore
import { IndexPattern } from 'src/legacy/core_plugins/data/public';
import { shortenDottedString } from '../../../../../common/utils/shorten_dotted_string';

import { TableHeaderColumn } from './table_header_column';
import { TableHeaderTimeColumn } from './table_header_time_column';
import { SortOrder } from './helpers';

interface Props {
indexPattern: any;
indexPattern: IndexPattern;
hideTimeColumn: number;
totalItems: number;
columns: string[];
headerClass: (name: string) => string;
cycleSortOrder: (name: string) => string;
getShortDotsName: (name: string) => string;
isSortableColumn: (name: string) => boolean;
getAriaLabelForColumn: (name: string) => string;
tooltip: (name: string) => string;
moveColumnLeft: (name: string) => boolean;
sortOrder: SortOrder;
isShortDots: boolean;
onRemoveColumn: (name: string) => void;
canMoveColumnRight: (name: string) => boolean;
canRemoveColumn: (name: string) => boolean;
canMoveColumnLeft: (name: string) => boolean;
moveColumnRight: (name: string) => void;
onChangeSortOrder: () => void;
onChangeSortOrder: (name: string, direction: 'asc' | 'desc') => void;
onMoveColumn: (name: string, index: number) => void;
}

export function TableHeader({
indexPattern,
hideTimeColumn,
columns,
headerClass,
cycleSortOrder,
getShortDotsName,
getAriaLabelForColumn,
tooltip,
moveColumnLeft,
onRemoveColumn,
canRemoveColumn,
canMoveColumnLeft,
canMoveColumnRight,
moveColumnRight,
onChangeSortOrder,
sortOrder,
isShortDots,
onMoveColumn,
}: Props) {
function isSortableColumn(columnName: string) {
return (
!!indexPattern &&
typeof onChangeSortOrder === 'function' &&
_.get(indexPattern, ['fields', 'byName', columnName, 'sortable'], false)
);
const { timeFieldName } = indexPattern;

function cycleSortOrder(colName: string) {
const [currColumnName, currDirection = 'asc'] = sortOrder;
const newDirection = colName === currColumnName && currDirection === 'asc' ? 'desc' : 'asc';

onChangeSortOrder(colName, newDirection);
}

return (
<tr>
<td></td>
{indexPattern.timeFieldName && !hideTimeColumn && (
<th data-test-subj="docTableHeaderField" scope="col">
<span>
<FormattedMessage
id="kbn.docTable.tableHeader.timeHeaderCellTitle"
defaultMessage="Time"
/>
<button
id="docTableHeaderFieldSort{{indexPattern.timeFieldName}}"
label="{{ getAriaLabelForColumn(indexPattern.timeFieldName) }}"
className={headerClass(indexPattern.timeFieldName)}
onClick={() => cycleSortOrder(indexPattern.timeFieldName)}
tooltip="{{ ::'kbn.docTable.tableHeader.sortByTimeTooltip' | i18n: {defaultMessage: 'Sort by time'} }}"
></button>
</span>
</th>
<td style={{ width: '1%' }}></td>
{timeFieldName && !hideTimeColumn && (
<TableHeaderTimeColumn
sortOrder={sortOrder}
onCycleSortOrder={cycleSortOrder}
timeFieldName={timeFieldName}
/>
)}
{columns.map((name: string) => (
<th data-test-subj="docTableHeaderField">
<span data-test-subj="docTableHeader-{{name}}">
{getShortDotsName(name)}
{isSortableColumn(name) && (
<button
data-test-subj="docTableHeaderFieldSort_{{name}}"
id={`docTableHeaderFieldSort${name}`}
aria-label={getAriaLabelForColumn(name)}
className={headerClass(name)}
onClick={() => cycleSortOrder(name)}
tooltip={tooltip(name)}
tooltip-append-to-body="1"
></button>
)}
</span>
{canRemoveColumn(name) && (
<button
className="fa fa-remove kbnDocTableHeader__move"
onClick={() => onRemoveColumn(name)}
tooltip-append-to-body="1"
tooltip="{{ ::'kbn.docTable.tableHeader.removeColumnButtonTooltip' | i18n: {defaultMessage: 'Remove column'} }}"
aria-label="{{ 'kbn.docTable.tableHeader.removeColumnButtonAriaLabel' | i18n: {
defaultMessage: 'Remove {columnName} column',
values: {columnName: name}
}}}"
data-test-subj="docTableRemoveHeader-{{name}}"
></button>
)}
{canMoveColumnLeft(name) && (
<button
className="fa fa-angle-double-left kbnDocTableHeader__move"
oncClick={() => moveColumnLeft(name)}
tooltip="{{ ::'kbn.docTable.tableHeader.moveColumnLeftButtonTooltip' | i18n: {defaultMessage: 'Move column to the left'} }}"
aria-label="{{ 'kbn.docTable.tableHeader.moveColumnLeftButtonAriaLabel' | i18n: {
defaultMessage: 'Move {columnName} column to the left',
values: {columnName: name}
} }}"
></button>
)}
{canMoveColumnRight(name) && (
<button
className="fa fa-angle-double-right kbnDocTableHeader__move"
onClick={() => moveColumnRight(name)}
tooltip="{{ ::'kbn.docTable.tableHeader.moveColumnRightButtonTooltip' | i18n: {defaultMessage: 'Move column to the right'} }}"
aria-label="{{ 'kbn.docTable.tableHeader.moveColumnRightButtonAriaLabel' | i18n: {
defaultMessage: 'Move {columnName} column to the right',
values: {columnName: name}
} }}"
></button>
)}
</th>
))}
{columns.map((name: string, idx: number) => {
const canRemoveColumn =
isFunction(onRemoveColumn) && (name !== '_source' || columns.length > 1);
const isSortable =
isFunction(onChangeSortOrder) &&
get(indexPattern, ['fields', 'byName', name, 'sortable'], false);

const colLeftIdx = idx - 1 < 0 ? -1 : idx - 1;
const colRightIdx = idx + 1 >= columns.length ? -1 : idx + 1;
const displayName = isShortDots ? shortenDottedString(name) : name;

return (
<TableHeaderColumn
key={name}
name={name}
displayName={displayName}
sortOrder={sortOrder}
onCycleSortOrder={isSortable ? () => cycleSortOrder(name) : undefined}
onMoveColumnLeft={colLeftIdx >= 0 ? () => onMoveColumn(name, colLeftIdx) : undefined}
onMoveColumnRight={colRightIdx >= 0 ? () => onMoveColumn(name, colRightIdx) : undefined}
onRemoveColumn={canRemoveColumn ? () => onRemoveColumn(name) : undefined}
/>
);
})}
</tr>
);
}
Loading

0 comments on commit a7d7aaa

Please sign in to comment.