ui: fix spot list header behavior, change spot login flow?

This commit is contained in:
nick-delirium 2024-09-13 15:54:17 +02:00
parent bc46a6910f
commit 69b3f7cdf4
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
6 changed files with 49 additions and 35 deletions

View file

@ -10,21 +10,19 @@ import {
GLOBAL_DESTINATION_PATH,
IFRAME,
JWT_PARAM,
SPOT_ONBOARDING
} from "App/constants/storageKeys";
SPOT_ONBOARDING,
} from 'App/constants/storageKeys';
import Layout from 'App/layout/Layout';
import { withStore } from "App/mstore";
import { checkParam, handleSpotJWT, isTokenExpired } from "App/utils";
import { withStore } from 'App/mstore';
import { checkParam, handleSpotJWT, isTokenExpired } from 'App/utils';
import { ModalProvider } from 'Components/Modal';
import { ModalProvider as NewModalProvider } from 'Components/ModalContext';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { setSessionPath } from 'Duck/sessions';
import { fetchList as fetchSiteList } from 'Duck/site';
import { init as initSite } from 'Duck/site';
import { fetchUserInfo, getScope, setJwt, logout } from "Duck/user";
import { fetchTenants } from 'Duck/user';
import { fetchUserInfo, getScope, logout, setJwt } from 'Duck/user';
import { Loader } from 'UI';
import { spotsList } from "./routes";
import * as routes from './routes';
interface RouterProps
@ -36,7 +34,6 @@ interface RouterProps
changePassword: boolean;
isEnterprise: boolean;
fetchUserInfo: () => any;
fetchTenants: () => any;
setSessionPath: (path: any) => any;
fetchSiteList: (siteId?: number) => any;
match: {
@ -45,7 +42,7 @@ interface RouterProps
};
};
mstore: any;
setJwt: (params: { jwt: string, spotJwt: string | null }) => any;
setJwt: (params: { jwt: string; spotJwt: string | null }) => any;
fetchMetadata: (siteId: string) => void;
initSite: (site: any) => void;
scopeSetup: boolean;
@ -68,15 +65,15 @@ const Router: React.FC<RouterProps> = (props) => {
logout,
} = props;
const params = new URLSearchParams(location.search)
const params = new URLSearchParams(location.search);
const spotCb = params.get('spotCallback');
const spotReqSent = React.useRef(false)
const spotReqSent = React.useRef(false);
const [isSpotCb, setIsSpotCb] = React.useState(false);
const [isIframe, setIsIframe] = React.useState(false);
const [isJwt, setIsJwt] = React.useState(false);
const handleJwtFromUrl = () => {
const params = new URLSearchParams(location.search)
const params = new URLSearchParams(location.search);
const urlJWT = params.get('jwt');
const spotJwt = params.get('spotJwt');
if (spotJwt) {
@ -92,6 +89,7 @@ const Router: React.FC<RouterProps> = (props) => {
return;
} else {
spotReqSent.current = true;
setIsSpotCb(false);
}
handleSpotJWT(jwt);
};
@ -107,13 +105,17 @@ const Router: React.FC<RouterProps> = (props) => {
const handleUserLogin = async () => {
if (isSpotCb) {
localStorage.setItem(SPOT_ONBOARDING, 'true')
localStorage.setItem(SPOT_ONBOARDING, 'true');
}
await fetchUserInfo();
const siteIdFromPath = parseInt(location.pathname.split('/')[1]);
await fetchSiteList(siteIdFromPath);
props.mstore.initClient();
if (localSpotJwt && !isTokenExpired(localSpotJwt)) {
handleSpotLogin(localSpotJwt);
}
const destinationPath = localStorage.getItem(GLOBAL_DESTINATION_PATH);
if (
destinationPath &&
@ -144,7 +146,7 @@ const Router: React.FC<RouterProps> = (props) => {
if (spotCb) {
setIsSpotCb(true);
}
}, [spotCb])
}, [spotCb]);
useEffect(() => {
handleDestinationPath();
@ -160,21 +162,19 @@ const Router: React.FC<RouterProps> = (props) => {
useEffect(() => {
if (scopeSetup) {
history.push(routes.scopeSetup())
history.push(routes.scopeSetup());
}
}, [scopeSetup])
}, [scopeSetup]);
useEffect(() => {
if (isLoggedIn && (location.pathname.includes('login') || isSpotCb)) {
if (localSpotJwt) {
if (!isTokenExpired(localSpotJwt)) {
handleSpotLogin(localSpotJwt);
} else {
logout();
}
if (isLoggedIn && isSpotCb) {
if (localSpotJwt && !isTokenExpired(localSpotJwt)) {
handleSpotLogin(localSpotJwt);
} else {
logout();
}
}
}, [isSpotCb, location, isLoggedIn, localSpotJwt])
}, [isSpotCb, location, isLoggedIn, localSpotJwt]);
useEffect(() => {
if (siteId && siteId !== lastFetchedSiteIdRef.current) {
@ -204,8 +204,7 @@ const Router: React.FC<RouterProps> = (props) => {
location.pathname.includes('multiview') ||
location.pathname.includes('/view-spot/') ||
location.pathname.includes('/spots/') ||
location.pathname.includes('/scope-setup')
location.pathname.includes('/scope-setup');
if (isIframe) {
return (
@ -238,8 +237,11 @@ const mapStateToProps = (state: Map<string, any>) => {
'loading',
]);
const sitesLoading = state.getIn(['site', 'fetchListRequest', 'loading']);
const scopeSetup = getScope(state) === 0
const loading = Boolean(userInfoLoading) || Boolean(sitesLoading) || (!scopeSetup && !siteId);
const scopeSetup = getScope(state) === 0;
const loading =
Boolean(userInfoLoading) ||
Boolean(sitesLoading) ||
(!scopeSetup && !siteId);
return {
siteId,
changePassword,
@ -262,7 +264,6 @@ const mapStateToProps = (state: Map<string, any>) => {
const mapDispatchToProps = {
fetchUserInfo,
fetchTenants,
setSessionPath,
fetchSiteList,
setJwt,

View file

@ -10,7 +10,7 @@ const SpotsListHeader = observer(
onDelete,
selectedCount,
onClearSelection,
isEmpty,
tenantHasSpots,
onRefresh,
}: {
onDelete: () => void;
@ -18,6 +18,7 @@ const SpotsListHeader = observer(
onClearSelection: () => void;
onRefresh: () => void;
isEmpty?: boolean;
tenantHasSpots: boolean;
}) => {
const { spotStore } = useStore();
@ -52,7 +53,7 @@ const SpotsListHeader = observer(
<ReloadButton buttonSize={'small'} onClick={onRefresh} iconSize={16} />
</div>
{isEmpty ? null : (
{tenantHasSpots ? null : (
<div className="flex gap-2 items-center">
<div className={'ml-auto'}>
{selectedCount > 0 && (

View file

@ -89,6 +89,7 @@ function SpotsList() {
selectedCount={selectedSpots.length}
onClearSelection={clearSelection}
isEmpty={isEmpty}
tenantHasSpots={spotStore.tenantHasSpots}
/>
</div>

View file

@ -1,10 +1,15 @@
import { makeAutoObservable } from 'mobx';
import { spotService } from 'App/services';
import { UpdateSpotRequest } from 'App/services/spotService';
import { Spot } from './types/spot';
export default class SpotStore {
isLoading: boolean = false;
spots: Spot[] = [];
@ -18,6 +23,7 @@ export default class SpotStore {
pubKey: { value: string; expiration: number } | null = null;
readonly order = 'desc';
accessError = false;
tenantHasSpots = false;
constructor() {
makeAutoObservable(this);
@ -81,13 +87,18 @@ export default class SpotStore {
limit: this.limit,
} as const;
const response = await this.withLoader(() =>
const { spots, tenantHasSpots, total } = await this.withLoader(() =>
spotService.fetchSpots(filters)
);
this.setSpots(response.spots.map((spot: any) => new Spot(spot)));
this.setTotal(response.total);
this.setSpots(spots.map((spot: any) => new Spot(spot)));
this.setTotal(total);
this.setTenantHasSpots(tenantHasSpots);
};
setTenantHasSpots(hasSpots: boolean) {
this.tenantHasSpots = hasSpots;
}
async fetchSpotById(id: string) {
try {
const response = await this.withLoader(() =>

View file

@ -33,6 +33,7 @@ interface AddCommentRequest {
interface GetSpotsResponse {
spots: SpotInfo[];
total: number;
tenantHasSpots: boolean;
}
interface GetSpotsRequest {

View file

@ -504,7 +504,6 @@ export function truncateStringToFit(string: string, screenWidth: number, charWid
let sendingRequest = false;
export const handleSpotJWT = (jwt: string) => {
console.log(jwt, sendingRequest)
let tries = 0;
if (!jwt || sendingRequest) {
return;