Add Rematch

This commit is contained in:
Nikita Nek Dudnik
2020-05-07 14:31:21 +02:00
parent c8e3b72adc
commit 7f00512d93
7 changed files with 130 additions and 67 deletions
+3
View File
@@ -28,11 +28,14 @@
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@rematch/core": "^1.4.0",
"@types/react-lazylog": "^4.5.0",
"@types/react-redux": "^7.1.8",
"circleci-api": "^4.0.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-lazylog": "^4.5.2",
"react-redux": "^7.2.0",
"react-router": "^5.1.2",
"react-use": "^13.0.0"
},
+9 -33
View File
@@ -1,41 +1,17 @@
import { Route } from 'react-router';
import React from 'react';
import { BuildsPage } from 'pages/BuildsPage';
import { DetailedViewPage } from 'pages/DetailedViewPage';
// import { BuildsPage } from 'pages/BuildsPage';
// import { DetailedViewPage } from 'pages/DetailedViewPage';
import { SettingsPage } from 'pages/SettingsPage';
type AppState = {
token: string;
owner: string;
repo: string;
};
type AppAction =
| { type: 'setToken'; payload: string }
| { type: 'setOwner'; payload: string }
| { type: 'setRepo'; payload: string };
const initialState: AppState = { token: '', owner: '', repo: '' };
function reducer(state: AppState, action: AppAction) {
switch (action.type) {
case 'setToken':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
const Context = React.createContext(42);
import { Provider } from 'react-redux';
import store from 'state/store';
export const App = () => {
return (
<Context.Provider value={42}>
<Route path="/" component={BuildsPage} />
<Route path="/build/:buildId" component={DetailedViewPage} />
<Route path="/settings" component={SettingsPage} />
</Context.Provider>
<Provider store={store}>
{/* <Route path="/" component={BuildsPage} />
<Route path="/build/:buildId" component={DetailedViewPage} /> */}
<Route path="*" component={SettingsPage} />
</Provider>
);
};
@@ -1,9 +1,8 @@
import React, { useState, useEffect } from 'react';
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Button, TextField, List, Grid, ListItem } from '@material-ui/core';
import { circleCIApiRef } from 'api';
import {
InfoCard,
useApi,
Content,
ContentHeader,
SupportButton,
@@ -12,30 +11,35 @@ import {
} from '@backstage/core';
import { Link as RouterLink } from 'react-router-dom';
import { Layout } from 'components/Layout';
import { SettingsState } from 'state/models/settings';
import { iRootState } from 'state/store';
import { Dispatch } from '../../state/store';
export const SettingsPage = () => {
const api = useApi(circleCIApiRef);
const apiGitInfo = api.options.vcs;
const [authed, setAuthed] = React.useState(api.authed);
const [token, setToken] = React.useState(api.token);
const { token, owner, repo } = useSelector(
(state: iRootState): SettingsState => state.settings,
);
React.useEffect(() => {
api
.restorePersistedSettings()
.then(() => api.validateToken())
.then(() => setAuthed(true))
.catch(() => setAuthed(false));
}, []);
const dispatch: Dispatch = useDispatch();
const [owner, setOwner] = useState('');
const [repo, setRepo] = useState('');
// const api = useApi(circleCIApiRef);
// const apiGitInfo = api.options.vcs;
const [authed] = React.useState(false);
useEffect(() => {
if (apiGitInfo && apiGitInfo.owner !== owner && apiGitInfo.owner)
setOwner(apiGitInfo.owner);
if (apiGitInfo && apiGitInfo.repo !== repo && apiGitInfo.repo)
setRepo(apiGitInfo.repo);
}, [apiGitInfo]);
// React.useEffect(() => {
// api
// .restorePersistedSettings()
// .then(() => api.validateToken())
// .then(() => setAuthed(true))
// .catch(() => setAuthed(false));
// }, []);
// useEffect(() => {
// if (apiGitInfo && apiGitInfo.owner !== owner && apiGitInfo.owner)
// setOwner(apiGitInfo.owner);
// if (apiGitInfo && apiGitInfo.repo !== repo && apiGitInfo.repo)
// setRepo(apiGitInfo.repo);
// }, [apiGitInfo]);
return (
<Layout>
@@ -59,10 +63,9 @@ export const SettingsPage = () => {
<ListItem>
<TextField
name="circleci-token"
type="password"
label="Token"
value={token}
onChange={(e) => setToken(e.target.value)}
onChange={e => dispatch.settings.setToken(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -70,7 +73,7 @@ export const SettingsPage = () => {
name="circleci-owner"
label="Owner"
value={owner}
onChange={(e) => setOwner(e.target.value)}
// onChange={(e) => setOwner(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -78,7 +81,7 @@ export const SettingsPage = () => {
name="circleci-repo"
label="Repo"
value={repo}
onChange={(e) => setRepo(e.target.value)}
// onChange={(e) => setRepo(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -87,12 +90,12 @@ export const SettingsPage = () => {
variant="outlined"
color="primary"
onClick={async () => {
api.setVCSOptions({ owner, repo });
api.setToken(token);
api
.validateToken()
.then(() => setAuthed(true))
.catch(() => setAuthed(false));
// api.setVCSOptions({ owner, repo });
// api.setToken(token);
// api
// .validateToken()
// .then(() => setAuthed(true))
// .catch(() => setAuthed(false));
}}
>
Save credentials
@@ -0,0 +1,8 @@
import { settings } from './settings';
// no need to extend from Models
export interface RootModel {
settings: typeof settings;
}
export const models: RootModel = { settings };
@@ -0,0 +1,36 @@
// import { Dispatch } from '../store'
export type SettingsState = {
token: string;
owner: string;
repo: string;
};
export const settings = {
state: {
token: '!!!',
owner: '',
repo: '',
}, // initial state
reducers: {
// handle state changes with pure functions
setToken(state: SettingsState, payload: string) {
return { ...state, token: payload };
},
setOwner(state: SettingsState, payload: string) {
return { ...state, owner: payload };
},
setRepo(state: SettingsState, payload: string) {
return { ...state, repo: payload };
},
},
// effects:
// (dispatch: Dispatch) => ({
// // handle state changes with impure functions.
// // use async/await for async actions
// // async incrementAsync(payload, rootState) {
// // await new Promise(resolve => setTimeout(resolve, 1000))
// // dispatch.count.increment(payload)
// // },
// }),
};
+12
View File
@@ -0,0 +1,12 @@
import { init, RematchRootState, RematchDispatch } from '@rematch/core';
import { models, RootModel } from './models';
const store = init({
models,
});
export type Store = typeof store;
export type Dispatch = RematchDispatch<RootModel>;
export type iRootState = RematchRootState<RootModel>;
export default store;
+27 -2
View File
@@ -2740,6 +2740,13 @@
prop-types "^15.6.1"
react-lifecycles-compat "^3.0.4"
"@rematch/core@^1.4.0":
version "1.4.0"
resolved "https://registry.npmjs.org/@rematch/core/-/core-1.4.0.tgz#686ce814e1cf125029c5e9fba23ef3ab7c3eb2a7"
integrity sha512-1zy9cTYxbvDHP0PwIL1QqkwagCEnqA0uWMmPf8v2BYvLi2OsxIfX1xiV+vCP3sdJAjjZ0b9+IbSmj0DL2MEgLQ==
dependencies:
redux "^4.0.5"
"@rollup/plugin-commonjs@^11.0.2":
version "11.0.2"
resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-11.0.2.tgz#837cc6950752327cb90177b608f0928a4e60b582"
@@ -4047,6 +4054,14 @@
resolved "https://registry.npmjs.org/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860"
integrity sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw==
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
"@types/html-minifier@*":
version "3.5.3"
resolved "https://registry.npmjs.org/@types/html-minifier/-/html-minifier-3.5.3.tgz#5276845138db2cebc54c789e0aaf87621a21e84f"
@@ -4290,6 +4305,16 @@
"@types/react" "*"
immutable ">=3.8.2"
"@types/react-redux@^7.1.8":
version "7.1.8"
resolved "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.8.tgz#3631feb559f7858d6ad9eea1d6ef41fa64fe7205"
integrity sha512-kpplH7Wg2SYU00sZVT98WBN0ou6QKrYcShRaW+5Vpe5l7bluKWJbWmAL+ieiso07OQzpcP5i1PeY3690640ZWg==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react-router-dom@^5.1.3":
version "5.1.3"
resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.3.tgz#b5d28e7850bd274d944c0fbbe5d57e6b30d71196"
@@ -17510,7 +17535,7 @@ react-popper@^1.3.6:
typed-styles "^0.0.7"
warning "^4.0.2"
react-redux@^7.0.3:
react-redux@^7.0.3, react-redux@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d"
integrity sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==
@@ -17976,7 +18001,7 @@ redeyed@~2.1.0:
dependencies:
esprima "~4.0.0"
redux@^4.0.1:
redux@^4.0.0, redux@^4.0.1, redux@^4.0.5:
version "4.0.5"
resolved "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f"
integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==