move api and "few" files to new project store
This commit is contained in:
parent
82586d23b2
commit
df20cd5333
18 changed files with 255 additions and 331 deletions
|
|
@ -3,8 +3,8 @@ import { Map } from 'immutable';
|
|||
import React, { Suspense, lazy } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import AdditionalRoutes from 'App/AdditionalRoutes';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from "./mstore";
|
||||
import { GLOBAL_HAS_NO_RECORDINGS } from 'App/constants/storageKeys';
|
||||
import { OB_DEFAULT_TAB } from 'App/routes';
|
||||
import { Loader } from 'UI';
|
||||
|
|
@ -110,20 +110,20 @@ const SCOPE_SETUP = routes.scopeSetup();
|
|||
|
||||
interface Props {
|
||||
tenantId: string;
|
||||
siteId: string;
|
||||
sites: Map<string, any>;
|
||||
onboarding: boolean;
|
||||
scope: number;
|
||||
}
|
||||
|
||||
function PrivateRoutes(props: Props) {
|
||||
const { onboarding, sites, siteId } = props;
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const siteId = projectsStore.siteId;
|
||||
const { onboarding } = props;
|
||||
const hasRecordings = sites.some(s => s.recorded);
|
||||
const redirectToSetup = props.scope === 0;
|
||||
const redirectToOnboarding =
|
||||
!onboarding && (localStorage.getItem(GLOBAL_HAS_NO_RECORDINGS) === 'true' || !hasRecordings) && props.scope > 0;
|
||||
const siteIdList: any = sites.map(({ id }) => id).toJS();
|
||||
|
||||
!onboarding && (localStorage.getItem(GLOBAL_HAS_NO_RECORDINGS) === 'true' || (sites.length > 0 && !hasRecordings)) && props.scope > 0;
|
||||
const siteIdList: any = sites.map(({ id }) => id);
|
||||
return (
|
||||
<Suspense fallback={<Loader loading={true} className="flex-1" />}>
|
||||
<Switch key="content">
|
||||
|
|
@ -292,7 +292,5 @@ function PrivateRoutes(props: Props) {
|
|||
export default connect((state: any) => ({
|
||||
onboarding: state.getIn(['user', 'onboarding']),
|
||||
scope: getScope(state),
|
||||
sites: state.getIn(['site', 'list']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
tenantId: state.getIn(['user', 'account', 'tenantId']),
|
||||
}))(PrivateRoutes);
|
||||
}))(observer(PrivateRoutes));
|
||||
|
|
|
|||
|
|
@ -13,56 +13,55 @@ import {
|
|||
SPOT_ONBOARDING
|
||||
} from 'App/constants/storageKeys';
|
||||
import Layout from 'App/layout/Layout';
|
||||
import { useStore, withStore } from 'App/mstore';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { checkParam, handleSpotJWT, isTokenExpired } from 'App/utils';
|
||||
import { ModalProvider } from 'Components/Modal';
|
||||
import { ModalProvider as NewModalProvider } from 'Components/ModalContext';
|
||||
import { setSessionPath } from 'Duck/sessions';
|
||||
import { fetchList as fetchSiteList } from 'Duck/site';
|
||||
import { init as initSite } from 'Duck/site';
|
||||
import { fetchUserInfo, getScope, logout, setJwt } from 'Duck/user';
|
||||
import { Loader } from 'UI';
|
||||
import * as routes from './routes';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
interface RouterProps
|
||||
extends RouteComponentProps,
|
||||
ConnectedProps<typeof connector> {
|
||||
isLoggedIn: boolean;
|
||||
sites: Map<string, any>;
|
||||
loading: boolean;
|
||||
changePassword: boolean;
|
||||
isEnterprise: boolean;
|
||||
fetchUserInfo: () => any;
|
||||
setSessionPath: (path: any) => any;
|
||||
fetchSiteList: (siteId?: number) => any;
|
||||
match: {
|
||||
params: {
|
||||
siteId: string;
|
||||
};
|
||||
};
|
||||
mstore: any;
|
||||
setJwt: (params: { jwt: string; spotJwt: string | null }) => any;
|
||||
initSite: (site: any) => void;
|
||||
scopeSetup: boolean;
|
||||
localSpotJwt: string | null;
|
||||
}
|
||||
|
||||
const Router: React.FC<RouterProps> = (props) => {
|
||||
const {
|
||||
isLoggedIn,
|
||||
siteId,
|
||||
sites,
|
||||
loading,
|
||||
userInfoLoading,
|
||||
location,
|
||||
fetchUserInfo,
|
||||
fetchSiteList,
|
||||
history,
|
||||
setSessionPath,
|
||||
scopeSetup,
|
||||
localSpotJwt,
|
||||
logout
|
||||
logout,
|
||||
scopeSetup,
|
||||
setJwt,
|
||||
} = props;
|
||||
const { customFieldStore } = useStore();
|
||||
const mstore = useStore();
|
||||
const { customFieldStore, projectsStore } = mstore;
|
||||
|
||||
const siteId = projectsStore.siteId;
|
||||
const sitesLoading = projectsStore.sitesLoading;
|
||||
const sites = projectsStore.list;
|
||||
const loading = Boolean(userInfoLoading || (!scopeSetup && !siteId) || sitesLoading);
|
||||
const initSite = projectsStore.initProject;
|
||||
const fetchSiteList = projectsStore.fetchList;
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
const spotCb = params.get('spotCallback');
|
||||
|
|
@ -80,7 +79,7 @@ const Router: React.FC<RouterProps> = (props) => {
|
|||
handleSpotLogin(spotJwt);
|
||||
}
|
||||
if (urlJWT) {
|
||||
props.setJwt({ jwt: urlJWT, spotJwt: spotJwt ?? null });
|
||||
setJwt({ jwt: urlJWT, spotJwt: spotJwt ?? null });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -108,9 +107,9 @@ const Router: React.FC<RouterProps> = (props) => {
|
|||
localStorage.setItem(SPOT_ONBOARDING, 'true');
|
||||
}
|
||||
await fetchUserInfo();
|
||||
const siteIdFromPath = parseInt(location.pathname.split('/')[1]);
|
||||
const siteIdFromPath = location.pathname.split('/')[1];
|
||||
await fetchSiteList(siteIdFromPath);
|
||||
props.mstore.initClient();
|
||||
mstore.initClient();
|
||||
|
||||
if (localSpotJwt && !isTokenExpired(localSpotJwt)) {
|
||||
handleSpotLogin(localSpotJwt);
|
||||
|
|
@ -177,13 +176,13 @@ const Router: React.FC<RouterProps> = (props) => {
|
|||
const fetchData = async () => {
|
||||
if (siteId && siteId !== lastFetchedSiteIdRef.current) {
|
||||
const activeSite = sites.find((s) => s.id == siteId);
|
||||
props.initSite(activeSite);
|
||||
lastFetchedSiteIdRef.current = activeSite.id;
|
||||
initSite(activeSite ?? {});
|
||||
lastFetchedSiteIdRef.current = activeSite?.id;
|
||||
await customFieldStore.fetchListActive(siteId + '');
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
void fetchData();
|
||||
}, [siteId]);
|
||||
|
||||
const lastFetchedSiteIdRef = useRef<any>(null);
|
||||
|
|
@ -229,7 +228,6 @@ const Router: React.FC<RouterProps> = (props) => {
|
|||
};
|
||||
|
||||
const mapStateToProps = (state: Map<string, any>) => {
|
||||
const siteId = state.getIn(['site', 'siteId']);
|
||||
const jwt = state.getIn(['user', 'jwt']);
|
||||
const changePassword = state.getIn(['user', 'account', 'changePassword']);
|
||||
const userInfoLoading = state.getIn([
|
||||
|
|
@ -237,21 +235,14 @@ const mapStateToProps = (state: Map<string, any>) => {
|
|||
'fetchUserInfoRequest',
|
||||
'loading'
|
||||
]);
|
||||
const sitesLoading = state.getIn(['site', 'fetchListRequest', 'loading']);
|
||||
const scopeSetup = getScope(state) === 0;
|
||||
const loading =
|
||||
Boolean(userInfoLoading) ||
|
||||
Boolean(sitesLoading) ||
|
||||
(!scopeSetup && !siteId);
|
||||
return {
|
||||
siteId,
|
||||
changePassword,
|
||||
sites: state.getIn(['site', 'list']),
|
||||
jwt,
|
||||
scopeSetup,
|
||||
localSpotJwt: state.getIn(['user', 'spotJwt']),
|
||||
isLoggedIn: jwt !== null && !changePassword,
|
||||
scopeSetup,
|
||||
loading,
|
||||
userInfoLoading,
|
||||
email: state.getIn(['user', 'account', 'email']),
|
||||
account: state.getIn(['user', 'account']),
|
||||
organisation: state.getIn(['user', 'account', 'name']),
|
||||
|
|
@ -266,12 +257,10 @@ const mapStateToProps = (state: Map<string, any>) => {
|
|||
const mapDispatchToProps = {
|
||||
fetchUserInfo,
|
||||
setSessionPath,
|
||||
fetchSiteList,
|
||||
setJwt,
|
||||
initSite,
|
||||
logout
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export default withStore(withRouter(connector(Router)));
|
||||
export default withRouter(connector(observer(Router)));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import store from 'App/store';
|
||||
import { queried } from './routes';
|
||||
import { setJwt } from 'Duck/user';
|
||||
import { projectStore } from 'App/mstore';
|
||||
|
||||
const siteIdRequiredPaths: string[] = [
|
||||
'/dashboard',
|
||||
|
|
@ -55,12 +54,12 @@ export const clean = (obj: any, forbiddenValues: any[] = [undefined, '']): any =
|
|||
|
||||
export default class APIClient {
|
||||
private init: RequestInit;
|
||||
private readonly siteId: string | undefined;
|
||||
private siteId: string | undefined;
|
||||
private siteIdCheck: (() => { siteId: string | null }) | undefined;
|
||||
private refreshingTokenPromise: Promise<string> | null = null;
|
||||
|
||||
constructor() {
|
||||
const jwt = store.getState().getIn(['user', 'jwt']);
|
||||
const { siteId } = projectStore.getSiteId();
|
||||
this.init = {
|
||||
headers: new Headers({
|
||||
Accept: 'application/json',
|
||||
|
|
@ -70,7 +69,10 @@ export default class APIClient {
|
|||
if (jwt !== null) {
|
||||
(this.init.headers as Headers).set('Authorization', `Bearer ${jwt}`);
|
||||
}
|
||||
this.siteId = siteId || undefined;
|
||||
}
|
||||
|
||||
setSiteIdCheck(checker: () => { siteId: string | null }): void {
|
||||
this.siteIdCheck = checker
|
||||
}
|
||||
|
||||
private getInit(method: string = 'GET', params?: any, reqHeaders?: Record<string, any>): RequestInit {
|
||||
|
|
@ -102,6 +104,7 @@ export default class APIClient {
|
|||
delete init.body; // GET requests shouldn't have a body
|
||||
}
|
||||
|
||||
this.siteId = this.siteIdCheck?.().siteId ?? undefined;
|
||||
return init;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { connect } from 'react-redux';
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import { Button, Loader, NoContent, Icon, Tooltip, Divider } from 'UI';
|
||||
import SiteDropdown from 'Shared/SiteDropdown';
|
||||
|
|
@ -12,20 +11,17 @@ import { useModal } from 'App/components/Modal';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
interface CustomFieldsProps {
|
||||
sites: any;
|
||||
}
|
||||
|
||||
const CustomFields: React.FC<CustomFieldsProps> = (props) => {
|
||||
const [currentSite, setCurrentSite] = useState(props.sites.get(0));
|
||||
const CustomFields = () => {
|
||||
const { customFieldStore: store, projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const [currentSite, setCurrentSite] = useState(sites[0]);
|
||||
const [deletingItem, setDeletingItem] = useState<number | null>(null);
|
||||
const { showModal, hideModal } = useModal();
|
||||
const { customFieldStore: store } = useStore();
|
||||
const fields = store.list;
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const activeSite = props.sites.get(0);
|
||||
const activeSite = sites[0];
|
||||
if (!activeSite) return;
|
||||
|
||||
setCurrentSite(activeSite);
|
||||
|
|
@ -34,7 +30,7 @@ const CustomFields: React.FC<CustomFieldsProps> = (props) => {
|
|||
store.fetchList(activeSite.id).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}, [props.sites]);
|
||||
}, [sites]);
|
||||
|
||||
const handleInit = (field?: any) => {
|
||||
console.log('field', field);
|
||||
|
|
@ -45,7 +41,7 @@ const CustomFields: React.FC<CustomFieldsProps> = (props) => {
|
|||
};
|
||||
|
||||
const onChangeSelect = ({ value }: { value: { value: number } }) => {
|
||||
const site = props.sites.find((s: any) => s.id === value.value);
|
||||
const site = sites.find((s: any) => s.id === value.value);
|
||||
setCurrentSite(site);
|
||||
|
||||
setLoading(true);
|
||||
|
|
@ -109,6 +105,4 @@ const CustomFields: React.FC<CustomFieldsProps> = (props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default connect((state: any) => ({
|
||||
sites: state.getIn(['site', 'list'])
|
||||
}))(withPageTitle('Metadata - OpenReplay Preferences')(observer(CustomFields)));
|
||||
export default withPageTitle('Metadata - OpenReplay Preferences')(observer(CustomFields));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import { Button, Checkbox, Form, Input, Loader } from 'UI';
|
|||
|
||||
function IntegrationForm(props: any) {
|
||||
const { formFields, name, integrated } = props;
|
||||
const { integrationsStore } = useStore();
|
||||
const { integrationsStore, projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const initialSiteId = projectsStore.siteId;
|
||||
const integrationStore = integrationsStore[name as unknown as namedStore];
|
||||
const config = integrationStore.instance;
|
||||
const loading = integrationStore.loading;
|
||||
|
|
@ -18,7 +20,7 @@ function IntegrationForm(props: any) {
|
|||
const fetchIntegrationList = integrationsStore.integrations.fetchIntegrations;
|
||||
|
||||
const fetchList = () => {
|
||||
void fetchIntegrationList(props.initialSiteId);
|
||||
void fetchIntegrationList(initialSiteId);
|
||||
};
|
||||
|
||||
const write = ({ target: { value, name: key, type, checked } }) => {
|
||||
|
|
@ -104,7 +106,4 @@ function IntegrationForm(props: any) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
sites: state.getIn(['site', 'list']),
|
||||
initialSiteId: state.getIn(['site', 'siteId']),
|
||||
}))(observer(IntegrationForm));
|
||||
export default observer(IntegrationForm);
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ interface Props {
|
|||
}
|
||||
|
||||
function Integrations(props: Props) {
|
||||
const { integrationsStore } = useStore();
|
||||
|
||||
const { integrationsStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const fetchIntegrationList = integrationsStore.integrations.fetchIntegrations;
|
||||
const storeIntegratedList = integrationsStore.integrations.list;
|
||||
const { siteId, hideHeader = false } = props;
|
||||
const { hideHeader = false } = props;
|
||||
const { showModal } = useModal();
|
||||
const [integratedList, setIntegratedList] = useState<string[]>([]);
|
||||
const [activeFilter, setActiveFilter] = useState<string>('all');
|
||||
|
|
@ -162,11 +162,7 @@ function Integrations(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
}))(
|
||||
withPageTitle('Integrations - OpenReplay Preferences')(observer(Integrations))
|
||||
);
|
||||
export default withPageTitle('Integrations - OpenReplay Preferences')(observer(Integrations))
|
||||
|
||||
const integrations = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import ToggleContent from 'Components/shared/ToggleContent';
|
||||
|
|
@ -8,9 +7,9 @@ import { CodeBlock } from 'UI';
|
|||
|
||||
import DocLink from 'Shared/DocLink/DocLink';
|
||||
|
||||
const PiniaDoc = (props) => {
|
||||
const { integrationsStore } = useStore();
|
||||
const sites = props.sites ? props.sites.toJS() : [];
|
||||
const PiniaDoc = () => {
|
||||
const { integrationsStore, projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const siteId = integrationsStore.integrations.siteId;
|
||||
const projectKey = siteId
|
||||
? sites.find((site) => site.id === siteId)?.projectKey
|
||||
|
|
@ -110,9 +109,4 @@ piniaStorePlugin(examplePiniaStore)
|
|||
|
||||
PiniaDoc.displayName = 'PiniaDoc';
|
||||
|
||||
export default connect((state: any) => {
|
||||
const sites = state.getIn(['site', 'list']);
|
||||
return {
|
||||
sites,
|
||||
};
|
||||
})(observer(PiniaDoc));
|
||||
export default observer(PiniaDoc);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Tooltip, Button } from 'UI';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import { init, remove, fetchGDPR } from 'Duck/site';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { connect } from 'react-redux';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import NewSiteForm from '../NewSiteForm';
|
||||
|
|
@ -10,16 +9,15 @@ import NewSiteForm from '../NewSiteForm';
|
|||
const PERMISSION_WARNING = 'You don’t have the permissions to perform this action.';
|
||||
const LIMIT_WARNING = 'You have reached site limit.';
|
||||
|
||||
function AddProjectButton({ isAdmin = false, init = () => {} }: any) {
|
||||
const { userStore } = useStore();
|
||||
function AddProjectButton({ isAdmin = false }: any) {
|
||||
const { userStore, projectsStore } = useStore();
|
||||
const init = projectsStore.initProject;
|
||||
const { showModal, hideModal } = useModal();
|
||||
const limtis = useObserver(() => userStore.limits);
|
||||
const canAddProject = useObserver(
|
||||
() => isAdmin && (limtis.projects === -1 || limtis.projects > 0)
|
||||
);
|
||||
const limits = userStore.limits;
|
||||
const canAddProject = isAdmin && (limits.projects === -1 || limits.projects > 0)
|
||||
|
||||
const onClick = () => {
|
||||
init();
|
||||
init({});
|
||||
showModal(<NewSiteForm onClose={hideModal} />, { right: true });
|
||||
};
|
||||
return (
|
||||
|
|
@ -34,4 +32,4 @@ function AddProjectButton({ isAdmin = false, init = () => {} }: any) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(null, { init, remove, fetchGDPR })(AddProjectButton);
|
||||
export default observer(AddProjectButton);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from "App/mstore";
|
||||
import { Form, Button, Input, Icon } from 'UI';
|
||||
import { editGDPR, saveGDPR } from 'Duck/site';
|
||||
import { validateNumber } from 'App/validate';
|
||||
import styles from './siteForm.module.css';
|
||||
import Select from 'Shared/Select';
|
||||
|
|
@ -12,124 +12,118 @@ const inputModeOptions = [
|
|||
{ label: 'Obscure all inputs', value: 'hidden' },
|
||||
];
|
||||
|
||||
@connect(state => ({
|
||||
site: state.getIn([ 'site', 'instance' ]),
|
||||
gdpr: state.getIn([ 'site', 'instance', 'gdpr' ]),
|
||||
saving: state.getIn([ 'site', 'saveGDPR', 'loading' ]),
|
||||
}), {
|
||||
editGDPR,
|
||||
saveGDPR,
|
||||
})
|
||||
export default class GDPRForm extends React.PureComponent {
|
||||
onChange = ({ target: { name, value } }) => {
|
||||
function GDPRForm(props) {
|
||||
const { projectsStore } = useStore();
|
||||
const site = projectsStore.instance;
|
||||
const gdpr = site.gdpr;
|
||||
const saving = false //projectsStore.;
|
||||
const editGDPR = projectsStore.editGDPR;
|
||||
const saveGDPR = projectsStore.saveGDPR;
|
||||
|
||||
|
||||
const onChange = ({ target: { name, value } }) => {
|
||||
if (name === "sampleRate") {
|
||||
if (!validateNumber(value, { min: 0, max: 100 })) return;
|
||||
if (value.length > 1 && value[0] === "0") {
|
||||
value = value.slice(1);
|
||||
}
|
||||
}
|
||||
this.props.editGDPR({ [ name ]: value });
|
||||
editGDPR({ [ name ]: value });
|
||||
}
|
||||
|
||||
onSampleRateBlur = ({ target: { name, value } }) => { //TODO: editState hoc
|
||||
const onSampleRateBlur = ({ target: { name, value } }) => { //TODO: editState hoc
|
||||
if (value === ''){
|
||||
this.props.editGDPR({ sampleRate: 100 });
|
||||
editGDPR({ sampleRate: 100 });
|
||||
}
|
||||
}
|
||||
|
||||
onChangeSelect = ({ name, value }) => {
|
||||
this.props.editGDPR({ [ name ]: value });
|
||||
const onChangeSelect = ({ name, value }) => {
|
||||
props.editGDPR({ [ name ]: value });
|
||||
};
|
||||
|
||||
onChangeOption = ({ target: { checked, name } }) => {
|
||||
this.props.editGDPR({ [ name ]: checked });
|
||||
const onChangeOption = ({ target: { checked, name } }) => {
|
||||
editGDPR({ [ name ]: checked });
|
||||
}
|
||||
|
||||
onSubmit = (e) => {
|
||||
const onSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
const { site, gdpr } = this.props;
|
||||
this.props.saveGDPR(site.id, gdpr);
|
||||
void saveGDPR(site.id);
|
||||
}
|
||||
|
||||
return (
|
||||
<Form className={ styles.formWrapper } onSubmit={ onSubmit }>
|
||||
<div className={ styles.content }>
|
||||
<Form.Field>
|
||||
<label>{ 'Name' }</label>
|
||||
<div>{ site.host }</div>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>{ 'Session Capture Rate' }</label>
|
||||
<Input
|
||||
icon="percent"
|
||||
name="sampleRate"
|
||||
value={ gdpr.sampleRate }
|
||||
onChange={ onChange }
|
||||
onBlur={ onSampleRateBlur }
|
||||
className={ styles.sampleRate }
|
||||
/>
|
||||
</Form.Field>
|
||||
|
||||
render() {
|
||||
const {
|
||||
site, onClose, saving, gdpr,
|
||||
} = this.props;
|
||||
<Form.Field>
|
||||
<label htmlFor="defaultInputMode">{ 'Data Recording Options' }</label>
|
||||
<Select
|
||||
name="defaultInputMode"
|
||||
options={ inputModeOptions }
|
||||
onChange={ onChangeSelect }
|
||||
placeholder="Default Input Mode"
|
||||
value={ gdpr.defaultInputMode }
|
||||
/>
|
||||
</Form.Field>
|
||||
|
||||
return (
|
||||
<Form className={ styles.formWrapper } onSubmit={ this.onSubmit }>
|
||||
<div className={ styles.content }>
|
||||
<Form.Field>
|
||||
<label>{ 'Name' }</label>
|
||||
<div>{ site.host }</div>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>{ 'Session Capture Rate' }</label>
|
||||
<Input
|
||||
icon="percent"
|
||||
name="sampleRate"
|
||||
value={ gdpr.sampleRate }
|
||||
onChange={ this.onChange }
|
||||
onBlur={ this.onSampleRateBlur }
|
||||
className={ styles.sampleRate }
|
||||
<Form.Field>
|
||||
<label>
|
||||
<input
|
||||
name="maskNumbers"
|
||||
type="checkbox"
|
||||
checked={ gdpr.maskNumbers }
|
||||
onChange={ onChangeOption }
|
||||
/>
|
||||
</Form.Field>
|
||||
{ 'Do not record any numeric text' }
|
||||
<div className={ styles.controlSubtext }>{ 'If enabled, OpenReplay will not record or store any numeric text for all sessions.' }</div>
|
||||
</label>
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label htmlFor="defaultInputMode">{ 'Data Recording Options' }</label>
|
||||
<Select
|
||||
name="defaultInputMode"
|
||||
options={ inputModeOptions }
|
||||
onChange={ this.onChangeSelect }
|
||||
placeholder="Default Input Mode"
|
||||
value={ gdpr.defaultInputMode }
|
||||
// className={ styles.dropdown }
|
||||
<Form.Field>
|
||||
<label>
|
||||
<input
|
||||
name="maskEmails"
|
||||
type="checkbox"
|
||||
checked={ gdpr.maskEmails }
|
||||
onChange={ onChangeOption }
|
||||
/>
|
||||
</Form.Field>
|
||||
{ 'Do not record email addresses ' }
|
||||
<div className={ styles.controlSubtext }>{ 'If enabled, OpenReplay will not record or store any email address for all sessions.' }</div>
|
||||
</label>
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label>
|
||||
<input
|
||||
name="maskNumbers"
|
||||
type="checkbox"
|
||||
checked={ gdpr.maskNumbers }
|
||||
onChange={ this.onChangeOption }
|
||||
/>
|
||||
{ 'Do not record any numeric text' }
|
||||
<div className={ styles.controlSubtext }>{ 'If enabled, OpenReplay will not record or store any numeric text for all sessions.' }</div>
|
||||
</label>
|
||||
</Form.Field>
|
||||
|
||||
<Form.Field>
|
||||
<label>
|
||||
<input
|
||||
name="maskEmails"
|
||||
type="checkbox"
|
||||
checked={ gdpr.maskEmails }
|
||||
onChange={ this.onChangeOption }
|
||||
/>
|
||||
{ 'Do not record email addresses ' }
|
||||
<div className={ styles.controlSubtext }>{ 'If enabled, OpenReplay will not record or store any email address for all sessions.' }</div>
|
||||
</label>
|
||||
</Form.Field>
|
||||
|
||||
<div className={ styles.blockIpWarapper }>
|
||||
<div className={ styles.button } onClick={ this.props.toggleBlockedIp }>
|
||||
{ 'Block IP' } <Icon name="next1" size="18" />
|
||||
</div>
|
||||
<div className={ styles.blockIpWarapper }>
|
||||
<div className={ styles.button } onClick={ props.toggleBlockedIp }>
|
||||
{ 'Block IP' } <Icon name="next1" size="18" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={ styles.footer }>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="float-left mr-2"
|
||||
loading={ saving }
|
||||
content="Update"
|
||||
/>
|
||||
<Button onClick={ onClose } content="Cancel" />
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
<div className={ styles.footer }>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="float-left mr-2"
|
||||
loading={ saving }
|
||||
content="Update"
|
||||
/>
|
||||
<Button onClick={ onClose } content="Cancel" />
|
||||
</div>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default observer(GDPRForm);
|
||||
|
|
@ -3,7 +3,6 @@ import { connect, ConnectedProps } from 'react-redux';
|
|||
import { Tag } from 'antd';
|
||||
import cn from 'classnames';
|
||||
import { Loader, Button, TextLink, NoContent, Pagination, PageTitle, Divider, Icon } from 'UI';
|
||||
import { init, remove, fetchGDPR, setSiteId } from 'Duck/site';
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import stl from './sites.module.css';
|
||||
import NewSiteForm from './NewSiteForm';
|
||||
|
|
@ -16,9 +15,11 @@ import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
|||
import { useModal } from 'App/components/Modal';
|
||||
import CaptureRate from 'Shared/SessionSettings/components/CaptureRate';
|
||||
import { BranchesOutlined } from '@ant-design/icons';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore'
|
||||
|
||||
type Project = {
|
||||
id: number;
|
||||
id: string;
|
||||
name: string;
|
||||
conditionsCount: number;
|
||||
platform: 'web' | 'mobile';
|
||||
|
|
@ -29,7 +30,11 @@ type Project = {
|
|||
|
||||
type PropsFromRedux = ConnectedProps<typeof connector>;
|
||||
|
||||
const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
|
||||
const Sites = ({ user }: PropsFromRedux) => {
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const loading = projectsStore.sitesLoading;
|
||||
const init = projectsStore.initProject
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showCaptureRate, setShowCaptureRate] = useState(true);
|
||||
const [activeProject, setActiveProject] = useState<Project | null>(null);
|
||||
|
|
@ -140,7 +145,7 @@ const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
|
|||
</div>
|
||||
}
|
||||
size="small"
|
||||
show={!loading && filteredSites.size === 0}
|
||||
show={!loading && filteredSites.length === 0}
|
||||
>
|
||||
<div className="grid grid-cols-12 gap-2 w-full items-center px-5 py-3 font-medium">
|
||||
<div className="col-span-4">Project Name</div>
|
||||
|
|
@ -160,7 +165,7 @@ const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
|
|||
<div className="w-full flex items-center justify-center py-10">
|
||||
<Pagination
|
||||
page={page}
|
||||
total={filteredSites.size}
|
||||
total={filteredSites.length}
|
||||
onPageChange={(page) => updatePage(page)}
|
||||
limit={pageSize}
|
||||
/>
|
||||
|
|
@ -181,18 +186,10 @@ const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
|
|||
};
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
site: state.getIn(['site', 'instance']),
|
||||
sites: state.getIn(['site', 'list']),
|
||||
loading: state.getIn(['site', 'loading']),
|
||||
user: state.getIn(['user', 'account']),
|
||||
account: state.getIn(['user', 'account']),
|
||||
});
|
||||
|
||||
const connector = connect(mapStateToProps, {
|
||||
init,
|
||||
remove,
|
||||
fetchGDPR,
|
||||
setSiteId,
|
||||
});
|
||||
const connector = connect(mapStateToProps, null);
|
||||
|
||||
export default connector(withPageTitle('Projects - OpenReplay Preferences')(Sites));
|
||||
export default connector(withPageTitle('Projects - OpenReplay Preferences')(observer(Sites)));
|
||||
|
|
|
|||
|
|
@ -1,32 +1,21 @@
|
|||
import React from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { withSiteId } from 'App/routes';
|
||||
import { setSiteId } from 'Duck/site';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from "App/mstore";
|
||||
|
||||
export default BaseComponent => {
|
||||
@withRouter
|
||||
@connect((state, props) => ({
|
||||
urlSiteId: props.match.params.siteId,
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
}), {
|
||||
setSiteId,
|
||||
})
|
||||
class WrappedClass extends React.PureComponent {
|
||||
push = (location) => {
|
||||
const { history, siteId } = this.props;
|
||||
if (typeof location === 'string') {
|
||||
history.push(withSiteId(location, siteId));
|
||||
} else if (typeof location === 'object') {
|
||||
history.push({ ...location, pathname: withSiteId(location.pathname, siteId) });
|
||||
}
|
||||
}
|
||||
export default BaseComponent => withRouter(observer((props) => {
|
||||
const { history, ...other } = props
|
||||
const { projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId
|
||||
|
||||
render() {
|
||||
const { history, ...other } = this.props
|
||||
|
||||
return <BaseComponent {...other} history={{ ...history, push: this.push }} />
|
||||
const push = (location) => {
|
||||
if (typeof location === 'string') {
|
||||
history.push(withSiteId(location, siteId));
|
||||
} else if (typeof location === 'object') {
|
||||
history.push({ ...location, pathname: withSiteId(location.pathname, siteId) });
|
||||
}
|
||||
}
|
||||
return WrappedClass
|
||||
}
|
||||
|
||||
return <BaseComponent {...other} history={{ ...history, push: push }} />
|
||||
}))
|
||||
|
|
@ -1,40 +1,39 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { setSiteId } from 'Duck/site';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useStore } from "App/mstore";
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
export default (BaseComponent) => {
|
||||
@connect((state, props) => ({
|
||||
urlSiteId: props.match.params.siteId,
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
}), {
|
||||
setSiteId,
|
||||
})
|
||||
class WrapperClass extends React.PureComponent {
|
||||
state = { load: false }
|
||||
constructor(props) {
|
||||
super(props);
|
||||
if (props.urlSiteId && props.urlSiteId !== props.siteId) {
|
||||
props.setSiteId(props.urlSiteId);
|
||||
const withSiteIdUpdater = (BaseComponent) => {
|
||||
const WrapperComponent = (props) => {
|
||||
const { projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const setSiteId = projectsStore.setSiteId;
|
||||
const urlSiteId = props.match.params.siteId
|
||||
const prevSiteIdRef = useRef(props.siteId);
|
||||
|
||||
useEffect(() => {
|
||||
if (urlSiteId && urlSiteId !== siteId) {
|
||||
props.setSiteId(urlSiteId);
|
||||
}
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
const { urlSiteId, siteId, location: { pathname }, history } = this.props;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const { location: { pathname }, history } = props;
|
||||
|
||||
const shouldUrlUpdate = urlSiteId && parseInt(urlSiteId, 10) !== parseInt(siteId, 10);
|
||||
if (shouldUrlUpdate) {
|
||||
const path = ['', siteId].concat(pathname.split('/').slice(2)).join('/');
|
||||
history.push(path);
|
||||
}
|
||||
const shouldBaseComponentReload = shouldUrlUpdate || siteId !== prevProps.siteId;
|
||||
if (shouldBaseComponentReload) {
|
||||
this.setState({ load: true });
|
||||
setTimeout(() => this.setState({ load: false }), 0);
|
||||
}
|
||||
}
|
||||
prevSiteIdRef.current = siteId;
|
||||
}, [urlSiteId, siteId, props.location.pathname, props.history]);
|
||||
|
||||
render() {
|
||||
return this.state.load ? null : <BaseComponent {...this.props} />;
|
||||
}
|
||||
}
|
||||
const key = props.siteId;
|
||||
|
||||
return WrapperClass
|
||||
}
|
||||
const passedProps = { ...props, siteId, setSiteId, urlSiteId };
|
||||
return <BaseComponent key={key} {...passedProps} />;
|
||||
};
|
||||
|
||||
return observer(WrapperComponent);
|
||||
};
|
||||
|
||||
export default withSiteIdUpdater;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
|
||||
import { useStore, withStore } from 'App/mstore';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { hasSiteId, siteChangeAvailable } from 'App/routes';
|
||||
import NewSiteForm from 'Components/Client/Sites/NewSiteForm';
|
||||
import { useModal } from 'Components/Modal';
|
||||
|
|
@ -27,18 +28,19 @@ interface Site {
|
|||
}
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
sites: Site[];
|
||||
siteId: string;
|
||||
setSiteId: (siteId: string) => void;
|
||||
clearSearch: (isSession: boolean) => void;
|
||||
clearSearchLive: () => void;
|
||||
initProject: (data: any) => void;
|
||||
mstore: any;
|
||||
account: any;
|
||||
}
|
||||
|
||||
function ProjectDropdown(props: Props) {
|
||||
const { sites, siteId, location, account } = props;
|
||||
const mstore = useStore();
|
||||
const { projectsStore } = mstore;
|
||||
const sites = projectsStore.list;
|
||||
const siteId = projectsStore.siteId;
|
||||
const setSiteId = projectsStore.setSiteId;
|
||||
const initProject = projectsStore.initProject;
|
||||
const { location, account } = props;
|
||||
const isAdmin = account.admin || account.superAdmin;
|
||||
const activeSite = sites.find((s) => s.id === siteId);
|
||||
const showCurrent =
|
||||
|
|
@ -47,21 +49,20 @@ function ProjectDropdown(props: Props) {
|
|||
const { customFieldStore } = useStore();
|
||||
|
||||
const handleSiteChange = async (newSiteId: string) => {
|
||||
props.setSiteId(newSiteId); // Fixed: should set the new siteId, not the existing one
|
||||
setSiteId(newSiteId); // Fixed: should set the new siteId, not the existing one
|
||||
await customFieldStore.fetchList(newSiteId)
|
||||
props.clearSearch(location.pathname.includes('/sessions'));
|
||||
props.clearSearchLive();
|
||||
|
||||
props.mstore.initClient();
|
||||
mstore.initClient();
|
||||
};
|
||||
|
||||
const addProjectClickHandler = () => {
|
||||
props.initProject({});
|
||||
initProject({});
|
||||
showModal(<NewSiteForm onClose={hideModal} />, { right: true });
|
||||
};
|
||||
|
||||
// @ts-ignore immutable
|
||||
const menuItems = sites.toJS().map((site) => ({
|
||||
const menuItems = sites.map((site) => ({
|
||||
key: site.id,
|
||||
label: (
|
||||
<div
|
||||
|
|
@ -142,16 +143,12 @@ function ProjectDropdown(props: Props) {
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
sites: state.getIn(['site', 'list']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
account: state.getIn(['user', 'account']),
|
||||
});
|
||||
|
||||
export default withRouter(
|
||||
connect(mapStateToProps, {
|
||||
setSiteId,
|
||||
clearSearch,
|
||||
clearSearchLive,
|
||||
initProject,
|
||||
})(withStore(ProjectDropdown))
|
||||
})(observer(ProjectDropdown))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,24 +4,19 @@ import SideMenu from 'App/layout/SideMenu';
|
|||
import TopHeader from 'App/layout/TopHeader';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { init as initSite } from 'Duck/site';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
|
||||
const { Sider, Content } = AntLayout;
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
hideHeader?: boolean;
|
||||
siteId?: string;
|
||||
initSite: (site: any) => void;
|
||||
sites: any[];
|
||||
}
|
||||
|
||||
function Layout(props: Props) {
|
||||
const { hideHeader, siteId } = props;
|
||||
const { hideHeader } = props;
|
||||
const isPlayer = /\/(session|assist|view-spot)\//.test(window.location.pathname);
|
||||
const { settingsStore } = useStore();
|
||||
const { settingsStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
|
||||
return (
|
||||
<AntLayout style={{ minHeight: '100vh' }}>
|
||||
|
|
@ -29,7 +24,7 @@ function Layout(props: Props) {
|
|||
<TopHeader />
|
||||
)}
|
||||
<AntLayout>
|
||||
{!hideHeader && !window.location.pathname.includes('/onboarding/') && (
|
||||
{!hideHeader && !window.location.pathname.includes('/onboarding/') ? (
|
||||
<Sider
|
||||
style={{
|
||||
position: 'sticky',
|
||||
|
|
@ -41,9 +36,9 @@ function Layout(props: Props) {
|
|||
collapsed={settingsStore.menuCollapsed}
|
||||
width={250}
|
||||
>
|
||||
<SideMenu siteId={siteId} isCollapsed={settingsStore.menuCollapsed} />
|
||||
<SideMenu siteId={siteId!} isCollapsed={settingsStore.menuCollapsed} />
|
||||
</Sider>
|
||||
)}
|
||||
) : null}
|
||||
<Content style={{ padding: isPlayer ? '0' : '20px', minHeight: 'calc(100vh - 60px)' }}>
|
||||
{props.children}
|
||||
</Content>
|
||||
|
|
@ -52,7 +47,4 @@ function Layout(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
sites: state.getIn(['site', 'list'])
|
||||
}), { initSite })(observer(Layout));
|
||||
export default observer(Layout);
|
||||
|
|
|
|||
|
|
@ -1,28 +1,26 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import Logo from 'App/layout/Logo';
|
||||
import TopRight from 'App/layout/TopRight';
|
||||
import { Layout, Space, Tooltip } from 'antd';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Icon } from 'UI';
|
||||
import { observer, useObserver } from 'mobx-react-lite';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { INDEXES } from 'App/constants/zindex';
|
||||
import { connect } from 'react-redux';
|
||||
import { logout } from 'Duck/user';
|
||||
import { init as initSite } from 'Duck/site';
|
||||
|
||||
const { Header } = Layout;
|
||||
|
||||
interface Props {
|
||||
account: any;
|
||||
siteId: string;
|
||||
initSite: (site: any) => void;
|
||||
}
|
||||
|
||||
function TopHeader(props: Props) {
|
||||
const { settingsStore } = useStore();
|
||||
|
||||
const { account, siteId } = props;
|
||||
const { userStore, notificationStore } = useStore();
|
||||
const { account } = props;
|
||||
const { userStore, notificationStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const initialDataFetched = userStore.initialDataFetched;
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -74,12 +72,10 @@ function TopHeader(props: Props) {
|
|||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
account: state.getIn(['user', 'account']),
|
||||
siteId: state.getIn(['site', 'siteId'])
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
onLogoutClick: logout,
|
||||
initSite
|
||||
};
|
||||
|
||||
export default connect(
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ import UserMenu from 'Components/Header/UserMenu/UserMenu';
|
|||
import GettingStartedProgress from 'Shared/GettingStarted/GettingStartedProgress';
|
||||
import ProjectDropdown from 'Shared/ProjectDropdown';
|
||||
import { getScope } from "../duck/user";
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
interface Props {
|
||||
account: any;
|
||||
siteId: any;
|
||||
sites: any;
|
||||
spotOnly?: boolean;
|
||||
}
|
||||
|
||||
function TopRight(props: Props) {
|
||||
const { projectsStore } = useStore();
|
||||
const { account } = props;
|
||||
// @ts-ignore
|
||||
return (
|
||||
<Space style={{ lineHeight: '0' }}>
|
||||
{props.spotOnly ? null : (
|
||||
|
|
@ -52,9 +52,7 @@ function mapStateToProps(state: any) {
|
|||
return {
|
||||
account: state.getIn(['user', 'account']),
|
||||
spotOnly: getScope(state) === 1,
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
sites: state.getIn(['site', 'list']),
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(TopRight);
|
||||
export default connect(mapStateToProps)(observer(TopRight));
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ export class RootStore {
|
|||
services.forEach((service) => {
|
||||
service.initClient(client);
|
||||
});
|
||||
client.setSiteIdCheck(this.projectsStore.getSiteId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,12 @@
|
|||
import Dashboard from "App/mstore/types/dashboard";
|
||||
import APIClient from 'App/api_client';
|
||||
import BaseService from "./BaseService";
|
||||
import Widget from "App/mstore/types/widget";
|
||||
|
||||
export default class DashboardService {
|
||||
private client: APIClient;
|
||||
|
||||
constructor(client?: APIClient) {
|
||||
this.client = client ? client : new APIClient();
|
||||
}
|
||||
|
||||
initClient(client?: APIClient) {
|
||||
this.client = client || new APIClient();
|
||||
}
|
||||
|
||||
export default class DashboardService extends BaseService {
|
||||
/**
|
||||
* Get all widgets from a dashboard.
|
||||
* @param dashboardId Required
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
getWidgets(dashboardId: string): Promise<any> {
|
||||
return this.client.get(`/dashboards/${dashboardId}/widgets`)
|
||||
|
|
@ -34,10 +24,10 @@ export default class DashboardService {
|
|||
.then(response => response.json())
|
||||
.then(response => response.data || []);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a dashboard by dashboardId.
|
||||
* @param dashboardId
|
||||
* @param dashboardId
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
getDashboard(dashboardId: string): Promise<any> {
|
||||
|
|
@ -66,9 +56,9 @@ export default class DashboardService {
|
|||
|
||||
/**
|
||||
* Add a widget to a dashboard.
|
||||
* @param dashboard
|
||||
* @param metricIds
|
||||
* @returns
|
||||
* @param dashboard
|
||||
* @param metricIds
|
||||
* @returns
|
||||
*/
|
||||
addWidget(dashboard: Dashboard, metricIds: any): Promise<any> {
|
||||
const data = dashboard.toJson()
|
||||
|
|
@ -80,7 +70,7 @@ export default class DashboardService {
|
|||
|
||||
/**
|
||||
* Delete a dashboard.
|
||||
* @param dashboardId
|
||||
* @param dashboardId
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
deleteDashboard(dashboardId: string): Promise<any> {
|
||||
|
|
@ -89,7 +79,7 @@ export default class DashboardService {
|
|||
|
||||
|
||||
/**
|
||||
* Create a new Meitrc, if the dashboardId is not provided,
|
||||
* Create a new Meitrc, if the dashboardId is not provided,
|
||||
* it will add the metric to the dashboard.
|
||||
* @param metric Required
|
||||
* @param dashboardId Optional
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue