Compare commits

..
Author SHA1 Message Date
braginini 35656cd416 Rename getSilentAccessToken to accessToken for clarity 2022-08-20 20:21:04 +02:00
35 changed files with 696 additions and 2393 deletions

No files matched your search

+283 -270
View File
File diff suppressed because it is too large. Load diff
-1
View File
@@ -21,7 +21,6 @@
"antd": "^4.20.6",
"autoprefixer": "^10.4.4",
"axios": "^0.27.2",
"cidr-regex": "^3.1.1",
"copyfiles": "^2.4.1",
"heroicons": "^1.0.6",
"highlight.js": "^11.2.0",
+1 -3
View File
@@ -8,7 +8,6 @@ import SetupKeys from "./views/SetupKeys";
import AddPeer from "./views/AddPeer";
import Users from './views/Users';
import AccessControl from './views/AccessControl';
import Routes from './views/Routes';
import Banner from "./components/Banner";
import {store} from "./store";
import { Col, Layout, Row} from 'antd';
@@ -39,7 +38,7 @@ function App() {
return (
<Provider store={store}>
<Layout>
<Banner/>
{/*<Banner/>*/}
<Header className="header" style={{
display: "flex",
flexDirection: "column",
@@ -69,7 +68,6 @@ function App() {
<Route path="/add-peer" component={withOidcSecure(AddPeer)}/>
<Route path="/setup-keys" component={withOidcSecure(SetupKeys)}/>
<Route path="/acls" component={withOidcSecure(AccessControl)}/>
<Route path="/routes" component={withOidcSecure(Routes)}/>
<Route path="/users" component={withOidcSecure(Users)}/>
</Switch>
</Content>
+11 -2
View File
@@ -96,7 +96,7 @@ const AccessControlNew = () => {
form.validateFields()
.then((values) => {
const ruleToSave = createRuleToSave()
dispatch(ruleActions.saveRule.request({getAccessTokenSilently:accessToken, payload: ruleToSave}))
dispatch(ruleActions.saveRule.request({accessToken:accessToken, payload: ruleToSave}))
})
.catch((errorInfo) => {
console.log('errorInfo', errorInfo)
@@ -210,7 +210,7 @@ const AccessControlNew = () => {
// const testDeleteGroup = () => {
// groups.forEach(g => {
// dispatch(groupsActions.deleteGroup.request({getAccessTokenSilently, payload: g.ID || ''}))
// dispatch(groupsActions.deleteGroup.request({accessToken, payload: g.ID || ''}))
// })
// }
@@ -308,7 +308,14 @@ const AccessControlNew = () => {
<Form.Item
name="disabled"
label="Status"
//valuePropName="checked"
>
{/*<Switch
checkedChildren={<CheckOutlined />}
unCheckedChildren={<CloseOutlined />}
onChange={handleChangeDisabled}
/>*/}
<Radio.Group
options={optionsDisabledEnabled}
@@ -323,6 +330,7 @@ const AccessControlNew = () => {
name="tagSourceGroups"
label="Source groups"
rules={[{ validator: selectValidator }]}
style={{display: 'flex'}}
>
<Select mode="tags"
style={{ width: '100%' }}
@@ -344,6 +352,7 @@ const AccessControlNew = () => {
name="tagDestinationGroups"
label="Destination groups"
rules={[{ validator: selectValidator }]}
style={{display: 'flex'}}
>
<Select
mode="tags" style={{ width: '100%' }}
+3 -3
View File
@@ -14,7 +14,7 @@ const Banner = () => {
const linkLearnMore = () => {
return (
<a
href="https://netbird.io/docs/how-to-guides/network-routes"
href="https://netbird.io/blog/introducing-access-control"
className="font-bold underline"
target="_blank"
rel="noreferrer"
@@ -27,7 +27,7 @@ const Banner = () => {
<Row>
<Col xs={24} sm={0} lg={0}>
<Text className="ant-col-md-0" style={{color: "#ffffff"}}>
New Release! Access private networks with the Network Routes feature.
Big news! Introducing NetBird Access Control.
</Text>
</Col>
<Col xs={24} sm={0} lg={0}>
@@ -38,7 +38,7 @@ const Banner = () => {
<Col xs={0} sm={24}>
<Space align="center" style={{display: "flex", justifyContent: "center"}}>
<Text style={{color: "#ffffff"}}>
New Release! Access private networks with the Network Routes feature.
Big news! Introducing NetBird Access Control.
</Text>
<span>
{linkLearnMore()}
-1
View File
@@ -34,7 +34,6 @@ const Navbar = () => {
{ label: (<Link to="/add-peer">Add Peer</Link>), key: '/add-peer' },
{ label: (<Link to="/setup-keys">Setup Keys</Link>), key: '/setup-keys' },
{ label: (<Link to="/acls">Access Control</Link>), key: '/acls' },
{ label: (<Link to="/routes">Network Routes</Link>), key: '/routes' },
{ label: (<Link to="/users">Users</Link>), key: '/users' }
] as ItemType[])
const logoutWithRedirect = () =>
+3 -3
View File
@@ -213,11 +213,11 @@ const PeerUpdate = () => {
if (!noUpdateToName()) {
const peerUpdate = createPeerToSave()
setCallingPeerAPI(true)
dispatch(peerActions.updatePeer.request({getAccessTokenSilently:accessToken, payload: peerUpdate}))
dispatch(peerActions.updatePeer.request({accessToken:accessToken, payload: peerUpdate}))
}
if (peerGroupsToSave.groupsToRemove.length || peerGroupsToSave.groupsToAdd.length || peerGroupsToSave.groupsNoId.length) {
setCallingGroupAPI(true)
dispatch(peerActions.saveGroups.request({getAccessTokenSilently:accessToken, payload: peerGroupsToSave}))
dispatch(peerActions.saveGroups.request({accessToken:accessToken, payload: peerGroupsToSave}))
}
})
.catch((errorInfo) => {
@@ -295,7 +295,7 @@ const PeerUpdate = () => {
) : (
<Form.Item
name="name"
label="Name"
label="Update Name"
rules={[{
required: true,
message: 'Please add a new name for this peer',
-373
View File
@@ -1,373 +0,0 @@
import React, {useEffect, useRef, useState} from 'react';
import {useDispatch, useSelector} from "react-redux";
import {RootState} from "typesafe-actions";
import { actions as routeActions } from '../store/route';
import {
Col,
Row,
Input,
InputNumber,
Space,
Switch,
SelectProps,
Button, Drawer, Form, Divider, Select, Radio, Typography
} from "antd";
import {CloseOutlined, FlagFilled, QuestionCircleFilled} from "@ant-design/icons";
import {Route} from "../store/route/types";
import {Header} from "antd/es/layout/layout";
import {RuleObject} from "antd/lib/form";
import {useOidcAccessToken} from "@axa-fr/react-oidc";
import cidrRegex from 'cidr-regex';
import {
masqueradeDisabledMSG,
peerToPeerIP,
initPeerMaps,
routePeerSeparator,
transformGroupedDataTable
} from '../utils/routes'
const { Paragraph } = Typography;
interface FormRoute extends Route {
}
const RouteUpdate = () => {
const {accessToken} = useOidcAccessToken()
const dispatch = useDispatch()
const setupNewRouteVisible = useSelector((state: RootState) => state.route.setupNewRouteVisible)
const setupNewRouteHA = useSelector((state: RootState) => state.route.setupNewRouteHA)
const peers = useSelector((state: RootState) => state.peer.data)
const route = useSelector((state: RootState) => state.route.route)
const routes = useSelector((state: RootState) => state.route.data)
const savedRoute = useSelector((state: RootState) => state.route.savedRoute)
// const [groupedDataTable, setGroupedDataTable] = useState([] as GroupedDataTable[]);
const [previousRouteKey, setPreviousRouteKey] = useState("")
const [editName, setEditName] = useState(false)
const [editDescription, setEditDescription] = useState(false)
const options: SelectProps['options'] = [];
const [formRoute, setFormRoute] = useState({} as FormRoute)
const [form] = Form.useForm()
const inputNameRef = useRef<any>(null)
const inputDescriptionRef = useRef<any>(null)
const defaultRoutingPeerMSG = "Routing Peer"
const [routingPeerMSG, setRoutingPeerMSG] = useState(defaultRoutingPeerMSG)
const defaultMasqueradeMSG = "Masquerade"
const [masqueradeMSG, setMasqueradeMSG] = useState(defaultMasqueradeMSG)
const defaultStatusMSG = "Status"
const [statusMSG, setStatusMSG] = useState(defaultStatusMSG)
const [peerNameToIP, peerIPToName] = initPeerMaps(peers);
const optionsDisabledEnabled = [{label: 'Enabled', value: true}, {label: 'Disabled', value: false}]
useEffect(() => {
if (setupNewRouteHA) {
setRoutingPeerMSG("Add additional routing peer")
setMasqueradeMSG("Update Masquerade")
setStatusMSG("Update Status")
} else {
setRoutingPeerMSG(defaultRoutingPeerMSG)
setMasqueradeMSG(defaultMasqueradeMSG)
setStatusMSG(defaultStatusMSG)
setPreviousRouteKey("")
}
}, [setupNewRouteHA])
useEffect(() => {
if (editName) inputNameRef.current!.focus({
cursor: 'end',
});
}, [editName]);
useEffect(() => {
if (editDescription) inputDescriptionRef.current!.focus({
cursor: 'end',
});
}, [editDescription]);
useEffect(() => {
if (!route) return
const fRoute = {
...route,
} as FormRoute
setFormRoute(fRoute)
setPreviousRouteKey(fRoute.network_id+fRoute.network)
form.setFieldsValue(fRoute)
}, [route])
peers.forEach((p) => {
let os:string
os = p.os
if (!os.toLowerCase().startsWith("darwin") && !os.toLowerCase().startsWith("windows")) {
options?.push({
label: peerToPeerIP(p.name,p.ip),
value: peerToPeerIP(p.name,p.ip),
disabled: false
})
}
})
const createRouteToSave = (inputRoute:FormRoute):Route => {
let peerIDList = inputRoute.peer.split(routePeerSeparator)
let peerID:string
if (peerIDList[1]) {
peerID = peerIDList[1]
} else {
peerID = peerNameToIP[inputRoute.peer]
}
return {
id: inputRoute.id,
network: inputRoute.network,
network_id: inputRoute.network_id,
description: inputRoute.description,
peer: peerID,
enabled: inputRoute.enabled,
masquerade: inputRoute.masquerade,
metric: inputRoute.metric
} as Route
}
const handleFormSubmit = () => {
form.validateFields()
.then(() => {
if (!setupNewRouteHA || formRoute.peer != '') {
const routeToSave = createRouteToSave(formRoute)
dispatch(routeActions.saveRoute.request({getAccessTokenSilently:accessToken, payload: routeToSave}))
} else {
let groupedDataTable = transformGroupedDataTable(routes,peerIPToName)
groupedDataTable.forEach((group) => {
if (group.key == previousRouteKey) {
group.groupedRoutes.forEach((route) => {
let updateRoute:FormRoute = {
...formRoute,
id: route.id,
peer: route.peer,
metric: route.metric,
enabled: (formRoute.enabled != group.enabled) ? formRoute.enabled : route.enabled
}
const routeToSave = createRouteToSave(updateRoute)
dispatch(routeActions.saveRoute.request({getAccessTokenSilently:accessToken, payload: routeToSave}))
})
}
})
}
})
.catch((errorInfo) => {
console.log('errorInfo', errorInfo)
});
};
const setVisibleNewRoute = (status:boolean) => {
dispatch(routeActions.setSetupNewRouteVisible(status));
}
const setSetupNewRouteHA = (status:boolean) => {
dispatch(routeActions.setSetupNewRouteHA(status));
}
const onCancel = () => {
if (savedRoute.loading) return
setEditName(false)
dispatch(routeActions.setRoute({
network: '',
network_id: '',
description: '',
peer: "",
metric: 9999,
masquerade: false,
enabled: true
} as Route))
setVisibleNewRoute(false)
setSetupNewRouteHA(false)
setPreviousRouteKey("")
}
const onChange = (data:any) => {
setFormRoute({...formRoute, ...data})
}
const dropDownRender = (menu: React.ReactElement) => (
<>
{menu}
</>
)
const toggleEditName = (status:boolean) => {
setEditName(status);
}
const toggleEditDescription = (status:boolean) => {
setEditDescription(status);
}
const networkRangeValidator = (_: RuleObject, value: string) => {
if (!cidrRegex().test(value)) {
return Promise.reject(new Error("Please enter a valid CIDR, e.g. 192.168.1.0/24"))
}
if (Number(value.split("/")[1]) < 7) {
return Promise.reject(new Error("Please enter a network mask larger than /7"))
}
return Promise.resolve()
}
return (
<>
{route &&
<Drawer
headerStyle={{display: "none"}}
forceRender={true}
visible={setupNewRouteVisible}
bodyStyle={{paddingBottom: 80}}
onClose={onCancel}
autoFocus={true}
footer={
<Space style={{display: 'flex', justifyContent: 'end'}}>
<Button onClick={onCancel} disabled={savedRoute.loading}>Cancel</Button>
<Button type="primary" disabled={savedRoute.loading} onClick={handleFormSubmit}>{`${formRoute.network_id ? 'Save' : 'Create'}`}</Button>
</Space>
}
>
<Form layout="vertical" hideRequiredMark form={form} onValuesChange={onChange}>
<Row gutter={16}>
<Col span={24}>
<Header style={{margin: "-32px -24px 20px -24px", padding: "24px 24px 0 24px"}}>
<Row align="top">
<Col flex="none" style={{display: "flex"}}>
{!editName && !editDescription && formRoute.id &&
<button type="button" aria-label="Close" className="ant-drawer-close"
style={{paddingTop: 3}}
onClick={onCancel}>
<span role="img" aria-label="close" className="anticon anticon-close">
<CloseOutlined size={16}/>
</span>
</button>
}
</Col>
<Col flex="auto">
{ !editName && formRoute.id ? (
<div className={"access-control input-text ant-drawer-title"} onClick={() => toggleEditName(true)}>{formRoute.id ? formRoute.network_id : 'New Route'}</div>
) : (
<Form.Item
name="network_id"
label="Network Identifier"
tooltip="You can enable high-availability by assigning the same network identifier and network CIDR to multiple routes"
rules={[{required: true, message: 'Please add an identifier for this access route', whitespace: true}]}
>
<Input placeholder="e.g. aws-eu-central-1-vpc" ref={inputNameRef} disabled={!setupNewRouteHA} onPressEnter={() => toggleEditName(false)} onBlur={() => toggleEditName(false)} autoComplete="off" maxLength={40}/>
</Form.Item>
)}
{ !editDescription ? (
<div className={"access-control input-text ant-drawer-subtitle"} onClick={() => toggleEditDescription(true)}>{formRoute.description && formRoute.description.trim() !== "" ? formRoute.description : 'Add description...'}</div>
) : (
<Form.Item
name="description"
label="Description"
style={{marginTop: 24}}
>
<Input placeholder="Add description..." ref={inputDescriptionRef} disabled={!setupNewRouteHA} onPressEnter={() => toggleEditDescription(false)} onBlur={() => toggleEditDescription(false)} autoComplete="off" maxLength={200}/>
</Form.Item>
)}
</Col>
</Row>
<Row align="top">
<Col flex="auto">
</Col>
</Row>
</Header>
</Col>
<Col span={24}>
</Col>
<Col span={24}>
<Form.Item
name="network"
label="Network Range"
tooltip="Use CIDR notation. e.g. 192.168.10.0/24 or 172.16.0.0/16"
rules={[{validator: networkRangeValidator}]}
>
<Input placeholder="e.g. 172.16.0.0/16" disabled={!setupNewRouteHA} autoComplete="off" minLength={9} maxLength={43}/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
name="enabled"
label={statusMSG}
>
<Radio.Group
options={optionsDisabledEnabled}
optionType="button"
buttonStyle="solid"
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
name="peer"
label={routingPeerMSG}
tooltip="Assign a peer as a routing peer for the Network CIDR"
>
<Select
showSearch
style={{ width: '100%' }}
placeholder="Select Peer"
dropdownRender={dropDownRender}
options={options}
allowClear={true}
/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
name="masquerade"
label={masqueradeMSG}
tooltip={masqueradeDisabledMSG}
>
<Switch size={"small"} disabled={!setupNewRouteHA} checked={formRoute.masquerade}/>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
name="metric"
label="Metric"
tooltip="Choose from 1 to 9999. Lower number has higher priority"
>
<InputNumber min={1} max={9999} autoComplete="off"/>
</Form.Item>
</Col>
<Col span={24}>
<Row wrap={false} gutter={12}>
<Col flex="none">
<FlagFilled/>
</Col>
<Col flex="auto">
<Paragraph>
You can enable high-availability by assigning the same network identifier and network CIDR to multiple routes.
</Paragraph>
</Col>
</Row>
</Col>
<Col span={24}>
<Divider></Divider>
<Button icon={<QuestionCircleFilled/>} type="link" target="_blank"
href="https://netbird.io/docs/how-to-guides/network-routes" style={{color: 'rgb(07, 114, 128)'}}>Learn
more about network routes</Button>
</Col>
</Row>
</Form>
</Drawer>
}
</>
)
}
export default RouteUpdate
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -14,7 +14,7 @@ async function apiRequest<T>(params: ApiRequestParams): Promise<ApiResponse<T>>
const url = `${params.urlBase}${params.url}`;
const extraHeaders = params.extraHeaders || {};
const headers = await headersFactory((params.data as any).getAccessTokenSilently);
const headers = await headersFactory((params.data as any).accessToken);
const builtHeader: RequestHeader = { ...headers, ...extraHeaders };
+3 -8
View File
@@ -3,19 +3,14 @@ export interface RequestHeader {
[key: string]: unknown;
}
const headersFactory = async (getAccessTokenSilently:any): Promise<RequestHeader> => {
const headersFactory = async (accessToken:any): Promise<RequestHeader> => {
const headers: RequestHeader = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
//const token = await getLocalItem<string>(StorageKey.token);
//const token = ''
// const token = await getAccessTokenSilently()
const token = getAccessTokenSilently
if (token) {
headers.authorization = `Bearer ${token}`;
if (accessToken) {
headers.authorization = `Bearer ${accessToken}`;
}
return headers;
+1 -1
View File
@@ -1,7 +1,7 @@
import { Method } from 'axios';
export interface RequestPayload<T> {
getAccessTokenSilently: any | null;
accessToken: any | null;
payload:T;
}
-2
View File
@@ -7,7 +7,6 @@ import { sagas as setupKeySagas } from './setup-key';
import { sagas as userSagas } from './user';
import { sagas as ruleSagas } from './rule';
import { sagas as groupSagas } from './group';
import { sagas as routeSagas } from './route';
import rootReducer from './root-reducer';
import { apiClient } from '../services/api-client';
@@ -24,6 +23,5 @@ sagaMiddleware.run(setupKeySagas);
sagaMiddleware.run(userSagas);
sagaMiddleware.run(ruleSagas);
sagaMiddleware.run(groupSagas);
sagaMiddleware.run(routeSagas);
export { apiClient, rootReducer, store };
+5 -5
View File
@@ -118,13 +118,13 @@ export function* saveGroups(action: ReturnType<typeof actions.saveGroups.request
}
const responsesGroup = yield all(groupsToSave.map(g => call(serviceGroup.editGroup, {
getAccessTokenSilently: action.payload.getAccessTokenSilently,
accessToken: action.payload.accessToken,
payload: g
})
))
const responsesGroupNoId = yield all(groupsNoId.map(g => call(serviceGroup.createGroup, {
getAccessTokenSilently: action.payload.getAccessTokenSilently,
accessToken: action.payload.accessToken,
payload: g
})
))
@@ -137,8 +137,8 @@ export function* saveGroups(action: ReturnType<typeof actions.saveGroups.request
data: [...(responsesGroup as ApiResponse<Group>[]).map(r => r.body), ...(responsesGroupNoId as ApiResponse<Group>[]).map(r => r.body)]
} as CreateResponse<Group[] | null>))
yield put(groupActions.getGroups.request({ getAccessTokenSilently: action.payload.getAccessTokenSilently, payload: null }));
yield put(actions.getPeers.request({ getAccessTokenSilently: action.payload.getAccessTokenSilently, payload: null }));
yield put(groupActions.getGroups.request({ accessToken: action.payload.accessToken, payload: null }));
yield put(actions.getPeers.request({ accessToken: action.payload.accessToken, payload: null }));
} catch (err) {
console.log(err)
@@ -166,7 +166,7 @@ export function* updatePeer(action: ReturnType<typeof actions.updatePeer.request
const peerId = peer.id
const payloadToSave = {
getAccessTokenSilently: action.payload.getAccessTokenSilently,
accessToken: action.payload.accessToken,
payload: peer
}
+1 -9
View File
@@ -21,12 +21,4 @@ export interface PeerGroupsToSave {
groupsToRemove: string[];
groupsToAdd: string[];
groupsNoId: string[];
}
export interface PeerNameToIP {
[key: string]: string;
}
export interface PeerIPToName {
[key: string]: string;
}
}
+1 -3
View File
@@ -3,13 +3,11 @@ import { actions as SetupKeyActions } from './setup-key';
import { actions as UserActions } from './user';
import { actions as GroupActions } from './group';
import { actions as RuleActions } from './rule';
import { actions as RouteActions } from './route';
export default {
peer: PeerActions,
setupKey: SetupKeyActions,
user: UserActions,
group: GroupActions,
rule: RuleActions,
route: RouteActions
rule: RuleActions
};
+1 -3
View File
@@ -5,13 +5,11 @@ import { reducer as setupKey } from './setup-key';
import { reducer as user } from './user';
import { reducer as group } from './group';
import { reducer as rule } from './rule';
import { reducer as route } from './route';
export default combineReducers({
peer,
setupKey,
user,
group,
rule,
route
rule
});
-35
View File
@@ -1,35 +0,0 @@
import { ActionType, createAction, createAsyncAction } from 'typesafe-actions';
import {Route} from './types';
import {ApiError, CreateResponse, DeleteResponse, RequestPayload} from '../../services/api-client/types';
const actions = {
getRoutes: createAsyncAction(
'GET_ROUTES_REQUEST',
'GET_ROUTES_SUCCESS',
'GET_ROUTES_FAILURE',
)<RequestPayload<null>, Route[], ApiError>(),
saveRoute: createAsyncAction(
'SAVE_ROUTE_REQUEST',
'SAVE_ROUTE_SUCCESS',
'SAVE_ROUTE_FAILURE',
)<RequestPayload<Route>, CreateResponse<Route | null>, CreateResponse<Route | null>>(),
setSavedRoute: createAction('SET_CREATE_ROUTE')<CreateResponse<Route | null>>(),
resetSavedRoute: createAction('RESET_CREATE_ROUTE')<null>(),
deleteRoute: createAsyncAction(
'DELETE_ROUTE_REQUEST',
'DELETE_ROUTE_SUCCESS',
'DELETE_ROUTE_FAILURE'
)<RequestPayload<string>, DeleteResponse<string | null>, DeleteResponse<string | null>>(),
setDeletedRoute: createAction('SET_DELETED_ROUTE')<DeleteResponse<string | null>>(),
resetDeletedRoute: createAction('RESET_DELETED_ROUTE')<null>(),
removeRoute: createAction('REMOVE_ROUTE')<string>(),
setRoute: createAction('SET_ROUTE')<Route>(),
setSetupNewRouteVisible: createAction('SET_SETUP_NEW_ROUTE_VISIBLE')<boolean>(),
setSetupNewRouteHA: createAction('SET_SETUP_NEW_ROUTE_HA')<boolean>()
};
export type ActionTypes = ActionType<typeof actions>;
export default actions;
-7
View File
@@ -1,7 +0,0 @@
import actions, { ActionTypes as _actionTypes } from './actions';
import reducer from './reducer';
import sagas from './sagas';
export type ActionTypes = _actionTypes;
export { actions, reducer, sagas };
-95
View File
@@ -1,95 +0,0 @@
import { createReducer } from 'typesafe-actions';
import { combineReducers } from 'redux';
import { Route } from './types';
import actions, { ActionTypes } from './actions';
import {ApiError, DeleteResponse, CreateResponse} from "../../services/api-client/types";
type StateType = Readonly<{
data: Route[] | null;
route: Route | null;
loading: boolean;
failed: ApiError | null;
saving: boolean;
deleteRoute: DeleteResponse<string | null>;
savedRoute: CreateResponse<Route | null>;
setupNewRouteVisible: boolean;
setupNewRouteHA: boolean
}>;
const initialState: StateType = {
data: [],
route: null,
loading: false,
failed: null,
saving: false,
deleteRoute: <DeleteResponse<string | null>>{
loading: false,
success: false,
failure: false,
error: null,
data : null
},
savedRoute: <CreateResponse<Route | null>>{
loading: false,
success: false,
failure: false,
error: null,
data : null
},
setupNewRouteVisible: false,
setupNewRouteHA: false
};
const data = createReducer<Route[], ActionTypes>(initialState.data as Route[])
.handleAction(actions.getRoutes.success,(_, action) => action.payload)
.handleAction(actions.getRoutes.failure, () => []);
const route = createReducer<Route, ActionTypes>(initialState.route as Route)
.handleAction(actions.setRoute, (store, action) => action.payload);
const loading = createReducer<boolean, ActionTypes>(initialState.loading)
.handleAction(actions.getRoutes.request, () => true)
.handleAction(actions.getRoutes.success, () => false)
.handleAction(actions.getRoutes.failure, () => false);
const failed = createReducer<ApiError | null, ActionTypes>(initialState.failed)
.handleAction(actions.getRoutes.request, () => null)
.handleAction(actions.getRoutes.success, () => null)
.handleAction(actions.getRoutes.failure, (store, action) => action.payload);
const saving = createReducer<boolean, ActionTypes>(initialState.saving)
.handleAction(actions.getRoutes.request, () => true)
.handleAction(actions.getRoutes.success, () => false)
.handleAction(actions.getRoutes.failure, () => false);
const deletedRoute = createReducer<DeleteResponse<string | null>, ActionTypes>(initialState.deleteRoute)
.handleAction(actions.deleteRoute.request, () => initialState.deleteRoute)
.handleAction(actions.deleteRoute.success, (store, action) => action.payload)
.handleAction(actions.deleteRoute.failure, (store, action) => action.payload)
.handleAction(actions.setDeletedRoute, (store, action) => action.payload)
.handleAction(actions.resetDeletedRoute, () => initialState.deleteRoute)
const savedRoute = createReducer<CreateResponse<Route | null>, ActionTypes>(initialState.savedRoute)
.handleAction(actions.saveRoute.request, () => initialState.savedRoute)
.handleAction(actions.saveRoute.success, (store, action) => action.payload)
.handleAction(actions.saveRoute.failure, (store, action) => action.payload)
.handleAction(actions.setSavedRoute, (store, action) => action.payload)
.handleAction(actions.resetSavedRoute, () => initialState.savedRoute)
const setupNewRouteVisible = createReducer<boolean, ActionTypes>(initialState.setupNewRouteVisible)
.handleAction(actions.setSetupNewRouteVisible, (store, action) => action.payload)
const setupNewRouteHA = createReducer<boolean, ActionTypes>(initialState.setupNewRouteHA)
.handleAction(actions.setSetupNewRouteHA, (store, action) => action.payload)
export default combineReducers({
data,
route,
loading,
failed,
saving,
deletedRoute,
savedRoute,
setupNewRouteVisible,
setupNewRouteHA
});
Loaded 20 of 35 files, more files were not shown because too many files have changed in this diff. Show more