Skip to content

Commit

Permalink
Convert Angular services to CommonJS-style and use them in React comp…
Browse files Browse the repository at this point in the history
…onents instead of injecting (#3331)

* Refine Auth service: remove dead code and fix race condition
* Export services in CommonJS style
* Refine Users, Events and OfflineListener services
* Refactor Notifications service - rewrite to CommonJS
* Replace Angular service injection with imports in React components
* Fix Footer tests
* Events service -> recordEvent function
* CR1
  • Loading branch information
kravets-levko authored and arikfr committed Jan 24, 2019
1 parent c2c722e commit b0b4d5e
Show file tree
Hide file tree
Showing 41 changed files with 319 additions and 355 deletions.
2 changes: 1 addition & 1 deletion client/app/components/AutocompleteToggle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import Tooltip from 'antd/lib/tooltip';
import PropTypes from 'prop-types';
import '@/redash-font/style.less';
import recordEvent from '@/lib/recordEvent';
import recordEvent from '@/services/recordEvent';

export default function AutocompleteToggle({ state, disabled, onToggle }) {
let tooltipMessage = 'Live Autocomplete Enabled';
Expand Down
5 changes: 2 additions & 3 deletions client/app/components/DateInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import DatePicker from 'antd/lib/date-picker';
import { clientConfig } from '@/services/auth';

export function DateInput({
value,
onSelect,
// eslint-disable-next-line react/prop-types
clientConfig,
className,
}) {
const format = clientConfig.dateFormat || 'YYYY-MM-DD';
Expand Down Expand Up @@ -46,7 +45,7 @@ DateInput.defaultProps = {
};

export default function init(ngModule) {
ngModule.component('dateInput', react2angular(DateInput, null, ['clientConfig']));
ngModule.component('dateInput', react2angular(DateInput));
}

init.init = true;
5 changes: 2 additions & 3 deletions client/app/components/DateRangeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import DatePicker from 'antd/lib/date-picker';
import { clientConfig } from '@/services/auth';

const { RangePicker } = DatePicker;

export function DateRangeInput({
value,
onSelect,
// eslint-disable-next-line react/prop-types
clientConfig,
className,
}) {
const format = clientConfig.dateFormat || 'YYYY-MM-DD';
Expand Down Expand Up @@ -53,7 +52,7 @@ DateRangeInput.defaultProps = {
};

export default function init(ngModule) {
ngModule.component('dateRangeInput', react2angular(DateRangeInput, null, ['clientConfig']));
ngModule.component('dateRangeInput', react2angular(DateRangeInput));
}

init.init = true;
5 changes: 2 additions & 3 deletions client/app/components/DateTimeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import DatePicker from 'antd/lib/date-picker';
import { clientConfig } from '@/services/auth';

export function DateTimeInput({
value,
withSeconds,
onSelect,
// eslint-disable-next-line react/prop-types
clientConfig,
className,
}) {
const format = (clientConfig.dateFormat || 'YYYY-MM-DD') +
Expand Down Expand Up @@ -51,7 +50,7 @@ DateTimeInput.defaultProps = {
};

export default function init(ngModule) {
ngModule.component('dateTimeInput', react2angular(DateTimeInput, null, ['clientConfig']));
ngModule.component('dateTimeInput', react2angular(DateTimeInput));
}

init.init = true;
5 changes: 2 additions & 3 deletions client/app/components/DateTimeRangeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import DatePicker from 'antd/lib/date-picker';
import { clientConfig } from '@/services/auth';

const { RangePicker } = DatePicker;

export function DateTimeRangeInput({
value,
withSeconds,
onSelect,
// eslint-disable-next-line react/prop-types
clientConfig,
className,
}) {
const format = (clientConfig.dateFormat || 'YYYY-MM-DD') +
Expand Down Expand Up @@ -58,7 +57,7 @@ DateTimeRangeInput.defaultProps = {
};

export default function init(ngModule) {
ngModule.component('dateTimeRangeInput', react2angular(DateTimeRangeInput, null, ['clientConfig']));
ngModule.component('dateTimeRangeInput', react2angular(DateTimeRangeInput));
}

init.init = true;
Expand Down
17 changes: 3 additions & 14 deletions client/app/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';

import { react2angular } from 'react2angular';
import { clientConfig, currentUser } from '@/services/auth';

import frontendVersion from '../version.json';

export function Footer({ clientConfig, currentUser }) {
export function Footer() {
const backendVersion = clientConfig.version;
const newVersionAvailable = clientConfig.newVersionAvailable && currentUser.isAdmin;
const separator = ' \u2022 ';
Expand All @@ -31,18 +30,8 @@ export function Footer({ clientConfig, currentUser }) {
);
}

Footer.propTypes = {
clientConfig: PropTypes.shape({
version: PropTypes.string,
newVersionAvailable: PropTypes.bool,
}).isRequired,
currentUser: PropTypes.shape({
isAdmin: PropTypes.bool,
}).isRequired,
};

export default function init(ngModule) {
ngModule.component('footer', react2angular(Footer, [], ['clientConfig', 'currentUser']));
ngModule.component('footer', react2angular(Footer));
}

init.init = true;
15 changes: 9 additions & 6 deletions client/app/components/Footer.test.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { extend } from 'lodash';
import React from 'react';
import renderer from 'react-test-renderer';
import { clientConfig, currentUser } from '../services/auth';
import { Footer } from './Footer';

test('Footer renders', () => {
const clientConfig = {
// TODO: Properly mock this
extend(clientConfig, {
version: '5.0.1',
newVersionAvailable: true,
};
const currentUser = {
isAdmin: true,
};
const component = renderer.create(<Footer clientConfig={clientConfig} currentUser={currentUser} />);
});
extend(currentUser, {
permissions: ['admin'],
});
const component = renderer.create(<Footer />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
55 changes: 8 additions & 47 deletions client/app/components/ParameterValueInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,99 +31,69 @@ export class ParameterValueInput extends React.Component {
};

renderDateTimeWithSecondsInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateTimeInput
className={this.props.className}
value={value}
onSelect={onSelect}
withSeconds
clientConfig={clientConfig}
/>
);
}

renderDateTimeInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateTimeInput
className={this.props.className}
value={value}
onSelect={onSelect}
clientConfig={clientConfig}
/>
);
}

renderDateInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateInput
className={this.props.className}
value={value}
onSelect={onSelect}
clientConfig={clientConfig}
/>
);
}

renderDateTimeRangeWithSecondsInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateTimeRangeInput
className={this.props.className}
value={value}
onSelect={onSelect}
withSeconds
clientConfig={clientConfig}
/>
);
}

renderDateTimeRangeInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateTimeRangeInput
className={this.props.className}
value={value}
onSelect={onSelect}
clientConfig={clientConfig}
/>
);
}

