mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 15:47:55 +01:00
Add error exception
This commit is contained in:
parent
6115eeec26
commit
680a679a92
@ -8,7 +8,7 @@ import ForgotPasswordSuccessPage from './components/forgot-password-success-page
|
||||
import RegistationPage from './components/registration-page';
|
||||
import LoginPage from './components/login-page';
|
||||
import MapsPage from './components/maps-page';
|
||||
import store from "./store";
|
||||
import store from "./redux/store";
|
||||
import { ForgotPasswordPage } from './components/forgot-password-page';
|
||||
import { Provider } from 'react-redux';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
|
@ -13,7 +13,6 @@ export type Label = {
|
||||
iconName: string;
|
||||
}
|
||||
|
||||
|
||||
export type MapInfo = {
|
||||
id: number;
|
||||
starred: boolean;
|
||||
|
@ -1,18 +1,23 @@
|
||||
import axios from 'axios';
|
||||
import { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label } from '..';
|
||||
import MockClient from '../mock-client/';
|
||||
import { useIntl } from 'react-intl';
|
||||
import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label } from '..';
|
||||
|
||||
//@Remove inheritance once is it completed.
|
||||
export default class RestClient extends MockClient {
|
||||
export default class RestClient implements Client {
|
||||
private baseUrl: string;
|
||||
private authFailed: () => void
|
||||
private sessionExpired: () => void
|
||||
|
||||
constructor(baseUrl: string, authFailed: () => void) {
|
||||
super();
|
||||
|
||||
constructor(baseUrl: string, sessionExpired: () => void) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.sessionExpired = sessionExpired;
|
||||
}
|
||||
|
||||
fetchMapInfo(id: number): Promise<BasicMapInfo> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
private parseResponseOnError = (response: any): ErrorInfo => {
|
||||
const intl = useIntl();
|
||||
|
||||
let result: ErrorInfo | undefined;
|
||||
if (response) {
|
||||
@ -22,7 +27,9 @@ export default class RestClient extends MockClient {
|
||||
|
||||
switch (status) {
|
||||
case 401:
|
||||
// this.authFailed();
|
||||
case 302:
|
||||
this.sessionExpired();
|
||||
result = { msg: intl.formatMessage({ id: "expired.title", defaultMessage: "Your current session has expired. Please, sign in and try again." })}
|
||||
break;
|
||||
default:
|
||||
if (data) {
|
||||
|
@ -8,7 +8,7 @@ import Footer from '../layout/footer'
|
||||
import FormContainer from '../layout/form-container';
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useMutation } from 'react-query'
|
||||
import { activeInstance } from '../../reducers/serviceSlice'
|
||||
import { activeInstance } from '../../redux/clientSlice'
|
||||
import Input from '../form/input'
|
||||
import GlobalError from '../form/global-error'
|
||||
import SubmitButton from '../form/submit-button'
|
||||
|
@ -6,7 +6,7 @@ import { FormControl } from '@material-ui/core';
|
||||
|
||||
|
||||
import Client, { BasicMapInfo, ErrorInfo } from '../../../../client';
|
||||
import { activeInstance } from '../../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../../redux/clientSlice';
|
||||
import Input from '../../../form/input';
|
||||
import BaseDialog from '../base-dialog';
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { useSelector } from "react-redux";
|
||||
import Client from "../../../../client";
|
||||
import { activeInstance } from '../../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../../redux/clientSlice';
|
||||
import { DialogProps, fetchMapById, handleOnMutationSuccess } from "..";
|
||||
import BaseDialog from "../base-dialog";
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { FormControl } from "@material-ui/core";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import Client, { BasicMapInfo, ErrorInfo } from "../../../../client";
|
||||
import { activeInstance } from '../../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../../redux/clientSlice';
|
||||
import Input from "../../../form/input";
|
||||
import { DialogProps, fetchMapById } from "..";
|
||||
import BaseDialog from "../base-dialog";
|
||||
|
@ -6,7 +6,7 @@ import { ErrorInfo, MapInfo } from '../../../client';
|
||||
import Client from '../../../client';
|
||||
import { useSelector } from "react-redux";
|
||||
import { QueryClient, useQuery } from 'react-query';
|
||||
import { activeInstance } from '../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../redux/clientSlice';
|
||||
import DuplicateDialog from './duplicate-dialog';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import CreateDialog from './create-dialog';
|
||||
@ -49,8 +49,6 @@ const ActionDispatcher = (props: ActionDialogProps) => {
|
||||
</span >
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
type MapLoadResult = {
|
||||
isLoading: boolean,
|
||||
error: ErrorInfo | null,
|
||||
|
@ -3,7 +3,7 @@ import { useIntl } from "react-intl";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { useSelector } from "react-redux";
|
||||
import Client, { BasicMapInfo, ErrorInfo } from "../../../../client";
|
||||
import { activeInstance } from '../../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../../redux/clientSlice';
|
||||
import { DialogProps, fetchMapById, handleOnMutationSuccess } from "..";
|
||||
import Input from "../../../form/input";
|
||||
import { FormControl } from "@material-ui/core";
|
||||
|
@ -9,15 +9,16 @@ import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import { useStyles } from './style';
|
||||
import { AccountCircle, AcUnitTwoTone, AddCircleTwoTone, CloudUploadTwoTone, DeleteOutlineTwoTone, EmailOutlined, EmojiPeopleOutlined, ExitToAppOutlined, FeedbackOutlined, Help, LabelTwoTone, PeopleAltTwoTone, PersonAddTwoTone, PersonOutlineTwoTone, PersonTwoTone, PolicyOutlined, PublicTwoTone, SettingsApplicationsOutlined, ShareTwoTone, StarTwoTone } from '@material-ui/icons';
|
||||
import { Button, Link, ListItemSecondaryAction, ListItemText, Menu, MenuItem, Tooltip } from '@material-ui/core';
|
||||
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Link, ListItemSecondaryAction, ListItemText, Menu, MenuItem, Tooltip } from '@material-ui/core';
|
||||
import { MapsList } from './maps-list';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
||||
import { activeInstance } from '../../reducers/serviceSlice';
|
||||
import { activeInstance, activeInstanceStatus, ClientStatus } from '../../redux/clientSlice';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Client, { Label } from '../../client';
|
||||
import ActionDispatcher from './action-dispatcher';
|
||||
import { ActionType } from './action-chooser';
|
||||
import { Alert, AlertTitle } from '@material-ui/lab';
|
||||
|
||||
const logoIcon = require('../../images/logo-small.svg');
|
||||
const poweredByIcon = require('../../images/pwrdby-white.svg');
|
||||
@ -46,12 +47,10 @@ const MapsPage = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const [activeDialog, setActiveDialog] = React.useState<ActionType | undefined>(undefined);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
document.title = 'Maps | WiseMapping';
|
||||
}, []);
|
||||
|
||||
|
||||
const mutation = useMutation(
|
||||
(id: number) => client.deleteLabel(id),
|
||||
{
|
||||
@ -106,6 +105,7 @@ const MapsPage = () => {
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<HandleClientStatus/>
|
||||
<AppBar
|
||||
position="fixed"
|
||||
className={clsx(classes.appBar, {
|
||||
@ -238,6 +238,46 @@ const StyleListItem = (props: ListItemProps) => {
|
||||
);
|
||||
}
|
||||
|
||||
const HandleClientStatus = () => {
|
||||
const status: ClientStatus = useSelector(activeInstanceStatus);
|
||||
|
||||
const handleOnClose = () => {
|
||||
window.location.href = '/c/login';
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Dialog
|
||||
open={status.state != 'healthy'}
|
||||
onClose={handleOnClose}
|
||||
maxWidth="sm"
|
||||
fullWidth={true}>
|
||||
|
||||
<DialogTitle>
|
||||
<FormattedMessage id="expired.title" defaultMessage="Your session has expired" />
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent>
|
||||
<Alert severity="error">
|
||||
<AlertTitle><FormattedMessage id="expired.title" defaultMessage="Your current session has expired. Please, sign in and try again." /></AlertTitle>
|
||||
</Alert>
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions>
|
||||
<Button
|
||||
type="button"
|
||||
color="primary"
|
||||
size="medium"
|
||||
onClick={handleOnClose} >
|
||||
<FormattedMessage id="action.close-button" defaultMessage="Close" />
|
||||
</Button>
|
||||
</DialogActions>
|
||||
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ProfileToobarButton = () => {
|
||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
const open = Boolean(anchorEl);
|
||||
|
@ -18,7 +18,7 @@ import StarRateRoundedIcon from '@material-ui/icons/StarRateRounded';
|
||||
import MoreHorizIcon from '@material-ui/icons/MoreHoriz';
|
||||
import { CSSProperties } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { activeInstance } from '../../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../../redux/clientSlice';
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||
import { ErrorInfo, MapInfo } from '../../../client';
|
||||
import Client from '../../../client';
|
||||
@ -30,6 +30,7 @@ import moment from 'moment'
|
||||
import { Filter, LabelFilter } from '..';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { DeleteOutlined, LabelTwoTone } from '@material-ui/icons';
|
||||
import Alert from '@material-ui/lab/Alert';
|
||||
|
||||
|
||||
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
|
||||
@ -162,7 +163,7 @@ const mapsFilter = (filter: Filter, search: string): ((mapInfo: MapInfo) => bool
|
||||
result = mapInfo.starred;
|
||||
break;
|
||||
case 'owned':
|
||||
//@todo: complete ...
|
||||
//@todo: complete ...
|
||||
|
||||
result = mapInfo.starred;
|
||||
break;
|
||||
@ -398,7 +399,7 @@ export const MapsList = (props: MapsListProps) => {
|
||||
{isLoading ? (
|
||||
<TableRow><TableCell colSpan={6}>Loading ...</TableCell></TableRow>) :
|
||||
(mapsInfo.length == 0 ?
|
||||
(<TableRow><TableCell colSpan={6} style={{ textAlign: 'center' }}><FormattedMessage id="maps.emptyresult" defaultMessage="No matching record found with the current filter criteria." /></TableCell></TableRow>) :
|
||||
(<TableRow><TableCell colSpan={6} style={{ textAlign: 'center' }}><FormattedMessage id="maps.empty-result" defaultMessage="No matching record found with the current filter criteria." /></TableCell></TableRow>) :
|
||||
stableSort(mapsInfo, getComparator(order, orderBy))
|
||||
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
|
||||
.map((row: MapInfo) => {
|
||||
@ -479,3 +480,9 @@ export const MapsList = (props: MapsListProps) => {
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
const ErrorDialog = (props) => {
|
||||
|
||||
return (<Alert severity="error">This is an error alert — check it out!</Alert>);
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ import Footer from '../layout/footer';
|
||||
import { FormControl, Typography } from '@material-ui/core';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useMutation } from 'react-query';
|
||||
import { activeInstance } from '../../reducers/serviceSlice';
|
||||
import { activeInstance } from '../../redux/clientSlice';
|
||||
import Input from '../form/input';
|
||||
import GlobalError from '../form/global-error';
|
||||
import SubmitButton from '../form/submit-button';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import axios from 'axios';
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import Client from '../client';
|
||||
import MockClient from '../client/mock-client';
|
||||
import RestClient from '../client/rest-client';
|
||||
@ -25,7 +24,7 @@ class RutimeConfig {
|
||||
buildClient(): Client {
|
||||
let result: Client;
|
||||
if (this.config) {
|
||||
result = new RestClient(this.config.apiBaseUrl, () => { console.log("401 error") });
|
||||
result = new RestClient(this.config.apiBaseUrl, () => { sessionExpired() });
|
||||
console.log("Service using rest client. " + JSON.stringify(this.config))
|
||||
|
||||
} else {
|
||||
@ -36,27 +35,40 @@ class RutimeConfig {
|
||||
}
|
||||
}
|
||||
|
||||
interface ServiceState {
|
||||
instance: Client;
|
||||
export interface ClientStatus {
|
||||
state: 'healthy' | 'session-expired';
|
||||
msg?: string
|
||||
|
||||
}
|
||||
|
||||
const initialState: ServiceState = {
|
||||
instance: new RutimeConfig().load().buildClient()
|
||||
export interface ClientState {
|
||||
instance: Client;
|
||||
status: ClientStatus;
|
||||
}
|
||||
|
||||
const initialState: ClientState = {
|
||||
instance: new RutimeConfig().load().buildClient(),
|
||||
status: { state: 'healthy' }
|
||||
};
|
||||
|
||||
export const serviceSlice = createSlice({
|
||||
name: "service",
|
||||
export const clientSlice = createSlice({
|
||||
name: "client",
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
initialize(state, action: PayloadAction<void[]>) {
|
||||
// state.instance = new RutimeConfig().load().buildClient()
|
||||
sessionExpired(state, action: PayloadAction<void>) {
|
||||
state.status = { state: 'session-expired', msg: 'Sessions has expired. You need to login again.' }
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const activeInstance = (state: any): Client => {
|
||||
return state.service.instance;
|
||||
return state.client.instance;
|
||||
}
|
||||
|
||||
export default serviceSlice.reducer
|
||||
export const activeInstanceStatus = (state: any): ClientStatus => {
|
||||
return state.client.status;
|
||||
}
|
||||
|
||||
export const { sessionExpired } = clientSlice.actions;
|
||||
export default clientSlice.reducer;
|
||||
|
12
packages/webapp/src/redux/store.ts
Normal file
12
packages/webapp/src/redux/store.ts
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import clientReducer from './clientSlice';
|
||||
|
||||
// Create Service object...
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
client: clientReducer
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
@ -1,12 +0,0 @@
|
||||
|
||||
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
|
||||
import serviceReducer from './reducers/serviceSlice';
|
||||
|
||||
// Create Service object...
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
service: serviceReducer
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
Loading…
Reference in New Issue
Block a user