diff --git a/MP.MON.Client/wwwroot/lib/boot.js b/MP.MON.Client/wwwroot/lib/boot.js
new file mode 100644
index 00000000..b00823da
--- /dev/null
+++ b/MP.MON.Client/wwwroot/lib/boot.js
@@ -0,0 +1,59 @@
+(() => {
+ const maximumRetryCount = 3;
+ const retryIntervalMilliseconds = 5000;
+ const reconnectModal = document.getElementById('reconnect-modal');
+
+ const startReconnectionProcess = () => {
+ reconnectModal.style.display = 'block';
+
+ let isCanceled = false;
+
+ (async () => {
+ for (let i = 0; i < maximumRetryCount; i++) {
+ reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;
+
+ await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));
+
+ if (isCanceled) {
+ return;
+ }
+
+ try {
+ const result = await Blazor.reconnect();
+ if (!result) {
+ // The server was reached, but the connection was rejected; reload the page.
+ location.reload();
+ return;
+ }
+
+ // Successfully reconnected to the server.
+ return;
+ } catch {
+ // Didn't reach the server; try again.
+ }
+ }
+
+ // Retried too many times; reload the page.
+ location.reload();
+ })();
+
+ return {
+ cancel: () => {
+ isCanceled = true;
+ reconnectModal.style.display = 'none';
+ },
+ };
+ };
+
+ let currentReconnectionProcess = null;
+
+ Blazor.start({
+ reconnectionHandler: {
+ onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
+ onConnectionUp: () => {
+ currentReconnectionProcess?.cancel();
+ currentReconnectionProcess = null;
+ }
+ }
+ });
+})();
\ No newline at end of file
diff --git a/MP.MON/Components/App.razor b/MP.MON/Components/App.razor
index a74296d3..e87468c5 100644
--- a/MP.MON/Components/App.razor
+++ b/MP.MON/Components/App.razor
@@ -20,6 +20,74 @@
@* *@
+ @* *@
+ @*
+ *@