diff --git a/CHANGES.md b/CHANGES.md index 0d6457c..d4dacd0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ ### Changes 2.2.1 (in dev) +* The DATA SOURCES panel now indicates by a progress spinner that data sources are being fetched. (#126) +* Fixed bug, where no data sources were shown right after start (#56) + ### Changes 2.2.0 * Using Keycloak authentication and user management service diff --git a/src/renderer/containers/DataSourcesPanel.tsx b/src/renderer/containers/DataSourcesPanel.tsx index 1907143..d16a78e 100644 --- a/src/renderer/containers/DataSourcesPanel.tsx +++ b/src/renderer/containers/DataSourcesPanel.tsx @@ -1,14 +1,8 @@ -import * as React from 'react'; -import {CSSProperties} from 'react'; -import {connect} from 'react-redux'; -import {Cell, Column, Table, TruncatedFormat} from '@blueprintjs/table'; -import ReactMarkdown from 'react-markdown'; -import {EcvMeta} from '../ecv-meta'; -import {DataSourceState, DataStoreNotice, DataStoreState, State} from '../state'; import { AnchorButton, ButtonGroup, Callout, + Card, Checkbox, Classes, Collapse, @@ -22,21 +16,27 @@ import { Tabs, Tag } from '@blueprintjs/core'; -import {ListBox, ListBoxSelectionMode} from '../components/ListBox'; -import {Card} from '@blueprintjs/core'; -import {ScrollablePanelContent} from '../components/ScrollableContent'; -import {ContentWithDetailsPanel} from '../components/ContentWithDetailsPanel'; -import {ToolButton} from '../components/ToolButton'; -import {TextWithLinks} from '../components/TextWithLinks'; -import DownloadDatasetDialog from './DownloadDataSourceDialog'; -import OpenDatasetDialog from './OpenDatasetDialog'; -import AddDatasetDialog from './AddDatasetDialog'; -import RemoveDatasetDialog from './RemoveDatasetDialog'; +import { Cell, Column, Table, TruncatedFormat } from '@blueprintjs/table'; +import * as React from 'react'; +import { CSSProperties } from 'react'; +import ReactMarkdown from 'react-markdown'; +import { connect } from 'react-redux'; import * as actions from '../actions'; -import * as selectors from '../selectors'; -import {NO_DATA_SOURCES_FOUND, NO_DATA_STORES_FOUND, NO_LOCAL_DATA_SOURCES} from '../messages'; +import { ContentWithDetailsPanel } from '../components/ContentWithDetailsPanel'; +import { ListBox, ListBoxSelectionMode } from '../components/ListBox'; +import { ScrollablePanelContent } from '../components/ScrollableContent'; +import { TextWithLinks } from '../components/TextWithLinks'; +import { ToolButton } from '../components/ToolButton'; +import { EcvMeta } from '../ecv-meta'; +import { DATA_SOURCES_LOADING, NO_DATA_SOURCES_FOUND, NO_DATA_STORES_FOUND, NO_LOCAL_DATA_SOURCES } from '../messages'; import _ecvMeta from '../resources/ecv-meta.json'; +import * as selectors from '../selectors'; +import { DataSourceState, DataStoreNotice, DataStoreState, State } from '../state'; +import AddDatasetDialog from './AddDatasetDialog'; +import DownloadDatasetDialog from './DownloadDataSourceDialog'; +import OpenDatasetDialog from './OpenDatasetDialog'; +import RemoveDatasetDialog from './RemoveDatasetDialog'; const ECV_META: EcvMeta = _ecvMeta; @@ -128,7 +128,7 @@ class DataSourcesPanel extends React.Component {this.renderDataStoreSelector()} +
+ + +
{this.renderDataSourceFilterExprInput()} this.props.setDataSourceFilterExpr('')}> @@ -326,7 +334,7 @@ class DataSourcesPanel extends React.Component - - - - ); } @@ -426,7 +425,12 @@ class DataSourcesPanel extends React.Component { this.handleIconLoadError = this.handleIconLoadError.bind(this); } + private static getItemKey(dataSource: DataSourceState) { + return dataSource.id; + } + + render() { + return ( + + + + ); + } + private handleDataSourceSelected(newSelection: Array) { if (newSelection.length > 0) { this.props.setSelectedDataSourceId(newSelection[0] as string); @@ -520,10 +542,6 @@ class DataSourcesList extends React.PureComponent { img.src = `resources/images/data-sources/esacci/${this.defaultIconName}.png`; } - private static getItemKey(dataSource: DataSourceState) { - return dataSource.id; - } - private renderIcon(dataSource: DataSourceState) { const icon = ((dataSource.meta_info && dataSource.meta_info.cci_project) || 'cci').toLowerCase(); return {
{dataSource.id}
) : ( - {title} - )} + {title} + )} ); } - - render() { - return ( - - - - ); - } } interface DetailPart { @@ -600,99 +604,6 @@ class DataSourceDetails extends React.PureComponentCatalogue - } - let spatialCoverage; - if (metaInfo.bbox_miny && metaInfo.bbox_maxy && metaInfo.bbox_minx && metaInfo.bbox_maxx) { - spatialCoverage = ( -
-
Spatial coverage
- - - - - - - - - - - - - -
- {metaInfo.bbox_maxy}° -
{metaInfo.bbox_minx}° - {metaInfo.bbox_maxx}°
- {metaInfo.bbox_miny}° -
-
-
- ); - } - let temporalCoverage; - if (dataSource.temporalCoverage) { - temporalCoverage = ( -
Temporal coverage
- - - - - - - - - - - -
Start{dataSource.temporalCoverage[0]}
End{dataSource.temporalCoverage[1]}
-
-
- ); - } - let summary; - if (metaInfo.abstract) { - summary = ( -
Summary
-

{metaInfo.abstract}

-
- ); - } - if (openOdpPage || spatialCoverage || temporalCoverage || summary) { - element = ( - - - {openOdpPage} - {spatialCoverage} - {temporalCoverage} - {summary} - - - ); - } - } - - if (!element) { - element = No abstract available.; - } - - return {title: 'Abstract', id: 'abstract', element}; - } - private static renderVariablesTable(variables?: any[]): DetailPart { let element; if (variables && variables.length > 0) { @@ -805,6 +716,99 @@ class DataSourceDetails extends React.PureComponent ); } + + private openOdpLink() { + const uuid = this.props.dataSource.meta_info.uuid; + const url = 'http://catalogue.ceda.ac.uk/uuid/' + uuid; + actions.openExternal(url); + } + + private renderAbstract(dataSource: DataSourceState): DetailPart { + const metaInfo = dataSource.meta_info; + let element; + if (metaInfo) { + let openOdpPage; + if (metaInfo.uuid) { + openOdpPage = + Catalogue + } + let spatialCoverage; + if (metaInfo.bbox_miny && metaInfo.bbox_maxy && metaInfo.bbox_minx && metaInfo.bbox_maxx) { + spatialCoverage = ( +
+
Spatial coverage
+ + + + + + + + + + + + + +
+ {metaInfo.bbox_maxy}° +
{metaInfo.bbox_minx}° + {metaInfo.bbox_maxx}°
+ {metaInfo.bbox_miny}° +
+
+
+ ); + } + let temporalCoverage; + if (dataSource.temporalCoverage) { + temporalCoverage = ( +
Temporal coverage
+ + + + + + + + + + + +
Start{dataSource.temporalCoverage[0]}
End{dataSource.temporalCoverage[1]}
+
+
+ ); + } + let summary; + if (metaInfo.abstract) { + summary = ( +
Summary
+

{metaInfo.abstract}

+
+ ); + } + if (openOdpPage || spatialCoverage || temporalCoverage || summary) { + element = ( + + + {openOdpPage} + {spatialCoverage} + {temporalCoverage} + {summary} + + + ); + } + } + + if (!element) { + element = No abstract available.; + } + + return {title: 'Abstract', id: 'abstract', element}; + } } export default connect(mapStateToProps, mapDispatchToProps)(DataSourcesPanel as any); diff --git a/src/renderer/messages.tsx b/src/renderer/messages.tsx index 877007c..1f5122c 100644 --- a/src/renderer/messages.tsx +++ b/src/renderer/messages.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Icon, NonIdealState } from '@blueprintjs/core'; +import { Icon, Intent, NonIdealState, Spinner } from '@blueprintjs/core'; import { IconName } from '@blueprintjs/icons'; export const ICON_CIRCLE: IconName = 'circle'; @@ -43,7 +43,14 @@ export const NO_LOCAL_DATA_SOURCES = ( Add new file data sources using the cate ds add name files... command-line
}/> + description={Add new file data sources using the button below.}/> +); + +export const DATA_SOURCES_LOADING = ( + } + description={Please wait until the list of data sources is being loaded from the server.}/> ); export const NO_DATA_SOURCES_FOUND = (