renderDateRangeInput() {
const {
value,
onSelect,
clientConfig, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect } = this.props;
return (
<DateRangeInput
className={this.props.className}
value={value}
onSelect={onSelect}
clientConfig={clientConfig}
/>
);
}
Expand All @@ -146,19 +116,13 @@ export class ParameterValueInput extends React.Component {
}

renderQueryBasedInput() {
const {
value,
onSelect,
queryId,
Query, // eslint-disable-line react/prop-types
} = this.props;
const { value, onSelect, queryId } = this.props;
return (
<QueryBasedParameterInput
className={this.props.className}
value={value}
queryId={queryId}
onSelect={onSelect}
Query={Query}
/>
);
}
Expand Down Expand Up @@ -212,10 +176,7 @@ export default function init(ngModule) {
};
},
});
ngModule.component(
'parameterValueInputImpl',
react2angular(ParameterValueInput, null, ['clientConfig', 'Query']),
);
ngModule.component('parameterValueInputImpl', react2angular(ParameterValueInput));
}

init.init = true;
4 changes: 2 additions & 2 deletions client/app/components/QueryBasedParameterInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { react2angular } from 'react2angular';
import Select from 'antd/lib/select';
import { Query } from '@/services/query';

const { Option } = Select;

Expand Down Expand Up @@ -79,7 +80,6 @@ export class QueryBasedParameterInput extends React.Component {

_loadOptions(queryId) {
if (queryId && (queryId !== this.state.queryId)) {
const Query = this.props.Query; // eslint-disable-line react/prop-types
this.setState({ loading: true });
Query.resultById({ id: queryId }, (result) => {
if (this.props.queryId === queryId) {
Expand Down Expand Up @@ -117,7 +117,7 @@ export class QueryBasedParameterInput extends React.Component {
}

export default function init(ngModule) {
ngModule.component('queryBasedParameterInput', react2angular(QueryBasedParameterInput, null, ['Query']));
ngModule.component('queryBasedParameterInput', react2angular(QueryBasedParameterInput));
}

init.init = true;
20 changes: 10 additions & 10 deletions client/app/components/QueryEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import 'brace/mode/sql';
import 'brace/theme/textmate';
import 'brace/ext/searchbox';

import { Query } from '@/services/query';
import { QuerySnippet } from '@/services/query-snippet';
import { KeyboardShortcuts } from '@/services/keyboard-shortcuts';

import localOptions from '@/lib/localOptions';
import AutocompleteToggle from '@/components/AutocompleteToggle';
import keywordBuilder from './keywordBuilder';
Expand Down Expand Up @@ -152,8 +156,7 @@ class QueryEditor extends React.Component {
}
});

// eslint-disable-next-line react/prop-types
this.props.QuerySnippet.query((snippets) => {
QuerySnippet.query((snippets) => {
const snippetManager = snippetsModule.snippetManager;
const m = {
snippetText: '',
Expand Down Expand Up @@ -194,29 +197,26 @@ class QueryEditor extends React.Component {
const selectedQueryText = (rawSelectedQueryText.length > 1) ? rawSelectedQueryText : null;
this.setState({ selectedQueryText });
this.props.updateSelectedQuery(selectedQueryText);
}
};

updateQuery = (queryText) => {
this.props.updateQuery(queryText);
this.setState({ queryText });
};

formatQuery = () => {
// eslint-disable-next-line react/prop-types
const format = this.props.Query.format;
format(this.props.dataSource.syntax || 'sql', this.props.queryText)
Query.format(this.props.dataSource.syntax || 'sql', this.props.queryText)
.then(this.updateQuery)
.catch(error => toastr.error(error));
};

toggleAutocomplete = (state) => {
this.setState({ autocompleteQuery: state });
localOptions.set('liveAutocomplete', state);
}
};

render() {
// eslint-disable-next-line react/prop-types
const modKey = this.props.KeyboardShortcuts.modKey;
const modKey = KeyboardShortcuts.modKey;

const isExecuteDisabled = this.props.queryExecuting || !this.props.canExecuteQuery();

Expand Down Expand Up @@ -320,7 +320,7 @@ class QueryEditor extends React.Component {
}

export default function init(ngModule) {
ngModule.component('queryEditor', react2angular(QueryEditor, null, ['QuerySnippet', 'Query', 'KeyboardShortcuts']));
ngModule.component('queryEditor', react2angular(QueryEditor));
}

init.init = true;
Loading

0 comments on commit b0b4d5e

Please sign in to comment.