1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

Improved backend polling behavior

This commit is contained in:
Ewout Prangsma 2018-07-06 16:42:27 +02:00
parent f2274a58a0
commit 06bda8c7fe
No known key found for this signature in database
GPG key ID: 4DBAD380D93D0698
8 changed files with 131 additions and 49 deletions

View file

@ -2691,6 +2691,16 @@
"sha.js": "^2.4.8"
}
},
"create-react-class": {
"version": "15.6.3",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
"integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
"requires": {
"fbjs": "^0.8.9",
"loose-envify": "^1.3.1",
"object-assign": "^4.1.1"
}
},
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@ -10269,6 +10279,16 @@
}
}
},
"react-timeout": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/react-timeout/-/react-timeout-1.1.1.tgz",
"integrity": "sha512-zEJYHb3WvVq0/RdAOw5KHaOjTrN5Sm4fssJMPhqcu3efunecgQLfLfrKG5tfRM4IdjNJ3FCPI5hEKv62IHyZTw==",
"requires": {
"create-react-class": "^15.5.2",
"hoist-non-react-statics": "^2.3.1",
"object-assign": "^4.0.1"
}
},
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",

View file

@ -9,6 +9,7 @@
"react-dom": "^16.4.1",
"react-emotion": "^9.2.4",
"react-router-dom": "^4.3.1",
"react-timeout": "^1.1.1",
"semantic-ui-less": "^2.2.12",
"semantic-ui-react": "^0.81.3"
},

View file

