new batch for site -> projects
This commit is contained in:
parent
df20cd5333
commit
81ecbac892
14 changed files with 223 additions and 192 deletions
|
|
@ -10,6 +10,8 @@ import NotFoundPage from 'Shared/NotFoundPage';
|
|||
import { ModalProvider } from 'Components/Modal';
|
||||
import Layout from 'App/layout/Layout';
|
||||
import PublicRoutes from 'App/PublicRoutes';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
const components: any = {
|
||||
SessionPure: lazy(() => import('Components/Session/Session')),
|
||||
|
|
@ -41,8 +43,11 @@ interface Props {
|
|||
}
|
||||
|
||||
function IFrameRoutes(props: Props) {
|
||||
const { isJwt = false, isLoggedIn = false, loading, onboarding, sites, siteId, jwt } = props;
|
||||
const siteIdList: any = sites.map(({ id }) => id).toJS();
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const siteId = projectsStore.siteId;
|
||||
const { isJwt = false, isLoggedIn = false, loading, onboarding, jwt } = props;
|
||||
const siteIdList: any = sites.map(({ id }) => id);
|
||||
|
||||
if (isLoggedIn) {
|
||||
return (
|
||||
|
|
@ -75,11 +80,9 @@ function IFrameRoutes(props: Props) {
|
|||
export default connect((state: any) => ({
|
||||
changePassword: state.getIn(['user', 'account', 'changePassword']),
|
||||
onboarding: state.getIn(['user', 'onboarding']),
|
||||
sites: state.getIn(['site', 'list']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
jwt: state.getIn(['user', 'jwt']),
|
||||
tenantId: state.getIn(['user', 'account', 'tenantId']),
|
||||
isEnterprise:
|
||||
state.getIn(['user', 'account', 'edition']) === 'ee' ||
|
||||
state.getIn(['user', 'authDetails', 'edition']) === 'ee'
|
||||
}))(IFrameRoutes);
|
||||
}))(observer(IFrameRoutes));
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@ interface Props {
|
|||
permissionsMap: any;
|
||||
removeErrors: any;
|
||||
resetErrors: () => void;
|
||||
projectsMap: any;
|
||||
}
|
||||
|
||||
function Roles(props: Props) {
|
||||
const { roleStore } = useStore();
|
||||
const { roleStore, projectsStore } = useStore();
|
||||
const projectsMap = projectsStore.list.reduce((acc: any, p: any) => {
|
||||
acc[p.id] = p.name;
|
||||
return acc;
|
||||
}, {})
|
||||
const roles = roleStore.list;
|
||||
const loading = roleStore.loading;
|
||||
const init = roleStore.init;
|
||||
|
|
@ -36,7 +39,7 @@ function Roles(props: Props) {
|
|||
roleStore.permissions.forEach((p: any) => {
|
||||
permissionsMap[p.value] = p.text;
|
||||
});
|
||||
const { account, projectsMap } = props;
|
||||
const { account } = props;
|
||||
const { showModal, hideModal } = useModal();
|
||||
const isAdmin = account.admin || account.superAdmin;
|
||||
|
||||
|
|
@ -108,13 +111,8 @@ function Roles(props: Props) {
|
|||
|
||||
export default connect(
|
||||
(state: any) => {
|
||||
const projects = state.getIn(['site', 'list']);
|
||||
return {
|
||||
account: state.getIn(['user', 'account']),
|
||||
projectsMap: projects.reduce((acc: any, p: any) => {
|
||||
acc[p.id] = p.name;
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
}
|
||||
)(withPageTitle('Roles & Access - OpenReplay Preferences')(observer(Roles)));
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ interface Permission {
|
|||
|
||||
interface Props {
|
||||
closeModal: (toastMessage?: string) => void;
|
||||
projects: any[];
|
||||
permissionsMap: any;
|
||||
deleteHandler: (id: any) => Promise<void>;
|
||||
}
|
||||
|
||||
const RoleForm = (props: Props) => {
|
||||
const { roleStore } = useStore();
|
||||
const { roleStore, projectsStore } = useStore();
|
||||
const projects = projectsStore.list;
|
||||
const role = roleStore.instance;
|
||||
const saving = roleStore.loading;
|
||||
const { closeModal, permissionsMap, projects } = props;
|
||||
const { closeModal, permissionsMap } = props;
|
||||
const projectOptions = projects
|
||||
.filter(({ value }) => !role.projects.includes(value))
|
||||
.map((p: any) => ({
|
||||
|
|
@ -217,12 +217,7 @@ const RoleForm = (props: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default connect((state: any) => {
|
||||
const projects = state.getIn(['site', 'list']);
|
||||
return {
|
||||
projects,
|
||||
};
|
||||
})(observer(RoleForm));
|
||||
export default observer(RoleForm);
|
||||
|
||||
function OptionLabel(nameMap: any, p: any, onChangeOption: (e: any) => void) {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -3,22 +3,18 @@ import React, { ChangeEvent, FormEvent, useEffect, useState } from 'react';
|
|||
import { ConnectedProps, connect } from 'react-redux';
|
||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { withStore } from 'App/mstore';
|
||||
import { clearSearch as clearSearchLive } from 'Duck/liveSearch';
|
||||
import { clearSearch } from 'Duck/search';
|
||||
import { edit, fetchList, remove, save, update } from 'Duck/site';
|
||||
import { setSiteId } from 'Duck/site';
|
||||
import { pushNewSite } from 'Duck/user';
|
||||
import { Button, Form, Icon, Input, SegmentSelection } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import styles from './siteForm.module.css';
|
||||
|
||||
type OwnProps = {
|
||||
onClose: (arg: any) => void;
|
||||
mstore: any;
|
||||
canDelete: boolean;
|
||||
};
|
||||
|
||||
type PropsFromRedux = ConnectedProps<typeof connector>;
|
||||
|
|
@ -26,36 +22,35 @@ type PropsFromRedux = ConnectedProps<typeof connector>;
|
|||
type Props = PropsFromRedux & RouteComponentProps & OwnProps;
|
||||
|
||||
const NewSiteForm = ({
|
||||
site,
|
||||
loading,
|
||||
save,
|
||||
remove,
|
||||
edit,
|
||||
update,
|
||||
pushNewSite,
|
||||
fetchList,
|
||||
setSiteId,
|
||||
clearSearch,
|
||||
clearSearchLive,
|
||||
location: { pathname },
|
||||
onClose,
|
||||
mstore,
|
||||
activeSiteId,
|
||||
canDelete,
|
||||
}: Props) => {
|
||||
const mstore = useStore();
|
||||
const { projectsStore } = mstore;
|
||||
const activeSiteId = projectsStore.active?.id
|
||||
const site = projectsStore.instance;
|
||||
const siteList = projectsStore.list;
|
||||
const loading = projectsStore.loading;
|
||||
const canDelete = siteList.length > 1;
|
||||
const setSiteId = projectsStore.setSiteId;
|
||||
const saveProject = projectsStore.save;
|
||||
const fetchList = projectsStore.fetchList;
|
||||
const [existsError, setExistsError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (pathname.includes('onboarding')) {
|
||||
if (pathname.includes('onboarding') && site?.id) {
|
||||
setSiteId(site.id);
|
||||
}
|
||||
if (!site) projectsStore.initProject({});
|
||||
}, []);
|
||||
|
||||
const onSubmit = (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (site.exists()) {
|
||||
update(site, site.id).then((response: any) => {
|
||||
if (site?.id && site.exists()) {
|
||||
projectsStore.updateProject( site.id, site.toData()).then((response: any) => {
|
||||
if (!response || !response.errors || response.errors.size === 0) {
|
||||
onClose(null);
|
||||
if (!pathname.includes('onboarding')) {
|
||||
|
|
@ -67,7 +62,7 @@ const NewSiteForm = ({
|
|||
}
|
||||
});
|
||||
} else {
|
||||
save(site).then((response: any) => {
|
||||
saveProject(site!).then((response: any) => {
|
||||
if (!response || !response.errors || response.errors.size === 0) {
|
||||
onClose(null);
|
||||
clearSearch();
|
||||
|
|
@ -89,8 +84,9 @@ const NewSiteForm = ({
|
|||
confirmButton: 'Yes, delete',
|
||||
cancelButton: 'Cancel',
|
||||
})
|
||||
&& site?.id
|
||||
) {
|
||||
remove(site.id).then(() => {
|
||||
projectsStore.removeProject(site.id).then(() => {
|
||||
onClose(null);
|
||||
if (site.id === activeSiteId) {
|
||||
setSiteId(null);
|
||||
|
|
@ -103,9 +99,12 @@ const NewSiteForm = ({
|
|||
target: { name, value },
|
||||
}: ChangeEvent<HTMLInputElement>) => {
|
||||
setExistsError(false);
|
||||
edit({ [name]: value });
|
||||
projectsStore.editInstance({ [name]: value });
|
||||
};
|
||||
|
||||
if (!site) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className="bg-white h-screen overflow-y-auto"
|
||||
|
|
@ -116,7 +115,7 @@ const NewSiteForm = ({
|
|||
</h3>
|
||||
<Form
|
||||
className={styles.formWrapper}
|
||||
onSubmit={site.validate() && onSubmit}
|
||||
onSubmit={site.validate && onSubmit}
|
||||
>
|
||||
<div className={styles.content}>
|
||||
<Form.Field>
|
||||
|
|
@ -146,7 +145,7 @@ const NewSiteForm = ({
|
|||
]}
|
||||
value={site.platform}
|
||||
onChange={(value) => {
|
||||
edit({ platform: value });
|
||||
projectsStore.editInstance({ platform: value });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -157,9 +156,9 @@ const NewSiteForm = ({
|
|||
type="submit"
|
||||
className="float-left mr-2"
|
||||
loading={loading}
|
||||
disabled={!site.validate()}
|
||||
disabled={!site.validate}
|
||||
>
|
||||
{site.exists() ? 'Update' : 'Add'}
|
||||
{site?.exists() ? 'Update' : 'Add'}
|
||||
</Button>
|
||||
{site.exists() && (
|
||||
<Button
|
||||
|
|
@ -183,26 +182,11 @@ const NewSiteForm = ({
|
|||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
activeSiteId: state.getIn(['site', 'active', 'id']),
|
||||
site: state.getIn(['site', 'instance']),
|
||||
siteList: state.getIn(['site', 'list']),
|
||||
loading:
|
||||
state.getIn(['site', 'save', 'loading']) ||
|
||||
state.getIn(['site', 'remove', 'loading']),
|
||||
canDelete: state.getIn(['site', 'list']).size > 1,
|
||||
});
|
||||
|
||||
const mapStateToProps = null;
|
||||
const connector = connect(mapStateToProps, {
|
||||
save,
|
||||
remove,
|
||||
edit,
|
||||
update,
|
||||
pushNewSite,
|
||||
fetchList,
|
||||
setSiteId,
|
||||
clearSearch,
|
||||
clearSearchLive,
|
||||
});
|
||||
|
||||
export default connector(withRouter(withStore(NewSiteForm)));
|
||||
export default connector(withRouter(observer(NewSiteForm)));
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
|||
|
||||
import DashboardEditModal from '../DashboardEditModal';
|
||||
|
||||
function DashboardList({ siteId }: { siteId: string }) {
|
||||
function DashboardList() {
|
||||
const { dashboardStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const [focusTitle, setFocusedInput] = React.useState(true);
|
||||
const [showEditModal, setShowEditModal] = React.useState(false);
|
||||
|
||||
const { dashboardStore } = useStore();
|
||||
const list = dashboardStore.filteredList;
|
||||
const dashboardsSearch = dashboardStore.filter.query;
|
||||
const history = useHistory();
|
||||
|
|
@ -219,6 +220,4 @@ function DashboardList({ siteId }: { siteId: string }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
}))(observer(DashboardList));
|
||||
export default observer(DashboardList);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import { Modal } from 'antd';
|
|||
import React, { useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import colors from 'tailwindcss/colors';
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import CreateCard from 'Components/Dashboard/components/DashboardList/NewDashModal/CreateCard';
|
||||
|
||||
import SelectCard from './SelectCard';
|
||||
|
|
@ -12,7 +13,6 @@ interface NewDashboardModalProps {
|
|||
open: boolean;
|
||||
isAddingFromLibrary?: boolean;
|
||||
isEnterprise?: boolean;
|
||||
isMobile?: boolean;
|
||||
}
|
||||
|
||||
const NewDashboardModal: React.FC<NewDashboardModalProps> = ({
|
||||
|
|
@ -20,8 +20,9 @@ const NewDashboardModal: React.FC<NewDashboardModalProps> = ({
|
|||
open,
|
||||
isAddingFromLibrary = false,
|
||||
isEnterprise = false,
|
||||
isMobile = false,
|
||||
}) => {
|
||||
const { projectsStore } = useStore();
|
||||
const isMobile = projectsStore.isMobile;
|
||||
const [step, setStep] = React.useState<number>(0);
|
||||
const [selectedCategory, setSelectedCategory] =
|
||||
React.useState<string>('product-analytics');
|
||||
|
|
@ -75,10 +76,9 @@ const NewDashboardModal: React.FC<NewDashboardModalProps> = ({
|
|||
};
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
isMobile: state.getIn(['site', 'instance', 'platform']) === 'ios',
|
||||
isEnterprise:
|
||||
state.getIn(['user', 'account', 'edition']) === 'ee' ||
|
||||
state.getIn(['user', 'account', 'edition']) === 'msaas',
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(NewDashboardModal);
|
||||
export default connect(mapStateToProps)(observer(NewDashboardModal));
|
||||
|
|
|
|||
|
|
@ -1,29 +1,26 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { Button, TagBadge } from 'UI';
|
||||
import { connect } from 'react-redux';
|
||||
import CustomFieldForm from '../../../Client/CustomFields/CustomFieldForm';
|
||||
import { confirm } from 'UI';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
interface MetadataListProps {
|
||||
site: { id: string };
|
||||
}
|
||||
|
||||
const MetadataList: React.FC<MetadataListProps> = (props) => {
|
||||
const { site } = props;
|
||||
const { customFieldStore } = useStore();
|
||||
const MetadataList = () => {
|
||||
const { customFieldStore, projectsStore } = useStore();
|
||||
const site = projectsStore.instance;
|
||||
const fields = customFieldStore.list;
|
||||
|
||||
const { showModal, hideModal } = useModal();
|
||||
|
||||
useEffect(() => {
|
||||
customFieldStore.fetchList(site.id);
|
||||
}, [site.id]);
|
||||
customFieldStore.fetchList(site?.id);
|
||||
}, [site?.id]);
|
||||
|
||||
const save = (field: any) => {
|
||||
customFieldStore.save(site.id, field).then((response) => {
|
||||
if (!site) return;
|
||||
customFieldStore.save(site.id!, field).then((response) => {
|
||||
if (!response || !response.errors || response.errors.size === 0) {
|
||||
hideModal();
|
||||
toast.success('Metadata added successfully!');
|
||||
|
|
@ -62,11 +59,4 @@ const MetadataList: React.FC<MetadataListProps> = (props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
site: state.getIn(['site', 'instance']),
|
||||
fields: state.getIn(['customFields', 'list']).sortBy((i: any) => i.index),
|
||||
field: state.getIn(['customFields', 'instance']),
|
||||
loading: state.getIn(['customFields', 'fetchRequest', 'loading'])
|
||||
})
|
||||
)(MetadataList);
|
||||
export default observer(MetadataList);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { useStore } from 'App/mstore';
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { multiview, liveSession, withSiteId } from 'App/routes';
|
||||
import { connect } from 'react-redux';
|
||||
import { PlayerContext, ILivePlayerContext } from 'App/components/Session/playerContext';
|
||||
|
||||
interface ITab {
|
||||
|
|
@ -44,13 +43,14 @@ const CurrentTab = React.memo(() => (
|
|||
</Tab>
|
||||
));
|
||||
|
||||
function AssistTabs({ session, siteId }: { session: Record<string, any>; siteId: string }) {
|
||||
function AssistTabs({ session }: { session: Record<string, any> }) {
|
||||
const history = useHistory();
|
||||
const { store } = React.useContext(PlayerContext) as unknown as ILivePlayerContext
|
||||
const { recordingState, calling, remoteControl } = store.get()
|
||||
const isDisabled = recordingState !== 0 || calling !== 0 || remoteControl !== 0
|
||||
|
||||
const { assistMultiviewStore } = useStore();
|
||||
const { assistMultiviewStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId!;
|
||||
|
||||
const placeholder = new Array(4 - assistMultiviewStore.sessions.length).fill(0);
|
||||
|
||||
|
|
@ -91,6 +91,4 @@ function AssistTabs({ session, siteId }: { session: Record<string, any>; siteId:
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({ siteId: state.getIn(['site', 'siteId']) }))(
|
||||
observer(AssistTabs)
|
||||
);
|
||||
export default observer(AssistTabs);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { convertElementToImage } from 'App/utils';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { fileNameFormat } from 'App/utils';
|
||||
import { toast } from 'react-toastify';
|
||||
import { forceVisible } from 'react-lazyload';
|
||||
|
|
@ -15,11 +14,11 @@ interface Props {
|
|||
export default function withReport<P extends Props>(WrappedComponent: React.ComponentType<P>) {
|
||||
const ComponentWithReport = (props: P) => {
|
||||
const [rendering, setRendering] = React.useState(false);
|
||||
const { site } = props;
|
||||
const { dashboardStore } = useStore();
|
||||
const dashboard: any = useObserver(() => dashboardStore.selectedDashboard);
|
||||
const period = useObserver(() => dashboardStore.period);
|
||||
const pendingRequests = useObserver(() => dashboardStore.pendingRequests);
|
||||
const { dashboardStore, projectsStore } = useStore();
|
||||
const site = projectsStore.instance;
|
||||
const dashboard: any = dashboardStore.selectedDashboard;
|
||||
const period = dashboardStore.period;
|
||||
const pendingRequests = dashboardStore.pendingRequests;
|
||||
|
||||
useEffect(() => {
|
||||
if (rendering && pendingRequests <= 0) {
|
||||
|
|
@ -181,7 +180,5 @@ export default function withReport<P extends Props>(WrappedComponent: React.Comp
|
|||
);
|
||||
};
|
||||
|
||||
return connect((state: any) => ({
|
||||
site: state.getIn(['site', 'instance']),
|
||||
}))(ComponentWithReport);
|
||||
return observer(ComponentWithReport);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ import { toggleFavorite } from 'Duck/sessions';
|
|||
import SessionDateRange from './SessionDateRange';
|
||||
import RecordingStatus from 'Shared/SessionsTabOverview/components/RecordingStatus';
|
||||
import { sessionService } from 'App/services';
|
||||
import { updateProjectRecordingStatus } from 'Duck/site';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
enum NoContentType {
|
||||
Bookmarked,
|
||||
|
|
@ -50,17 +51,18 @@ interface Props extends RouteComponentProps {
|
|||
updateCurrentPage: (page: number) => void;
|
||||
setScrollPosition: (scrollPosition: number) => void;
|
||||
fetchSessions: (filters: any, force: boolean) => void;
|
||||
updateProjectRecordingStatus: (siteId: string, status: boolean) => void;
|
||||
activeTab: any;
|
||||
isEnterprise?: boolean;
|
||||
checkForLatestSessions: () => void;
|
||||
toggleFavorite: (sessionId: string) => Promise<void>;
|
||||
sites: object[];
|
||||
isLoggedIn: boolean;
|
||||
siteId: string;
|
||||
}
|
||||
|
||||
function SessionList(props: Props) {
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const siteId = projectsStore.siteId;
|
||||
const updateProjectRecordingStatus = projectsStore.updateProjectRecordingStatus;
|
||||
const [noContentType, setNoContentType] = React.useState<NoContentType>(NoContentType.ToDate);
|
||||
const {
|
||||
loading,
|
||||
|
|
@ -73,9 +75,7 @@ function SessionList(props: Props) {
|
|||
metaList,
|
||||
activeTab,
|
||||
isEnterprise = false,
|
||||
sites,
|
||||
isLoggedIn,
|
||||
siteId
|
||||
} = props;
|
||||
const _filterKeys = filters.map((i: any) => i.key);
|
||||
const hasUserFilter =
|
||||
|
|
@ -139,7 +139,7 @@ function SessionList(props: Props) {
|
|||
}
|
||||
|
||||
if (statusData.status === 2 && activeSite) { // recording && processed
|
||||
props.updateProjectRecordingStatus(activeSite.id, true);
|
||||
updateProjectRecordingStatus(activeSite.id, true);
|
||||
props.fetchSessions(null, true);
|
||||
clearInterval(sessionStatusTimeOut);
|
||||
}
|
||||
|
|
@ -293,8 +293,6 @@ export default connect(
|
|||
activeTab: state.getIn(['search', 'activeTab']),
|
||||
pageSize: state.getIn(['search', 'pageSize']),
|
||||
isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
sites: state.getIn(['site', 'list']),
|
||||
isLoggedIn: Boolean(state.getIn(['user', 'jwt'])),
|
||||
}),
|
||||
{
|
||||
|
|
@ -304,6 +302,5 @@ export default connect(
|
|||
fetchSessions,
|
||||
checkForLatestSessions,
|
||||
toggleFavorite,
|
||||
updateProjectRecordingStatus
|
||||
}
|
||||
)(withRouter(SessionList));
|
||||
)(withRouter(observer(SessionList)));
|
||||
|
|
|
|||
|
|
@ -1,77 +1,81 @@
|
|||
import React from "react";
|
||||
import stl from "./NoSessionPermission.module.css";
|
||||
import { Icon, Button } from "UI";
|
||||
import { connect } from "react-redux";
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import {
|
||||
sessions as sessionsRoute,
|
||||
assist as assistRoute,
|
||||
withSiteId,
|
||||
} from "App/routes";
|
||||
import { withRouter, RouteComponentProps } from "react-router-dom";
|
||||
assist as assistRoute,
|
||||
sessions as sessionsRoute,
|
||||
withSiteId,
|
||||
} from 'App/routes';
|
||||
import { Button, Icon } from 'UI';
|
||||
|
||||
import stl from './NoSessionPermission.module.css';
|
||||
|
||||
const SESSIONS_ROUTE = sessionsRoute();
|
||||
const ASSIST_ROUTE = assistRoute();
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
session: any;
|
||||
siteId: string;
|
||||
history: any;
|
||||
sessionPath: any;
|
||||
isAssist: boolean;
|
||||
session: any;
|
||||
history: any;
|
||||
sessionPath: any;
|
||||
isAssist: boolean;
|
||||
}
|
||||
function NoSessionPermission(props: Props) {
|
||||
const { session, history, siteId, sessionPath, isAssist } = props;
|
||||
const { projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId!;
|
||||
const { session, history, sessionPath, isAssist } = props;
|
||||
|
||||
const backHandler = () => {
|
||||
if (
|
||||
sessionPath.pathname === history.location.pathname ||
|
||||
sessionPath.pathname.includes("/session/") ||
|
||||
isAssist
|
||||
) {
|
||||
history.push(
|
||||
withSiteId(isAssist ? ASSIST_ROUTE : SESSIONS_ROUTE, siteId)
|
||||
);
|
||||
} else {
|
||||
history.push(
|
||||
sessionPath
|
||||
? sessionPath.pathname + sessionPath.search
|
||||
: withSiteId(SESSIONS_ROUTE, siteId)
|
||||
);
|
||||
}
|
||||
};
|
||||
const backHandler = () => {
|
||||
if (
|
||||
sessionPath.pathname === history.location.pathname ||
|
||||
sessionPath.pathname.includes('/session/') ||
|
||||
isAssist
|
||||
) {
|
||||
history.push(
|
||||
withSiteId(isAssist ? ASSIST_ROUTE : SESSIONS_ROUTE, siteId)
|
||||
);
|
||||
} else {
|
||||
history.push(
|
||||
sessionPath
|
||||
? sessionPath.pathname + sessionPath.search
|
||||
: withSiteId(SESSIONS_ROUTE, siteId)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={stl.wrapper}>
|
||||
<Icon name="shield-lock" size="50" className="py-16" />
|
||||
<div className={stl.title}>Not allowed</div>
|
||||
{session.isLive ? (
|
||||
<span>
|
||||
This session is still live, and you don’t have the necessary
|
||||
permissions to access this feature. Please check with your
|
||||
admin.
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
You don’t have the necessary permissions to access this
|
||||
feature. Please check with your admin.
|
||||
</span>
|
||||
)}
|
||||
{/* <Link to="/"> */}
|
||||
<Button variant="primary" onClick={backHandler} className="mt-6">
|
||||
GO BACK
|
||||
</Button>
|
||||
{/* </Link> */}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={stl.wrapper}>
|
||||
<Icon name="shield-lock" size="50" className="py-16" />
|
||||
<div className={stl.title}>Not allowed</div>
|
||||
{session.isLive ? (
|
||||
<span>
|
||||
This session is still live, and you don’t have the necessary
|
||||
permissions to access this feature. Please check with your admin.
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
You don’t have the necessary permissions to access this feature.
|
||||
Please check with your admin.
|
||||
</span>
|
||||
)}
|
||||
{/* <Link to="/"> */}
|
||||
<Button variant="primary" onClick={backHandler} className="mt-6">
|
||||
GO BACK
|
||||
</Button>
|
||||
{/* </Link> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(
|
||||
connect((state: any) => {
|
||||
const isAssist = window.location.pathname.includes("/assist/");
|
||||
return {
|
||||
isAssist,
|
||||
session: state.getIn(["sessions", "current"]),
|
||||
siteId: state.getIn(["site", "siteId"]),
|
||||
sessionPath: state.getIn(["sessions", "sessionPath"]),
|
||||
};
|
||||
})(NoSessionPermission)
|
||||
connect((state: any) => {
|
||||
const isAssist = window.location.pathname.includes('/assist/');
|
||||
return {
|
||||
isAssist,
|
||||
session: state.getIn(['sessions', 'current']),
|
||||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
};
|
||||
})(observer(NoSessionPermission))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export default class ProjectsStore {
|
|||
siteId: string | null = null;
|
||||
active: Project | null = null;
|
||||
sitesLoading = false;
|
||||
loading = false;
|
||||
|
||||
constructor() {
|
||||
const storedSiteId = localStorage.getItem(SITE_ID_STORAGE_KEY);
|
||||
|
|
@ -17,6 +18,10 @@ export default class ProjectsStore {
|
|||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
get isMobile() {
|
||||
return this.instance ? ['ios', 'android'].includes(this.instance.platform) : false;
|
||||
}
|
||||
|
||||
getSiteId = () => {
|
||||
return {
|
||||
siteId: this.siteId,
|
||||
|
|
@ -32,6 +37,10 @@ export default class ProjectsStore {
|
|||
this.sitesLoading = loading;
|
||||
}
|
||||
|
||||
setLoading = (loading: boolean) => {
|
||||
this.loading = loading;
|
||||
}
|
||||
|
||||
setSiteId(siteId: string) {
|
||||
this.siteId = siteId;
|
||||
localStorage.setItem(SITE_ID_STORAGE_KEY, siteId.toString());
|
||||
|
|
@ -73,7 +82,7 @@ export default class ProjectsStore {
|
|||
}
|
||||
}
|
||||
|
||||
fetchList = async (siteIdFromPath: string) =>{
|
||||
fetchList = async (siteIdFromPath?: string) => {
|
||||
this.setSitesLoading(true);
|
||||
try {
|
||||
const response = await projectsService.fetchList();
|
||||
|
|
@ -87,8 +96,8 @@ export default class ProjectsStore {
|
|||
siteId = siteIdFromPath;
|
||||
} else if (!siteId || !siteExists) {
|
||||
siteId = siteIds.includes(this.siteId)
|
||||
? this.siteId
|
||||
: response.data[0].projectId;
|
||||
? this.siteId
|
||||
: response.data[0].projectId;
|
||||
}
|
||||
|
||||
const hasRecordings = this.list.some(site => site.recorded);
|
||||
|
|
@ -109,6 +118,7 @@ export default class ProjectsStore {
|
|||
}
|
||||
|
||||
save = async (projectData: Partial<Project>) => {
|
||||
this.setLoading(true);
|
||||
try {
|
||||
const response = await projectsService.saveProject(projectData);
|
||||
runInAction(() => {
|
||||
|
|
@ -124,6 +134,8 @@ export default class ProjectsStore {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to save site:', error);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,5 +151,39 @@ export default class ProjectsStore {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
removeProject = async (projectId: string) => {
|
||||
this.setLoading(true);
|
||||
try {
|
||||
await projectsService.removeProject(projectId);
|
||||
runInAction(() => {
|
||||
this.list = this.list.filter(site => site.id !== projectId);
|
||||
if (this.siteId === projectId) {
|
||||
this.setSiteId(this.list[0].id!);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('Failed to remove project:', e);
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
updateProject = async (projectId: string, projectData: Partial<Project>) => {
|
||||
this.setLoading(true);
|
||||
try {
|
||||
const response = await projectsService.updateProject(projectId, projectData);
|
||||
runInAction(() => {
|
||||
const updatedSite = new Project(response.data);
|
||||
const index = this.list.findIndex(site => site.id === updatedSite.id);
|
||||
if (index !== -1) {
|
||||
this.list[index] = updatedSite;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to update site:', error);
|
||||
} finally {
|
||||
this.setLoading
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ export default class Project {
|
|||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
exists = () => {
|
||||
return !!this.id;
|
||||
}
|
||||
|
||||
get validate() {
|
||||
return this.name.length > 0;
|
||||
}
|
||||
|
||||
edit = (data: Partial<Project>) => {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (key in this) {
|
||||
|
|
|
|||
|
|
@ -24,4 +24,16 @@ export default class ProjectsService extends BaseService {
|
|||
|
||||
return await r.json();
|
||||
}
|
||||
}
|
||||
|
||||
removeProject = async (projectId: string) => {
|
||||
const r = await this.client.delete(`/projects/${projectId}`)
|
||||
|
||||
return await r.json();
|
||||
}
|
||||
|
||||
updateProject = async (projectId: string, projectData: any) => {
|
||||
const r = await this.client.put(`/projects/${projectId}`, projectData);
|
||||
|
||||
return await r.json();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue