Server availability and version notification
This commit is contained in:
1 parent
7768c79c20
commit
e35254cb6f
5 files changed
+102
-19
No files matched your search
@@ -33,6 +33,7 @@ import * as localCache from "./local-cache";
|
||||
import { PermissionSet } from "./types";
|
||||
import { authSimple } from "./ui/api-functions";
|
||||
import * as init from "./init";
|
||||
import { version as VERSION } from "../package.json";
|
||||
|
||||
declare module "koa" {
|
||||
interface Request {
|
||||
@@ -64,6 +65,7 @@ koa.use(async (ctx, next) => {
|
||||
const configSnapshot = await localCache.getCurrentSnapshot();
|
||||
ctx.state.configSnapshot = configSnapshot;
|
||||
ctx.set("X-Config-Snapshot", configSnapshot);
|
||||
ctx.set("GenieACS-Version", VERSION);
|
||||
return next();
|
||||
});
|
||||
|
||||
@@ -143,6 +145,10 @@ koa.use(async (ctx, next) => {
|
||||
koa.use(koaBodyParser());
|
||||
router.use("/api", api.routes(), api.allowedMethods());
|
||||
|
||||
router.get("/status", ctx => {
|
||||
ctx.body = "OK";
|
||||
});
|
||||
|
||||
router.get("/init", async ctx => {
|
||||
const status = await init.getStatus();
|
||||
if (Object.keys(localCache.getUsers(ctx.state.configSnapshot)).length) {
|
||||
@@ -207,6 +213,7 @@ router.get("/", async ctx => {
|
||||
ui: localCache.getUiConfig(ctx.state.configSnapshot)
|
||||
})};
|
||||
window.configSnapshot = ${JSON.stringify(ctx.state.configSnapshot)};
|
||||
window.genieacsVersion = ${JSON.stringify(VERSION)};
|
||||
window.username = ${JSON.stringify(
|
||||
ctx.state.user ? ctx.state.user.username : ""
|
||||
)};
|
||||
|
||||
@@ -45,6 +45,7 @@ declare global {
|
||||
username: string;
|
||||
clientConfig: any;
|
||||
configSnapshot: string;
|
||||
genieacsVersion: string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,3 +19,4 @@
|
||||
|
||||
export default window.clientConfig;
|
||||
export const configSnapshot = window.configSnapshot;
|
||||
export const genieacsVersion = window.genieacsVersion;
|
||||
+26
-2
@@ -17,9 +17,27 @@
|
||||
* along with GenieACS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as notifications from "./notifications";
|
||||
|
||||
export let codeMirror;
|
||||
export let yaml;
|
||||
|
||||
let note;
|
||||
|
||||
function onError(): void {
|
||||
if (!note) {
|
||||
note = notifications.push(
|
||||
"error",
|
||||
"Error loading JS resource, please reload the page",
|
||||
{
|
||||
Reload: () => {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function loadCodeMirror(): Promise<void> {
|
||||
if (codeMirror) return Promise.resolve();
|
||||
|
||||
@@ -36,7 +54,10 @@ export function loadCodeMirror(): Promise<void> {
|
||||
codeMirror = modules[0];
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
.catch(err => {
|
||||
onError();
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,6 +70,9 @@ export function loadYaml(): Promise<void> {
|
||||
yaml = module;
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
.catch(err => {
|
||||
onError();
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
+67
-17
@@ -23,13 +23,13 @@ import { or, and, not, evaluate, subset } from "../lib/common/expression";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import { QueryOptions, Expression } from "../lib/types";
|
||||
import * as notifications from "./notifications";
|
||||
import { configSnapshot } from "./config";
|
||||
import { configSnapshot, genieacsVersion } from "./config";
|
||||
|
||||
const memoizedStringify = memoize(stringify);
|
||||
const memoizedEvaluate = memoize(evaluate);
|
||||
|
||||
let fulfillTimestamp = 0;
|
||||
let refreshNotification;
|
||||
let connectionNotification, configNotification, versionNotification;
|
||||
|
||||
const queries = {
|
||||
filter: new WeakMap(),
|
||||
@@ -89,6 +89,71 @@ class QueryResponse {
|
||||
}
|
||||
}
|
||||
|
||||
function checkConnection(): void {
|
||||
m.request({
|
||||
url: "/status",
|
||||
method: "GET",
|
||||
background: true,
|
||||
extract: xhr => {
|
||||
if (xhr.status !== 200) {
|
||||
if (!connectionNotification) {
|
||||
connectionNotification = notifications.push(
|
||||
"warning",
|
||||
"Server is unreachable",
|
||||
{}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (connectionNotification) {
|
||||
notifications.dismiss(connectionNotification);
|
||||
connectionNotification = null;
|
||||
}
|
||||
|
||||
const configChanged =
|
||||
xhr.getResponseHeader("x-config-snapshot") !== configSnapshot;
|
||||
const versionChanged =
|
||||
xhr.getResponseHeader("genieacs-version") !== genieacsVersion;
|
||||
|
||||
if (!configNotification !== !configChanged) {
|
||||
if (configNotification) {
|
||||
notifications.dismiss(configNotification);
|
||||
configNotification = null;
|
||||
} else {
|
||||
configNotification = notifications.push(
|
||||
"warning",
|
||||
"Configuration has been modified, please reload the page",
|
||||
{
|
||||
Reload: () => {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!versionNotification !== !versionChanged) {
|
||||
if (versionNotification) {
|
||||
notifications.dismiss(versionNotification);
|
||||
versionNotification = null;
|
||||
} else {
|
||||
versionNotification = notifications.push(
|
||||
"warning",
|
||||
"Server has been updated, please reload the page",
|
||||
{
|
||||
Reload: () => {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(checkConnection, 3000);
|
||||
|
||||
export async function xhrRequest(
|
||||
options: { url: string } & m.RequestOptions<{}>
|
||||
): Promise<any> {
|
||||
@@ -99,21 +164,6 @@ export async function xhrRequest(
|
||||
xhr: XMLHttpRequest,
|
||||
_options?: { url: string } & m.RequestOptions<{}>
|
||||
): any => {
|
||||
if (
|
||||
!refreshNotification &&
|
||||
configSnapshot !== xhr.getResponseHeader("x-config-snapshot")
|
||||
) {
|
||||
refreshNotification = notifications.push(
|
||||
"warning",
|
||||
"Configuration has been modified, please reload the page",
|
||||
{
|
||||
Reload: () => {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof extract === "function") return extract(xhr, _options);
|
||||
|
||||
let response: any;
|
||||
|
||||
Reference in new issue
Block a user