@ -1,4 +1,5 @@
import React, { Component } from 'react';
import ReactTimeout from 'react-timeout';
import DeploymentOperator from './deployment/DeploymentOperator.js';
import NoOperator from './NoOperator.js';
import Loading from './util/Loading.js';
@ -15,11 +16,13 @@ const PodInfoView = ({pod, namespace}) => (
</Segment>
);
const OperatorsView = ({deployment, pod, namespace}) => (
<div>
{deployment ? <DeploymentOperator pod-info={<PodInfoView pod={pod} namespace={namespace}/>}/> : <NoOperator />}
</div>
);
const OperatorsView = ({error, deployment, pod, namespace}) => {
const podInfoView = (<PodInfoView pod={pod} namespace={namespace}/>);
if (deployment) {
return (<DeploymentOperator podInfoView={podInfoView} error={error}/>);
}
return (<NoOperator podInfoView={podInfoView} error={error}/>);
}
const LoadingView = () => (
<Container>
@ -28,25 +31,29 @@ const LoadingView = () => (
);
class App extends Component {
state = {};
state = {
operators: undefined,
error: undefined
};
componentDidMount() {
this.intervalId = setInterval(this.reloadOperators, 5000);
this.reloadOperators();
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
reloadOperators = async() => {
const operators = await api.get('/api/operators');
this.setState({operators});
try {
const operators = await api.get('/api/operators');
this.setState({operators, error: undefined});
} catch (e) {
this.setState({error: e.message});
}
this.props.setTimeout(this.reloadOperators, 10000);
}
render() {
if (this.state.operators) {
return <OperatorsView
error={this.state.error}
deployment={this.state.operators.deployment}
pod={this.state.operators.pod}
namespace={this.state.operators.namespace}
@ -56,4 +63,4 @@ class App extends Component {
}
}
export default App;
export default ReactTimeout(App);

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Message } from 'semantic-ui-react';
class NoOperator extends Component {
render() {
@ -13,7 +14,8 @@ class NoOperator extends Component {
<p className="App-intro">
There are no operators available yet.
</p>
{this.props["pod-info"]}
{this.props.podInfoView}
{(this.props.error) ? <Message error content={this.props.error}/> : null}
</div>
);
}

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react';
import api from '../api/api.js';
import Login from './Login.js';
import Loading from '../util/Loading.js';
import LogoutContext from './LogoutContext.js';
import { getSessionItem, setSessionItem } from "../util/Storage.js";
@ -9,6 +10,7 @@ const tokenSessionKey = "auth-token";
class Auth extends Component {
state = {
authenticated: false,
showLoading: true,
token: getSessionItem(tokenSessionKey) || ""
};
@ -18,11 +20,13 @@ class Auth extends Component {
await api.get('/api/operators');
this.setState({
authenticated: true,
showLoading: false,
token: api.token
});
} catch (e) {
this.setState({
authenticated: false,
showLoading: false,
token: ''
});
}
@ -65,9 +69,10 @@ class Auth extends Component {
render() {
return (
<LogoutContext.Provider value={this.handleLogout}>
{(!this.state.authenticated) ?
<Login doLogin={this.handleLogin} error={this.state.error}/> :
this.props.children
{(this.state.showLoading) ? <Loading/> :
(!this.state.authenticated) ?
<Login doLogin={this.handleLogin} error={this.state.error}/> :
this.props.children
}
</LogoutContext.Provider>
);

View file

@ -1,7 +1,20 @@
import ReactTimeout from 'react-timeout';
import React, { Component } from 'react';
import api from '../api/api.js';
import Loading from '../util/Loading.js';
import MemberList from './MemberList.js';
import styled from 'react-emotion';
import { Loader } from 'semantic-ui-react';
const LoaderBox = styled('span')`
float: right;
width: 0;
padding-right: 1em;
margin-right: 1em;
margin-top: 1em;
max-width: 0;
display: inline-block;
`;
const MemberGroupsView = ({memberGroups, namespace}) => (
<div>
@ -15,21 +28,31 @@ const MemberGroupsView = ({memberGroups, namespace}) => (
);
class DeploymentDetails extends Component {
state = {};
state = {
loading: true,
error: undefined
};
componentDidMount() {
this.intervalId = setInterval(this.reloadDeployment, 5000);
this.reloadDeployment();
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
reloadDeployment = async() => {
// TODO
const result = await api.get(`/api/deployment/${this.props.name}`);
this.setState({deployment:result});
try {
this.setState({loading:true});
const result = await api.get(`/api/deployment/${this.props.name}`);
this.setState({
deployment: result,
loading: false,
error: undefined
});
} catch (e) {
this.setState({
loading: false,
error: e.message
});
}
this.props.setTimeout(this.reloadDeployment, 5000);
}
render() {
@ -39,10 +62,11 @@ class DeploymentDetails extends Component {
}
return (
<div>
<LoaderBox><Loader size="mini" active={this.state.loading} inline/></LoaderBox>
<MemberGroupsView memberGroups={d.member_groups} namespace={d.namespace}/>
</div>
);
}
}
export default DeploymentDetails;
export default ReactTimeout(DeploymentDetails);

View file

@ -1,11 +1,21 @@
import React, { Component } from 'react';
import api from '../api/api.js';
import { Icon, Popup, Table } from 'semantic-ui-react';
import Loading from '../util/Loading.js';
import CommandInstruction from '../util/CommandInstruction.js';
import { Icon, Loader, Popup, Table } from 'semantic-ui-react';
import { Link } from "react-router-dom";
import api from '../api/api.js';
import CommandInstruction from '../util/CommandInstruction.js';
import Loading from '../util/Loading.js';
import React, { Component } from 'react';
import ReactTimeout from 'react-timeout';
import styled from 'react-emotion';
const HeaderView = () => (
const LoaderBox = styled('span')`
float: right;
width: 0;
padding-right: 1em;
max-width: 0;
display: inline-block;
`;
const HeaderView = ({loading}) => (
<Table.Header>
<Table.Row>
<Table.HeaderCell>State</Table.HeaderCell>
@ -15,7 +25,10 @@ const HeaderView = () => (
<Table.HeaderCell><Popup trigger={<span>Pods</span>}>Ready / Total</Popup></Table.HeaderCell>
<Table.HeaderCell><Popup trigger={<span>Volumes</span>}>Bound / Total</Popup></Table.HeaderCell>
<Table.HeaderCell>StorageClass</Table.HeaderCell>
<Table.HeaderCell>Actions</Table.HeaderCell>
<Table.HeaderCell>
Actions
<LoaderBox><Loader size="mini" active={loading} inline/></LoaderBox>
</Table.HeaderCell>
</Table.Row>
</Table.Header>
);
@ -83,9 +96,9 @@ const RowView = ({name, mode, environment, stateColor, version, license, readyPo
</Table.Row>
);
const ListView = ({items}) => (
const ListView = ({items, loading}) => (
<Table striped celled>
<HeaderView/>
<HeaderView loading={loading}/>
<Table.Body>
{
(items) ? items.map((item) =>
@ -138,20 +151,29 @@ function getStateColorDescription(stateColor) {
}
class DeploymentList extends Component {
state = {};
state = {
items: undefined,
error: undefined,
loading: true
};
componentDidMount() {
this.intervalId = setInterval(this.reloadDeployments, 5000);
this.reloadDeployments();
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
reloadDeployments = async() => {
const result = await api.get('/api/deployment');
this.setState({items:result.deployments});
try {
this.setState({loading: true});
const result = await api.get('/api/deployment');
this.setState({
items: result.deployments,
loading: false,
error: undefined
});
} catch (e) {
this.setState({error: e.message, loading: false});
}
this.props.setTimeout(this.reloadDeployments, 5000);
}
render() {
@ -162,8 +184,8 @@ class DeploymentList extends Component {
if (items.length === 0) {
return (<EmptyView/>);
}
return (<ListView items={items}/>);
return (<ListView items={items} loading={this.state.loading}/>);
}
}
export default DeploymentList;
export default ReactTimeout(DeploymentList);

View file

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import LogoutContext from '../auth/LogoutContext.js';
import DeploymentDetails from './DeploymentDetails.js';
import DeploymentList from './DeploymentList.js';
import { Header, Menu, Segment } from 'semantic-ui-react';
import { Header, Menu, Message, Segment } from 'semantic-ui-react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import styled from 'react-emotion';
@ -62,7 +62,8 @@ class DeploymentOperator extends Component {
<Route path="/deployment/:name" component={DetailView} />
</div>
</Segment>
{this.props["pod-info"]}
{this.props.podInfoView}
{(this.props.error) ? <Segment basic><Message error content={this.props.error}/></Segment> : null}
</StyledContentBox>
</div>
</Router>