mirror of
https://github.com/apache/superset.git
synced 2026-04-17 15:15:20 +00:00
js translation -- performance improvment (#3390)
* Chinese page * Using react-intl-universal to improve multi language in react page * Using react-intl-universal to improve multi language in react page * react_intl_universal * change * change * change * change * change * change * change * merge * multiple page in js * merge * merge * merge * merge * Js Translations * JS Translation * JS Translations * Js translation * JS translations * JS translations * Js translaion * JS en Translation * JS Translation * upgrade document Fixing the damn build (#3179) * Fixing the build * Going deeper [bugfix] only filterable columns should show up in FilterBox list (#3105) * [bugfix] only filterable columns should show up in FilterBox list * Touchups Datasource cannot be empty (#3035) add title description to model view (#3045) * add title description to model view * add missing import Add 'show/hide totals' option to pivot table vis (#3101) [bugfix] numeric value for date fields in table viz (#3036) Bug was present only when using the NOT GROUPED BY option fixes https://github.com/ApacheInfra/superset/issues/3027 fix hive.fetch_logs (#2968) add Zalando to the list of organizations (#3171) docs: fixup installation examples code indentation (#3169) [bugfix] fix bar order (#3180) [bugfix] visualize flow error: 'Metric x is not valid' (#3181) The metric name in the frontend doesn't match the one generated on the backend. It turns out the explore view will default to the first metric so specifying one isn't needed. Fix the segment interval for pulling metadata (#3174) The end of the interval would be on the truncated today date, which means that you will exclude today. If your realtime ingestion job runs shorter than a day, the metadata cannot be pulled from the druid cluster. Bump cryptography to 1.9 (#3065) As 1.7.2 doesn't compile here with openssl 1.1.0f Escaping the user's SQL in the explore view (#3186) * Escaping the user's SQL in the explore view When executing SQL from SQL Lab, we use a lower level API to the database which doesn't require escaping the SQL. When going through the explore view, the stack chain leading to the same method may need escaping depending on how the DBAPI driver is written, and that is the case for Presto (and perhaps other drivers). * Using regex to avoid doubling doubles [sqllab] improve Hive support (#3187) * [sqllab] improve Hive support * Fix "Transport not open" bug * Getting progress bar to show * Bump pyhive to 0.4.0 * Getting [Track Job] button to show * Fix testzz Add BigQuery engine specifications (#3193) As contributed by @mxmzdlv on issue #945 [bugfix] fix merge conflict that broke Hive support (#3196) Adding 'apache' to docs (#3194) [druid] Allow custom druid postaggregators (#3146) * [druid] Allow custom druid postaggregators Also, fix the postaggregation for approxHistogram quantiles so it adds the dependent field and that can show up in the graphs/tables. In general, postAggregators add significant power, we should probably support including custom postAggregators. Plywood has standard postAggregators here, and a customAggregator escape hatch that allows you to define custom postAggregators. This commit adds a similar capability for Superset and a additional field/fields/fieldName breakdown of the typical naming for dependent aggregations, which should make it significantly easier to develop approxHistogram and custom postAggregation-required dashboards. * [druid] Minor style cleanup in tests file. * [druid] Apply code review suggestions * break out CustomPostAggregator into separate class. This just cleans up the creation of the postaggregator a little bit. * minor style issues. * move the function around so the git diff is more readable add combine config for metrics in pivot table (#3086) * add combine config for metrics in pivot table * change method to stack/unstack * update backendSync Autofocus search input in VizTypeControl modal onEnter (#2929) Speed up JS build time (#3203) Also bumping a few related libs JS Translation JS translations js translation fix issue 3204 (#3205) [bugfix] capture Hive job_id pre-url transformation (#3213) js translation fix issue 3204 (#3205) [bugfix] capture Hive job_id pre-url transformation (#3213) [docs] update url in CONTRIBUTING.md (#3212) [sqllab/cosmetics] add margin-top for labels in query history (#3222) [explore] nvd3 sort values in rich tooltip (#3197) [sqllab] fix UI shows 'The query returned no results' momentarily (#3214) this is visible when running async queries between the fetching and success state as the rows are getting cached in the component [explore] DatasourceControl to pick datasource in modal (#3210) * [explore] DatasourceControl to pick datasource in modal Makes it easier to change datasource, also makes it such that the list of all datasources doesn't need to be loaded upfront. * Adding more metadata * Js translation * js tran * js trans * js trans * js tran * js trans * js trans * js tran * js translation * js trans * js translation * try load language pack async * Backend translations things * create language pack inside common data * performance improvement for js i18n. - js bundle should not contain localized content - we populate translation content from server-side, in boostrap.common.language_pack - in client-side, use promise to wrap around translation content. text will be translated after translation content arrived/parsed. - fix linting * fix Timer unit test * 1. add global hook for all tests, to make translation pack avaialble before each test starts. 2. fix unit test for Timer component 3. remove noused method get_locale, and modules 4. fix page reload after user change page language * parse and build i18n dictionary as a module * fix sync-backend task, which should run without DOM
This commit is contained in:
committed by
Maxime Beauchemin
parent
1cf634afa2
commit
9af34ba51c
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import CopyToClipboard from '../../components/CopyToClipboard';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
queryEditor: PropTypes.object.isRequired,
|
||||
@@ -26,10 +27,10 @@ export default class CopyQueryTabUrl extends React.PureComponent {
|
||||
inMenu
|
||||
copyNode={(
|
||||
<div>
|
||||
<i className="fa fa-clipboard" /> <span>share query</span>
|
||||
<i className="fa fa-clipboard" /> <span>{t('share query')}</span>
|
||||
</div>
|
||||
)}
|
||||
tooltipText="copy URL to clipboard"
|
||||
tooltipText={t('copy URL to clipboard')}
|
||||
shouldShowText={false}
|
||||
getText={this.getUrl.bind(this)}
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import sql from 'react-syntax-highlighter/dist/languages/sql';
|
||||
import github from 'react-syntax-highlighter/dist/styles/github';
|
||||
|
||||
import ModalTrigger from '../../components/ModalTrigger';
|
||||
import { t } from '../../locales';
|
||||
|
||||
registerLanguage('sql', sql);
|
||||
|
||||
@@ -57,7 +58,7 @@ class HighlightedSql extends React.Component {
|
||||
if (this.props.rawSql && this.props.rawSql !== this.props.sql) {
|
||||
rawSql = (
|
||||
<div>
|
||||
<h4>Raw SQL</h4>
|
||||
<h4>{t('Raw SQL')}</h4>
|
||||
<SyntaxHighlighter language="sql" style={github}>
|
||||
{this.props.rawSql}
|
||||
</SyntaxHighlighter>
|
||||
@@ -67,7 +68,7 @@ class HighlightedSql extends React.Component {
|
||||
this.setState({
|
||||
modalBody: (
|
||||
<div>
|
||||
<h4>Source SQL</h4>
|
||||
<h4>{t('Source SQL')}</h4>
|
||||
<SyntaxHighlighter language="sql" style={github}>
|
||||
{this.props.sql}
|
||||
</SyntaxHighlighter>
|
||||
@@ -79,7 +80,7 @@ class HighlightedSql extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ModalTrigger
|
||||
modalTitle="SQL"
|
||||
modalTitle={t('SQL')}
|
||||
triggerNode={this.triggerNode()}
|
||||
modalBody={this.state.modalBody}
|
||||
beforeOpen={this.generateModal.bind(this)}
|
||||
|
||||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { Alert } from 'react-bootstrap';
|
||||
|
||||
import QueryTable from './QueryTable';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
queries: PropTypes.array.isRequired,
|
||||
@@ -24,7 +25,7 @@ const QueryHistory = (props) => {
|
||||
}
|
||||
return (
|
||||
<Alert bsStyle="info">
|
||||
No query history yet...
|
||||
{t('No query history yet...')}
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { now, epochTimeXHoursAgo,
|
||||
epochTimeXDaysAgo, epochTimeXYearsAgo } from '../../modules/dates';
|
||||
import { STATUS_OPTIONS, TIME_OPTIONS } from '../constants';
|
||||
import AsyncSelect from '../../components/AsyncSelect';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const $ = window.$ = require('jquery');
|
||||
|
||||
@@ -102,7 +103,7 @@ class QuerySearch extends React.PureComponent {
|
||||
if (data.result.length === 0) {
|
||||
this.props.actions.addAlert({
|
||||
bsStyle: 'danger',
|
||||
msg: "It seems you don't have access to any database",
|
||||
msg: t('It seems you don\'t have access to any database'),
|
||||
});
|
||||
}
|
||||
return options;
|
||||
@@ -150,15 +151,15 @@ class QuerySearch extends React.PureComponent {
|
||||
type="text"
|
||||
onChange={this.changeSearch.bind(this)}
|
||||
className="form-control input-sm"
|
||||
placeholder="Search Results"
|
||||
placeholder={t('Search Results')}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-sm-4 search-date-filter-container">
|
||||
<Select
|
||||
name="select-from"
|
||||
placeholder="[From]-"
|
||||
placeholder={t('[From]-')}
|
||||
options={TIME_OPTIONS
|
||||
.slice(1, TIME_OPTIONS.length).map(t => ({ value: t, label: t }))}
|
||||
.slice(1, TIME_OPTIONS.length).map(xt => ({ value: xt, label: xt }))}
|
||||
value={this.state.from}
|
||||
autosize={false}
|
||||
onChange={this.changeFrom.bind(this)}
|
||||
@@ -166,8 +167,8 @@ class QuerySearch extends React.PureComponent {
|
||||
|
||||
<Select
|
||||
name="select-to"
|
||||
placeholder="[To]-"
|
||||
options={TIME_OPTIONS.map(t => ({ value: t, label: t }))}
|
||||
placeholder={t('[To]-')}
|
||||
options={TIME_OPTIONS.map(xt => ({ value: xt, label: xt }))}
|
||||
value={this.state.to}
|
||||
autosize={false}
|
||||
onChange={this.changeTo.bind(this)}
|
||||
@@ -175,7 +176,7 @@ class QuerySearch extends React.PureComponent {
|
||||
|
||||
<Select
|
||||
name="select-status"
|
||||
placeholder="[Query Status]"
|
||||
placeholder={t('[Query Status]')}
|
||||
options={STATUS_OPTIONS.map(s => ({ value: s, label: s }))}
|
||||
value={this.state.status}
|
||||
isLoading={false}
|
||||
@@ -184,7 +185,7 @@ class QuerySearch extends React.PureComponent {
|
||||
/>
|
||||
|
||||
<Button bsSize="small" bsStyle="success" onClick={this.refreshQueries.bind(this)}>
|
||||
Search
|
||||
{t('Search')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import HighlightedSql from './HighlightedSql';
|
||||
import { fDuration } from '../../modules/dates';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
import QueryStateLabel from './QueryStateLabel';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
columns: PropTypes.array,
|
||||
@@ -45,7 +46,7 @@ class QueryTable extends React.PureComponent {
|
||||
openQuery(dbId, schema, sql) {
|
||||
const newQuery = {
|
||||
dbId,
|
||||
title: 'Untitled Query',
|
||||
title: t('Untitled Query'),
|
||||
schema,
|
||||
sql,
|
||||
};
|
||||
@@ -110,7 +111,7 @@ class QueryTable extends React.PureComponent {
|
||||
className="btn btn-link btn-xs"
|
||||
onClick={this.openQuery.bind(this, q.dbId, q.schema, q.sql)}
|
||||
>
|
||||
<i className="fa fa-external-link" />Open in SQL Editor
|
||||
<i className="fa fa-external-link" />{t('Open in SQL Editor')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
@@ -129,10 +130,10 @@ class QueryTable extends React.PureComponent {
|
||||
bsStyle="info"
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
view results
|
||||
{t('view results')}
|
||||
</Label>
|
||||
)}
|
||||
modalTitle={'Data preview'}
|
||||
modalTitle={t('Data preview')}
|
||||
beforeOpen={this.openAsyncResults.bind(this, query)}
|
||||
onExit={this.clearQueryResults.bind(this, query)}
|
||||
modalBody={
|
||||
@@ -172,24 +173,24 @@ class QueryTable extends React.PureComponent {
|
||||
<div style={{ width: '75px' }}>
|
||||
<Link
|
||||
className="fa fa-line-chart m-r-3"
|
||||
tooltip="Visualize the data out of this query"
|
||||
tooltip={t('Visualize the data out of this query')}
|
||||
onClick={this.showVisualizeModal.bind(this, query)}
|
||||
/>
|
||||
<Link
|
||||
className="fa fa-pencil m-r-3"
|
||||
onClick={this.restoreSql.bind(this, query)}
|
||||
tooltip="Overwrite text in editor with a query on this table"
|
||||
tooltip={t('Overwrite text in editor with a query on this table')}
|
||||
placement="top"
|
||||
/>
|
||||
<Link
|
||||
className="fa fa-plus-circle m-r-3"
|
||||
onClick={this.openQueryInNewTab.bind(this, query)}
|
||||
tooltip="Run query in a new tab"
|
||||
tooltip={t('Run query in a new tab')}
|
||||
placement="top"
|
||||
/>
|
||||
<Link
|
||||
className="fa fa-trash m-r-3"
|
||||
tooltip="Remove query from log"
|
||||
tooltip={t('Remove query from log')}
|
||||
onClick={this.removeQuery.bind(this, query)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import VisualizeModal from './VisualizeModal';
|
||||
import HighlightedSql from './HighlightedSql';
|
||||
import FilterableTable from '../../components/FilterableTable/FilterableTable';
|
||||
import QueryStateLabel from './QueryStateLabel';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
actions: PropTypes.object,
|
||||
@@ -63,7 +64,7 @@ export default class ResultSet extends React.PureComponent {
|
||||
if (this.props.csv) {
|
||||
csvButton = (
|
||||
<Button bsSize="small" href={'/superset/csv/' + this.props.query.id}>
|
||||
<i className="fa fa-file-text-o" /> .CSV
|
||||
<i className="fa fa-file-text-o" /> {t('.CSV')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -74,7 +75,7 @@ export default class ResultSet extends React.PureComponent {
|
||||
bsSize="small"
|
||||
onClick={this.showModal.bind(this)}
|
||||
>
|
||||
<i className="fa fa-line-chart m-l-1" /> Visualize
|
||||
<i className="fa fa-line-chart m-l-1" /> {t('Visualize')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -85,7 +86,7 @@ export default class ResultSet extends React.PureComponent {
|
||||
type="text"
|
||||
onChange={this.changeSearch.bind(this)}
|
||||
className="form-control input-sm"
|
||||
placeholder="Search Results"
|
||||
placeholder={t('Search Results')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -158,14 +159,14 @@ export default class ResultSet extends React.PureComponent {
|
||||
return (
|
||||
<div>
|
||||
<Alert bsStyle="info">
|
||||
Table [<strong>{query.tempTable}</strong>] was
|
||||
created
|
||||
{t('Table')} [<strong>{query.tempTable}</strong>] {t('was ' +
|
||||
'created')}
|
||||
<Button
|
||||
bsSize="small"
|
||||
className="m-r-5"
|
||||
onClick={this.popSelectStar.bind(this)}
|
||||
>
|
||||
Query in a new tab
|
||||
{t('Query in a new tab')}
|
||||
</Button>
|
||||
</Alert>
|
||||
</div>);
|
||||
@@ -206,7 +207,7 @@ export default class ResultSet extends React.PureComponent {
|
||||
bsStyle="primary"
|
||||
onClick={this.reFetchQueryResults.bind(this, query)}
|
||||
>
|
||||
Fetch data preview
|
||||
{t('Fetch data preview')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -226,13 +227,13 @@ export default class ResultSet extends React.PureComponent {
|
||||
bsSize="small"
|
||||
onClick={() => { window.open(query.trackingUrl); }}
|
||||
>
|
||||
Track Job
|
||||
{t('Track Job')}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<img className="loading" alt="Loading..." src="/static/assets/images/loading.gif" />
|
||||
<img className="loading" alt={t('Loading...')} src="/static/assets/images/loading.gif" />
|
||||
<QueryStateLabel query={query} />
|
||||
{progressBar}
|
||||
<div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Button from '../../components/Button';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
allowAsync: PropTypes.bool.isRequired,
|
||||
@@ -15,10 +16,10 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
export default function RunQueryActionButton(props) {
|
||||
const runBtnText = props.selectedText ? 'Run Selected Query' : 'Run Query';
|
||||
const runBtnText = props.selectedText ? t('Run Selected Query') : t('Run Query');
|
||||
const btnStyle = props.selectedText ? 'warning' : 'primary';
|
||||
const shouldShowStopBtn = ['running', 'pending'].indexOf(props.queryState) > -1;
|
||||
const tooltip = 'shortcut: [alt+enter]';
|
||||
const asyncToolTip = t('Run query asynchronously');
|
||||
|
||||
const commonBtnProps = {
|
||||
bsSize: 'small',
|
||||
@@ -31,7 +32,7 @@ export default function RunQueryActionButton(props) {
|
||||
{...commonBtnProps}
|
||||
onClick={() => props.runQuery(false)}
|
||||
key="run-btn"
|
||||
tooltip={tooltip}
|
||||
tooltip={asyncToolTip}
|
||||
>
|
||||
<i className="fa fa-refresh" /> {runBtnText}
|
||||
</Button>
|
||||
@@ -42,7 +43,7 @@ export default function RunQueryActionButton(props) {
|
||||
{...commonBtnProps}
|
||||
onClick={() => props.runQuery(true)}
|
||||
key="run-async-btn"
|
||||
tooltip={tooltip}
|
||||
tooltip={asyncToolTip}
|
||||
>
|
||||
<i className="fa fa-table" /> {runBtnText}
|
||||
</Button>
|
||||
@@ -53,7 +54,7 @@ export default function RunQueryActionButton(props) {
|
||||
{...commonBtnProps}
|
||||
onClick={props.stopQuery}
|
||||
>
|
||||
<i className="fa fa-stop" /> Stop
|
||||
<i className="fa fa-stop" /> {t('Stop')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormControl, FormGroup, Overlay, Popover, Row, Col } from 'react-bootstrap';
|
||||
import Button from '../../components/Button';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
defaultLabel: PropTypes.string,
|
||||
@@ -12,7 +13,7 @@ const propTypes = {
|
||||
onSave: PropTypes.func,
|
||||
};
|
||||
const defaultProps = {
|
||||
defaultLabel: 'Undefined',
|
||||
defaultLabel: t('Undefined'),
|
||||
animation: true,
|
||||
onSave: () => {},
|
||||
};
|
||||
@@ -62,12 +63,12 @@ class SaveQuery extends React.PureComponent {
|
||||
<Col md={12}>
|
||||
<small>
|
||||
<label className="control-label" htmlFor="embed-height">
|
||||
Label
|
||||
{t('Label')}
|
||||
</label>
|
||||
</small>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Label for your query"
|
||||
placeholder={t('Label for your query')}
|
||||
value={this.state.label}
|
||||
onChange={this.onLabelChange}
|
||||
/>
|
||||
@@ -77,11 +78,11 @@ class SaveQuery extends React.PureComponent {
|
||||
<Row>
|
||||
<Col md={12}>
|
||||
<small>
|
||||
<label className="control-label" htmlFor="embed-height">Description</label>
|
||||
<label className="control-label" htmlFor="embed-height">{t('Description')}</label>
|
||||
</small>
|
||||
<FormControl
|
||||
componentClass="textarea"
|
||||
placeholder="Write a description for your query"
|
||||
placeholder={t('Write a description for your query')}
|
||||
value={this.state.description}
|
||||
onChange={this.onDescriptionChange}
|
||||
/>
|
||||
@@ -95,10 +96,10 @@ class SaveQuery extends React.PureComponent {
|
||||
onClick={this.onSave}
|
||||
className="m-r-3"
|
||||
>
|
||||
Save
|
||||
{t('Save')}
|
||||
</Button>
|
||||
<Button onClick={this.onCancel} className="cancelQuery">
|
||||
Cancel
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -119,7 +120,7 @@ class SaveQuery extends React.PureComponent {
|
||||
{this.renderPopover()}
|
||||
</Overlay>
|
||||
<Button bsSize="small" className="toggleSave" onClick={this.toggleSave}>
|
||||
<i className="fa fa-save" /> Save Query
|
||||
<i className="fa fa-save" /> {t('Save Query')}
|
||||
</Button>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { bindActionCreators } from 'redux';
|
||||
import * as Actions from '../actions';
|
||||
import QueryHistory from './QueryHistory';
|
||||
import ResultSet from './ResultSet';
|
||||
import { t } from '../../locales';
|
||||
|
||||
/*
|
||||
editorQueries are queries executed by users passed from SqlEditor component
|
||||
@@ -48,12 +49,12 @@ class SouthPane extends React.PureComponent {
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
results = <Alert bsStyle="info">Run a query to display results here</Alert>;
|
||||
results = <Alert bsStyle="info">{t('Run a query to display results here')}</Alert>;
|
||||
}
|
||||
|
||||
const dataPreviewTabs = props.dataPreviewQueries.map(query => (
|
||||
<Tab
|
||||
title={`Preview for ${query.tableName}`}
|
||||
title={t('Preview for %s', query.tableName)}
|
||||
eventKey={query.id}
|
||||
key={query.id}
|
||||
>
|
||||
@@ -77,13 +78,13 @@ class SouthPane extends React.PureComponent {
|
||||
onSelect={this.switchTab.bind(this)}
|
||||
>
|
||||
<Tab
|
||||
title="Results"
|
||||
title={t('Results')}
|
||||
eventKey="Results"
|
||||
>
|
||||
{results}
|
||||
</Tab>
|
||||
<Tab
|
||||
title="Query History"
|
||||
title={t('Query History')}
|
||||
eventKey="History"
|
||||
>
|
||||
<div style={{ height: `${innerTabHeight}px`, overflow: 'scroll' }}>
|
||||
|
||||
@@ -22,6 +22,7 @@ import SqlEditorLeftBar from './SqlEditorLeftBar';
|
||||
import AceEditorWrapper from './AceEditorWrapper';
|
||||
import { STATE_BSSTYLE_MAP } from '../constants';
|
||||
import RunQueryActionButton from './RunQueryActionButton';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
actions: PropTypes.object.isRequired,
|
||||
@@ -119,7 +120,7 @@ class SqlEditor extends React.PureComponent {
|
||||
renderEditorBottomBar() {
|
||||
let ctasControls;
|
||||
if (this.props.database && this.props.database.allow_ctas) {
|
||||
const ctasToolTip = 'Create table as with query results';
|
||||
const ctasToolTip = t('Create table as with query results');
|
||||
ctasControls = (
|
||||
<FormGroup>
|
||||
<InputGroup>
|
||||
@@ -127,7 +128,7 @@ class SqlEditor extends React.PureComponent {
|
||||
type="text"
|
||||
bsSize="small"
|
||||
className="input-sm"
|
||||
placeholder="new table name"
|
||||
placeholder={t('new table name')}
|
||||
onChange={this.ctasChanged.bind(this)}
|
||||
/>
|
||||
<InputGroup.Button>
|
||||
|
||||
@@ -7,6 +7,7 @@ import createFilterOptions from 'react-select-fast-filter-options';
|
||||
|
||||
import TableElement from './TableElement';
|
||||
import AsyncSelect from '../../components/AsyncSelect';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const $ = window.$ = require('jquery');
|
||||
|
||||
@@ -62,7 +63,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
if (data.result.length === 0) {
|
||||
this.props.actions.addAlert({
|
||||
bsStyle: 'danger',
|
||||
msg: "It seems you don't have access to any database",
|
||||
msg: t('It seems you don\'t have access to any database'),
|
||||
});
|
||||
}
|
||||
return options;
|
||||
@@ -86,7 +87,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
})
|
||||
.fail(() => {
|
||||
this.setState({ tableLoading: false, tableOptions: [], tableLength: 0 });
|
||||
notify.error('Error while fetching table list');
|
||||
notify.error(t('Error while fetching table list'));
|
||||
});
|
||||
} else {
|
||||
this.setState({ tableLoading: false, tableOptions: [], filterOptions: null });
|
||||
@@ -127,7 +128,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
})
|
||||
.fail(() => {
|
||||
this.setState({ schemaLoading: false, schemaOptions: [] });
|
||||
notify.error('Error while fetching schema list');
|
||||
notify.error(t('Error while fetching schema list'));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -149,29 +150,29 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
'_od_DatabaseAsync=asc'
|
||||
}
|
||||
onChange={this.onDatabaseChange.bind(this)}
|
||||
onAsyncError={() => notify.error('Error while fetching database list')}
|
||||
onAsyncError={() => notify.error(t('Error while fetching database list'))}
|
||||
value={this.props.queryEditor.dbId}
|
||||
databaseId={this.props.queryEditor.dbId}
|
||||
actions={this.props.actions}
|
||||
valueRenderer={o => (
|
||||
<div>
|
||||
<span className="text-muted">Database:</span> {o.label}
|
||||
<span className="text-muted">{t('Database:')}</span> {o.label}
|
||||
</div>
|
||||
)}
|
||||
mutator={this.dbMutator.bind(this)}
|
||||
placeholder="Select a database"
|
||||
placeholder={t('Select a database')}
|
||||
autoSelect
|
||||
/>
|
||||
</div>
|
||||
<div className="m-t-5">
|
||||
<Select
|
||||
name="select-schema"
|
||||
placeholder={`Select a schema (${this.state.schemaOptions.length})`}
|
||||
placeholder={t('Select a schema (%s)', this.state.schemaOptions.length)}
|
||||
options={this.state.schemaOptions}
|
||||
value={this.props.queryEditor.schema}
|
||||
valueRenderer={o => (
|
||||
<div>
|
||||
<span className="text-muted">Schema:</span> {o.label}
|
||||
<span className="text-muted">{t('Schema:')}</span> {o.label}
|
||||
</div>
|
||||
)}
|
||||
isLoading={this.state.schemaLoading}
|
||||
@@ -186,7 +187,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
ref="selectTable"
|
||||
isLoading={this.state.tableLoading}
|
||||
value={this.state.tableName}
|
||||
placeholder={`Add a table (${this.state.tableOptions.length})`}
|
||||
placeholder={t('Add a table (%s)', this.state.tableOptions.length)}
|
||||
autosize={false}
|
||||
onChange={this.changeTable.bind(this)}
|
||||
filterOptions={this.state.filterOptions}
|
||||
@@ -199,7 +200,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
name="async-select-table"
|
||||
ref="selectTable"
|
||||
value={this.state.tableName}
|
||||
placeholder={'Type to search ...'}
|
||||
placeholder={t('Type to search ...')}
|
||||
autosize={false}
|
||||
onChange={this.changeTable.bind(this)}
|
||||
loadOptions={this.getTableNamesBySubStr.bind(this)}
|
||||
@@ -222,7 +223,7 @@ class SqlEditorLeftBar extends React.PureComponent {
|
||||
</div>
|
||||
{shouldShowReset &&
|
||||
<Button bsSize="small" bsStyle="danger" onClick={this.resetState.bind(this)}>
|
||||
<i className="fa fa-bomb" /> Reset State
|
||||
<i className="fa fa-bomb" /> {t('Reset State')}
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import * as Actions from '../actions';
|
||||
import SqlEditor from './SqlEditor';
|
||||
import CopyQueryTabUrl from './CopyQueryTabUrl';
|
||||
import { areArraysShallowEqual } from '../../reduxUtils';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
actions: PropTypes.object.isRequired,
|
||||
@@ -101,7 +102,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
}
|
||||
renameTab(qe) {
|
||||
/* eslint no-alert: 0 */
|
||||
const newTitle = prompt('Enter a new title for the tab');
|
||||
const newTitle = prompt(t('Enter a new title for the tab'));
|
||||
if (newTitle) {
|
||||
this.props.actions.queryEditorSetTitle(qe, newTitle);
|
||||
}
|
||||
@@ -120,7 +121,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
queryCount++;
|
||||
const activeQueryEditor = this.activeQueryEditor();
|
||||
const qe = {
|
||||
title: `Untitled Query ${queryCount}`,
|
||||
title: t('Untitled Query %s', queryCount),
|
||||
dbId: (activeQueryEditor && activeQueryEditor.dbId) ?
|
||||
activeQueryEditor.dbId :
|
||||
this.props.defaultDbId,
|
||||
@@ -166,10 +167,10 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
title=""
|
||||
>
|
||||
<MenuItem eventKey="1" onClick={this.removeQueryEditor.bind(this, qe)}>
|
||||
<i className="fa fa-close" /> close tab
|
||||
<i className="fa fa-close" /> {t('close tab')}
|
||||
</MenuItem>
|
||||
<MenuItem eventKey="2" onClick={this.renameTab.bind(this, qe)}>
|
||||
<i className="fa fa-i-cursor" /> rename tab
|
||||
<i className="fa fa-i-cursor" /> {t('rename tab')}
|
||||
</MenuItem>
|
||||
{qe &&
|
||||
<CopyQueryTabUrl queryEditor={qe} />
|
||||
@@ -177,7 +178,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
<MenuItem eventKey="4" onClick={this.toggleLeftBar.bind(this)}>
|
||||
<i className="fa fa-cogs" />
|
||||
|
||||
{this.state.hideLeftBar ? 'expand tool bar' : 'hide tool bar'}
|
||||
{this.state.hideLeftBar ? t('expand tool bar') : t('hide tool bar')}
|
||||
</MenuItem>
|
||||
</DropdownButton>
|
||||
</div>
|
||||
@@ -193,7 +194,7 @@ class TabbedSqlEditors extends React.PureComponent {
|
||||
{isSelected &&
|
||||
<SqlEditor
|
||||
height={this.props.editorHeight}
|
||||
tables={this.props.tables.filter(t => (t.queryEditorId === qe.id))}
|
||||
tables={this.props.tables.filter(xt => (xt.queryEditorId === qe.id))}
|
||||
queryEditor={qe}
|
||||
editorQueries={this.state.queriesArray}
|
||||
dataPreviewQueries={this.state.dataPreviewQueries}
|
||||
|
||||
@@ -9,6 +9,7 @@ import Link from './Link';
|
||||
import ColumnElement from './ColumnElement';
|
||||
import ModalTrigger from '../../components/ModalTrigger';
|
||||
import Loading from '../../components/Loading';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const propTypes = {
|
||||
table: PropTypes.object,
|
||||
@@ -71,7 +72,7 @@ class TableElement extends React.PureComponent {
|
||||
let partitionClipBoard;
|
||||
if (table.partitions.partitionQuery) {
|
||||
partitionQuery = table.partitions.partitionQuery;
|
||||
const tt = 'Copy partition query to clipboard';
|
||||
const tt = t('Copy partition query to clipboard');
|
||||
partitionClipBoard = (
|
||||
<CopyToClipboard
|
||||
text={partitionQuery}
|
||||
@@ -90,7 +91,7 @@ class TableElement extends React.PureComponent {
|
||||
<Well bsSize="small">
|
||||
<div>
|
||||
<small>
|
||||
latest partition: {latest}
|
||||
{t('latest partition:')} {latest}
|
||||
</small> {partitionClipBoard}
|
||||
</div>
|
||||
</Well>
|
||||
@@ -106,7 +107,7 @@ class TableElement extends React.PureComponent {
|
||||
<ModalTrigger
|
||||
modalTitle={
|
||||
<div>
|
||||
Keys for table <strong>{table.name}</strong>
|
||||
{t('Keys for table')} <strong>{table.name}</strong>
|
||||
</div>
|
||||
}
|
||||
modalBody={table.indexes.map((ix, i) => (
|
||||
@@ -115,7 +116,7 @@ class TableElement extends React.PureComponent {
|
||||
triggerNode={
|
||||
<Link
|
||||
className="fa fa-key pull-left m-l-2"
|
||||
tooltip={`View keys & indexes (${table.indexes.length})`}
|
||||
tooltip={t('View keys & indexes (%s)', table.indexes.length)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -131,8 +132,8 @@ class TableElement extends React.PureComponent {
|
||||
onClick={this.toggleSortColumns.bind(this)}
|
||||
tooltip={
|
||||
!this.state.sortColumns ?
|
||||
'Sort columns alphabetically' :
|
||||
'Original table column order'}
|
||||
t('Sort columns alphabetically') :
|
||||
t('Original table column order')}
|
||||
href="#"
|
||||
/>
|
||||
{table.selectStar &&
|
||||
@@ -142,13 +143,13 @@ class TableElement extends React.PureComponent {
|
||||
}
|
||||
text={table.selectStar}
|
||||
shouldShowText={false}
|
||||
tooltipText="Copy SELECT statement to clipboard"
|
||||
tooltipText={t('Copy SELECT statement to clipboard')}
|
||||
/>
|
||||
}
|
||||
<Link
|
||||
className="fa fa-times table-remove pull-left m-l-2"
|
||||
onClick={this.removeTable.bind(this)}
|
||||
tooltip="Remove table preview"
|
||||
tooltip={t('Remove table preview')}
|
||||
href="#"
|
||||
/>
|
||||
</ButtonGroup>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { getExploreUrl } from '../../explore/exploreUtils';
|
||||
import * as actions from '../actions';
|
||||
import { VISUALIZE_VALIDATION_ERRORS } from '../constants';
|
||||
import visTypes from '../../explore/stores/visTypes';
|
||||
import { t } from '../../locales';
|
||||
|
||||
const CHART_TYPES = Object.keys(visTypes)
|
||||
.filter(typeName => !!visTypes[typeName].showOnExplore)
|
||||
@@ -86,9 +87,9 @@ class VisualizeModal extends React.PureComponent {
|
||||
if (!re.test(colName)) {
|
||||
hints.push(
|
||||
<div>
|
||||
"{colName}" is not right as a column name, please alias it
|
||||
(as in SELECT count(*) <strong>AS my_alias</strong>) using only
|
||||
alphanumeric characters and underscores
|
||||
{t('%s is not right as a column name, please alias it ' +
|
||||
'(as in SELECT count(*) ', colName)} <strong>{t('AS my_alias')}</strong>) {t('using only ' +
|
||||
'alphanumeric characters and underscores')}
|
||||
</div>);
|
||||
}
|
||||
});
|
||||
@@ -162,7 +163,7 @@ class VisualizeModal extends React.PureComponent {
|
||||
if (mainGroupBy) {
|
||||
formData.groupby = [mainGroupBy.name];
|
||||
}
|
||||
notify.info('Creating a data source and popping a new tab');
|
||||
notify.info(t('Creating a data source and popping a new tab'));
|
||||
|
||||
window.open(getExploreUrl(formData));
|
||||
})
|
||||
@@ -192,7 +193,7 @@ class VisualizeModal extends React.PureComponent {
|
||||
<div className="VisualizeModal">
|
||||
<Modal show={this.props.show} onHide={this.props.onHide}>
|
||||
<Modal.Body>
|
||||
No results available for this query
|
||||
{t('No results available for this query')}
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
</div>
|
||||
@@ -237,17 +238,17 @@ class VisualizeModal extends React.PureComponent {
|
||||
<div className="VisualizeModal">
|
||||
<Modal show={this.props.show} onHide={this.props.onHide}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Visualize</Modal.Title>
|
||||
<Modal.Title>{t('Visualize')}</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
{alerts}
|
||||
{this.buildVisualizeAdvise()}
|
||||
<div className="row">
|
||||
<Col md={6}>
|
||||
Chart Type
|
||||
{t('Chart Type')}
|
||||
<Select
|
||||
name="select-chart-type"
|
||||
placeholder="[Chart Type]"
|
||||
placeholder={t('[Chart Type]')}
|
||||
options={CHART_TYPES}
|
||||
value={(this.state.chartType) ? this.state.chartType.value : null}
|
||||
autosize={false}
|
||||
@@ -255,11 +256,11 @@ class VisualizeModal extends React.PureComponent {
|
||||
/>
|
||||
</Col>
|
||||
<Col md={6}>
|
||||
Datasource Name
|
||||
{t('Datasource Name')}
|
||||
<input
|
||||
type="text"
|
||||
className="form-control input-sm"
|
||||
placeholder="datasource name"
|
||||
placeholder={t('datasource name')}
|
||||
onChange={this.changeDatasourceName.bind(this)}
|
||||
value={this.state.datasourceName}
|
||||
/>
|
||||
@@ -276,7 +277,7 @@ class VisualizeModal extends React.PureComponent {
|
||||
bsStyle="primary"
|
||||
disabled={(this.state.hints.length > 0)}
|
||||
>
|
||||
Visualize
|
||||
{t('Visualize')}
|
||||
</Button>
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
|
||||
Reference in New Issue
Block a user