adding loading spinner for index management table (#27204)

* adding loading spinner for index management table

* removing search bar and system indices switch on first load

* removing console.log
This commit is contained in:
Bill McConaghy 2018-12-15 14:31:30 -05:00 committed by GitHub
parent 2d6789d53d
commit 19b9da5dca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 100 additions and 85 deletions

View file

@ -15,6 +15,7 @@ import {
getSortField,
isSortAscending,
getIndicesAsArray,
indicesLoading,
} from '../../../../store/selectors';
import {
filterChanged,
@ -40,7 +41,8 @@ const mapStateToProps = (state) => {
filter: getFilter(state),
showSystemIndices: showSystemIndices(state),
sortField: getSortField(state),
isSortAscending: isSortAscending(state)
isSortAscending: isSortAscending(state),
indicesLoading: indicesLoading(state),
};
};

View file

@ -10,12 +10,8 @@ import { FormattedMessage, injectI18n } from '@kbn/i18n/react';
import { Route } from 'react-router-dom';
import { NoMatch } from '../../../no_match';
import { healthToColor } from '../../../../services';
import { toastNotifications } from 'ui/notify';
import '../../../../styles/table.less';
import {
REFRESH_RATE_INDEX_LIST
} from '../../../../constants';
import { REFRESH_RATE_INDEX_LIST } from '../../../../constants';
import {
EuiButton,
EuiCallOut,
@ -24,6 +20,7 @@ import {
EuiCheckbox,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingSpinner,
EuiPage,
EuiSpacer,
EuiSearchBar,
@ -99,10 +96,7 @@ export class IndexTableUi extends Component {
componentDidMount() {
this.props.loadIndices();
this.interval = setInterval(this.props.reloadIndices, REFRESH_RATE_INDEX_LIST);
const {
filterChanged,
filterFromURI
} = this.props;
const { filterChanged, filterFromURI } = this.props;
if (filterFromURI) {
const decodedFilter = decodeURIComponent(filterFromURI);
filterChanged(EuiSearchBar.Query.parse(decodedFilter));
@ -128,14 +122,17 @@ export class IndexTableUi extends Component {
<EuiCallOut
iconType="faceSad"
color="danger"
title={intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.invalidSearchErrorMessage',
defaultMessage: 'Invalid search: {errorMessage}',
}, {
errorMessage: filterError.message
})}
title={intl.formatMessage(
{
id: 'xpack.idxMgmt.indexTable.invalidSearchErrorMessage',
defaultMessage: 'Invalid search: {errorMessage}',
},
{
errorMessage: filterError.message,
}
)}
/>
<EuiSpacer size="l"/>
<EuiSpacer size="l" />
</Fragment>
);
}
@ -146,14 +143,14 @@ export class IndexTableUi extends Component {
this.props.filterChanged(query);
this.setState({ filterError: null });
}
}
};
getFilters = () => {
const { allIndices } = this.props;
return getFilterExtensions().reduce((accum, filterExtension) => {
const filtersToAdd = filterExtension(allIndices);
return [...accum, ...filtersToAdd];
}, []);
}
};
toggleAll = () => {
const allSelected = this.areAllItemsSelected();
if (allSelected) {
@ -255,27 +252,15 @@ export class IndexTableUi extends Component {
return null;
}
const {
type,
title,
message,
filter,
filterLabel,
} = bannerData;
const { type, title, message, filter, filterLabel } = bannerData;
return (
<Fragment key={`bannerExtension${i}`}>
<EuiCallOut
color={type}
size="m"
title={title}
>
<EuiCallOut color={type} size="m" title={title}>
<EuiText>
{message}
{filter ? (
<EuiLink onClick={() => filterChanged(filter)}>
{filterLabel}
</EuiLink>
<EuiLink onClick={() => filterChanged(filter)}>{filterLabel}</EuiLink>
) : null}
</EuiText>
</EuiCallOut>
@ -336,7 +321,18 @@ export class IndexTableUi extends Component {
indices,
intl,
loadIndices,
indicesLoading,
allIndices
} = this.props;
const emptyState = indicesLoading ? (
<EuiFlexGroup justifyContent="spaceAround">
<EuiFlexItem grow={false}>
<EuiLoadingSpinner size="xl" />
</EuiFlexItem>
</EuiFlexGroup>
) : (
<NoMatch />
);
const { selectedIndicesMap } = this.state;
const atLeastOneItemSelected = Object.keys(selectedIndicesMap).length > 0;
return (
@ -364,17 +360,21 @@ export class IndexTableUi extends Component {
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSwitch
id="checkboxShowSystemIndices"
checked={showSystemIndices}
onChange={event => showSystemIndicesChanged(event.target.checked)}
label={
<FormattedMessage
id="xpack.idxMgmt.indexTable.systemIndicesSwitchLabel"
defaultMessage="Include system indices"
{indicesLoading && allIndices.length === 0 ? null :
(
<EuiSwitch
id="checkboxShowSystemIndices"
checked={showSystemIndices}
onChange={event => showSystemIndicesChanged(event.target.checked)}
label={
<FormattedMessage
id="xpack.idxMgmt.indexTable.systemIndicesSwitchLabel"
defaultMessage="Include system indices"
/>
}
/>
}
/>
)
}
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
@ -395,45 +395,45 @@ export class IndexTableUi extends Component {
/>
</EuiFlexItem>
) : null}
<EuiFlexItem>
<EuiSearchBar
filters={this.getFilters()}
defaultQuery={filter}
query={filter}
box={{
incremental: true,
placeholder: intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder',
defaultMessage: 'Search',
}) }
}
aria-label={intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel',
defaultMessage: 'Search indices',
})}
data-test-subj="indexTableFilterInput"
onChange={this.onFilterChanged}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
color="secondary"
onClick={() => {
loadIndices();
toastNotifications.addSuccess(intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.reloadingIndicesMessage',
defaultMessage: 'Reloading indices'
}));
}}
iconType="refresh"
>
<FormattedMessage
id="xpack.idxMgmt.indexTable.reloadIndicesButton"
defaultMessage="Reload indices"
/>
</EuiButton>
</EuiFlexItem>
{indicesLoading && allIndices.length === 0 ? null : (
<Fragment>
<EuiFlexItem>
<EuiSearchBar
filters={this.getFilters()}
defaultQuery={filter}
query={filter}
box={{
incremental: true,
placeholder: intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder',
defaultMessage: 'Search',
}),
}}
aria-label={intl.formatMessage({
id: 'xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel',
defaultMessage: 'Search indices',
})}
data-test-subj="indexTableFilterInput"
onChange={this.onFilterChanged}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
isLoading={indicesLoading}
color="secondary"
onClick={() => {
loadIndices();
}}
iconType="refresh"
>
<FormattedMessage
id="xpack.idxMgmt.indexTable.reloadIndicesButton"
defaultMessage="Reload indices"
/>
</EuiButton>
</EuiFlexItem>
</Fragment>
)}
</EuiFlexGroup>
{this.renderFilterError()}
<EuiSpacer size="m" />
@ -454,7 +454,7 @@ export class IndexTableUi extends Component {
<EuiTableBody>{this.buildRows()}</EuiTableBody>
</EuiTable>
) : (
<NoMatch />
emptyState
)}
<EuiSpacer size="m" />
{indices.length > 0 ? this.renderPager() : null}

