This dashboard shows values kept in server memory. Many clients
can open this page. As soon as any client changes any value,
all clients update automatically.
The JS code that watches state changes, reconnects on network failures.
That means if server restarts, dashboard on all connected clients
refresh automatically.
You can use curl command-line utility:
curl localhost:8000/api/config/get curl localhost:8000/api/config/watch curl localhost:8000/api/config/set -d '{"a":123}' NOTE: administrators
can change settings values, whilst users cannot.
`
}
}
class Logs extends Component {
state = {live: '', static: ''};
componentDidMount() {
var self = this;
var f = function(r) {
return r.read().then(function(result) {
var data = String.fromCharCode.apply(null, result.value);
var live = self.state.live + data;
self.setState({live}); // Append live log
if (!result.done) f(r); // Read next chunk
});
};
fetch('/api/log/static')
.then(r => r.text())
.then(r => {
self.setState({static: r});
})
.then(r => fetch('/api/log/live'))
.then(r => r.body.getReader())
.then(f);
}
render(props, state) {
return html`
A div below shows file log.txt, which is produced by the server.
The server appends a new log message to that file every second,
and a div below also shows that, implementing a "live log" feature.
JS code on this page first fetches /api/log/static that returns
log.txt contents, then fetches /api/log/live that does not return,
but feeds chunks of data as they arrive (live log).
You can also use curl command-line utility to see
live logs:
curl localhost:8000/api/log/live
Static
${state.static}
Live
${state.live}
`
}
}
class App extends Component {
state = {user: null, url: '/'};
setUser(token) {
const maxAge = token ? 86400 : 0;
document.cookie = `access_token=${token};path=/;max-age=${maxAge}`;
// this.setState({token});
return axios.get('/api/login')
.then(res => this.setState({user: res.data}))
.catch(err => this.setState({user: {}}));
}
componentDidMount() {
const getCookie = name => {
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : '';
};
this.setUser(getCookie('access_token')); // Move from state1 to 2 or 3
}
render(props, state) {
// We have three states:
// 1. Beginning. We don't know if we have a valid auth token or not
// 2. We sent an /api/login request, and failed to login
// 3. We sent an /api/login request, and succeeded to login
if (!state.user) return ''; // State 1
if (!state.user.user) return h(Login, {app: this}); // State 2
return h( // State 3
'div', {}, h(Header, {url: state.url, app: this}),
h(preactRouter.Router, {
history: History.createHashHistory(),
onChange: ev => this.setState({url: ev.url}),
},
h(state.user.user == 'admin' ? AdminDashboard : UserDashboard,
{default: true, app: this}),
h(Logs, {path: 'logs', app: this})));
}
};
window.onload = () => render(h(App), document.body);