-
- {/* @ts-ignore */}
-
+
+
+
+ {/* @ts-ignore */}
+
+
+
+
{title}
+
{description}
+
-
-
{title}
-
{description}
-
-
+
);
}
diff --git a/frontend/app/components/Dashboard/components/MetricTypeList/MetricTypeList.tsx b/frontend/app/components/Dashboard/components/MetricTypeList/MetricTypeList.tsx
index 46c540d07..e033396c4 100644
--- a/frontend/app/components/Dashboard/components/MetricTypeList/MetricTypeList.tsx
+++ b/frontend/app/components/Dashboard/components/MetricTypeList/MetricTypeList.tsx
@@ -2,27 +2,44 @@ import { useModal } from 'App/components/Modal';
import React from 'react';
import MetricsLibraryModal from '../MetricsLibraryModal';
import MetricTypeItem, { MetricType } from '../MetricTypeItem/MetricTypeItem';
-import { TYPES, LIBRARY } from 'App/constants/card';
+import { TYPES, LIBRARY, INSIGHTS } from 'App/constants/card';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import { dashboardMetricCreate, withSiteId } from 'App/routes';
import { useStore } from 'App/mstore';
+import { connect } from 'react-redux';
interface Props extends RouteComponentProps {
dashboardId: number;
siteId: string;
+ isEnterprise: boolean;
}
function MetricTypeList(props: Props) {
- const { dashboardId, siteId, history } = props;
+ const { dashboardId, siteId, history, isEnterprise } = props;
const { metricStore } = useStore();
const { hideModal } = useModal();
+ const list = React.useMemo(() => {
+ return TYPES.map((metric: MetricType) => {
+ const disabled = metric.slug === INSIGHTS && !isEnterprise;
+ return {
+ ...metric,
+ disabled: metric.slug === INSIGHTS && !isEnterprise,
+ tooltipTitle: disabled ? 'This feature requires an enterprise license.' : '',
+ };
+ });
+ }, []);
+
const { showModal } = useModal();
const onClick = ({ slug }: MetricType) => {
hideModal();
if (slug === LIBRARY) {
- return showModal(
, { right: true, width: 800, onClose: () => {
- metricStore.updateKey('metricsSearch', '')
- } });
+ return showModal(
, {
+ right: true,
+ width: 800,
+ onClose: () => {
+ metricStore.updateKey('metricsSearch', '');
+ },
+ });
}
// TODO redirect to card builder with metricType query param
@@ -30,17 +47,19 @@ function MetricTypeList(props: Props) {
const queryString = new URLSearchParams({ type: slug }).toString();
history.push({
pathname: path,
- search: `?${queryString}`
+ search: `?${queryString}`,
});
};
return (
<>
- {TYPES.map((metric: MetricType) => (
+ {list.map((metric: MetricType) => (
onClick(metric)} />
))}
>
);
}
-export default withRouter(MetricTypeList);
+export default connect((state: any) => ({
+ isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
+}))(withRouter(MetricTypeList));
diff --git a/frontend/app/components/Login/Login.js b/frontend/app/components/Login/Login.js
index 06a2a8dd7..9ce132f28 100644
--- a/frontend/app/components/Login/Login.js
+++ b/frontend/app/components/Login/Login.js
@@ -1,7 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import withPageTitle from 'HOCs/withPageTitle';
-import { Icon, Loader, Button, Link, Input, Form } from 'UI';
+import { Icon, Loader, Button, Link, Input, Form, Popover, Tooltip } from 'UI';
import { login } from 'Duck/user';
import { forgotPassword, signup } from 'App/routes';
import ReCAPTCHA from 'react-google-recaptcha';
@@ -16,12 +16,12 @@ const recaptchaRef = React.createRef();
@connect(
(state, props) => ({
- errors: state.getIn([ 'user', 'loginRequest', 'errors' ]),
- loading: state.getIn([ 'user', 'loginRequest', 'loading' ]),
+ errors: state.getIn(['user', 'loginRequest', 'errors']),
+ loading: state.getIn(['user', 'loginRequest', 'loading']),
authDetails: state.getIn(['user', 'authDetails']),
- params: new URLSearchParams(props.location.search)
+ params: new URLSearchParams(props.location.search),
}),
- { login, setJwt },
+ { login, setJwt }
)
@withPageTitle('Login - OpenReplay')
@withRouter
@@ -34,7 +34,7 @@ export default class Login extends React.Component {
componentDidMount() {
const { params } = this.props;
- const jwt = params.get('jwt')
+ const jwt = params.get('jwt');
if (jwt) {
this.props.setJwt(jwt);
window.location.href = '/';
@@ -44,110 +44,139 @@ export default class Login extends React.Component {
handleSubmit = (token) => {
const { email, password } = this.state;
this.props.login({ email: email.trim(), password, 'g-recaptcha-response': token }).then(() => {
- const { errors } = this.props;
- })
- }
+ const { errors } = this.props;
+ });
+ };
- onSubmit = (e) => {
+ onSubmit = (e) => {
e.preventDefault();
const { CAPTCHA_ENABLED } = this.state;
if (CAPTCHA_ENABLED && recaptchaRef.current) {
- recaptchaRef.current.execute();
+ recaptchaRef.current.execute();
} else if (!CAPTCHA_ENABLED) {
this.handleSubmit();
}
- }
+ };
- write = ({ target: { value, name } }) => this.setState({ [ name ]: value })
-
-
+ write = ({ target: { value, name } }) => this.setState({ [name]: value });
render() {
const { errors, loading, authDetails } = this.props;
const { CAPTCHA_ENABLED } = this.state;
return (
-