View file

@ -8,12 +8,15 @@ import { createAction } from 'redux-actions';
import { loadIndices as request } from '../../services';
import { toastNotifications } from 'ui/notify';
export const loadIndicesStart = createAction('INDEX_MANAGEMENT_LOAD_INDICES_START');
export const loadIndicesSuccess = createAction('INDEX_MANAGEMENT_LOAD_INDICES_SUCCESS');
export const loadIndices = () => async (dispatch) => {
dispatch(loadIndicesStart());
let indices;
try {
indices = await request();
} catch (error) {
dispatch(loadIndicesSuccess({ indices: [] }));
return toastNotifications.addDanger(error.data.message);
}
dispatch(loadIndicesSuccess({ indices }));

View file

@ -10,6 +10,7 @@ import {
deleteIndicesSuccess,
loadIndicesSuccess,
reloadIndicesSuccess,
loadIndicesStart
} from '../actions';
const byId = handleActions({
@ -69,8 +70,16 @@ const allIds = handleActions({
return state;
}
}, []);
const loading = handleActions({
[loadIndicesStart]() {
return true;
},
[loadIndicesSuccess]() {
return false;
}
}, true);
export const indices = combineReducers({
loading,
byId,
allIds
});

View file

@ -15,6 +15,7 @@ export const getDetailPanelType = (state) => state.detailPanel.panelType;
export const isDetailPanelOpen = (state) => !!getDetailPanelType(state);
export const getDetailPanelIndexName = (state) => state.detailPanel.indexName;
export const getIndices = (state) => state.indices.byId;
export const indicesLoading = (state) => state.indices.loading;
export const getIndicesAsArray = (state) => Object.values(state.indices.byId);
export const getIndicesByName = (state, indexNames) => {
const indices = getIndices(state);