Skip to content

Commit 49a5b60

Browse files
committed
Retain latest admin dashboard UI and browser checks
Preserve all current authorized source changes; qualification runs in GitHub Actions.
1 parent fd1faef commit 49a5b60

8 files changed

Lines changed: 593 additions & 334 deletions

File tree

‎src/KeyLoad.Server/Features/AdminDashboard/Assets/app.js‎

Lines changed: 93 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -28,132 +28,139 @@ import {
2828
import {
2929
resetMetrics
3030
} from './metrics.js';
31-
let credential=Text.empty;
32-
let epoch=Config.zero;
33-
let controller=null;
34-
let inFlight=false;
35-
let poll=null;
36-
let view=View.overview;
37-
function connection(active){
38-
document.body.classList.toggle(Dom.connected,active);
39-
write(Id.state,active?Text.connected:Text.disconnected);
40-
el(Id.disconnect).disabled=!active;
41-
el(Id.refresh).disabled=!active;
31+
let credential = Text.empty;
32+
let epoch = Config.zero;
33+
let controller = null;
34+
let inFlight = false;
35+
let poll = null;
36+
let view = View.overview;
37+
function connection(active) {
38+
document.body.classList.toggle(Dom.connected, active);
39+
write(Id.state, active?Text.connected:Text.disconnected);
40+
el(Id.disconnect).disabled = !active;
41+
el(Id.refresh).disabled = !active;
4242
}
43-
function stopPolling(){
44-
if(poll!==null)clearTimeout(poll);
45-
poll=null;
43+
function stopPolling() {
44+
if (poll !== null)clearTimeout(poll);
45+
poll = null;
4646
}
47-
function schedule(){
47+
function schedule() {
4848
stopPolling();
49-
if(credential&&!document.hidden)poll=setTimeout(refresh,Config.pollMs);
49+
if (credential && !document.hidden)poll = setTimeout(refresh, Config.pollMs);
5050
}
51-
function cancelPending(){
52-
epoch+=Config.one;
51+
function cancelPending() {
52+
epoch += Config.one;
5353
controller?.abort();
54-
controller=null;
55-
inFlight=false;
54+
controller = null;
55+
inFlight = false;
5656
stopPolling();
5757
}
58-
function disconnect(message=Text.disconnectedHint,resetScope=true){
58+
function disconnect(message = Text.disconnectedHint, resetScope = true) {
5959
cancelPending();
60-
credential=Text.empty;
61-
el(Id.key).value=Text.empty;
62-
if(resetScope){
63-
el(Id.tenant).value=Text.defaultTenant;
64-
el(Id.database).value=Text.defaultDatabase;
65-
el(Id.partition).value=Text.defaultPartition;
66-
}connection(false);
60+
credential = Text.empty;
61+
el(Id.key).value = Text.empty;
62+
if (resetScope) {
63+
el(Id.tenant).value = Text.defaultTenant;
64+
el(Id.database).value = Text.defaultDatabase;
65+
el(Id.partition).value = Text.defaultPartition;
66+
}
67+
connection(false);
6768
clearObservations();
6869
resetBrowsing();
69-
status(message,message===Text.unauthorized);
70+
status(message, message === Text.unauthorized);
7071
}
71-
async function request(path,body=null){
72-
if(!credential||inFlight)return null;
73-
inFlight=true;
74-
const started=epoch;
75-
const current=new AbortController();
76-
controller=current;
72+
async function request(path, body = null) {
73+
if (!credential || inFlight)return null;
74+
inFlight = true;
75+
const started = epoch;
76+
const current = new AbortController();
77+
controller = current;
7778
stopPolling();
78-
try{
79-
const headers={
79+
try {
80+
const headers = {
8081
[Api.authorization]:Api.bearer+credential
8182
};
82-
if(body!==null)headers[Api.contentType]=Api.json;
83-
const response=await fetch(path,{
84-
method:body===null?Api.get:Api.post,headers,body:body===null?undefined:JSON.stringify(body),credentials:Api.sameOrigin,cache:Api.noStore,signal:current.signal
83+
if (body !== null)headers[Api.contentType] = Api.json;
84+
const response = await fetch(path, {
85+
method:body === null?Api.get:Api.post,
86+
headers,
87+
body:body === null?undefined:JSON.stringify(body),
88+
credentials:Api.sameOrigin,
89+
cache:Api.noStore,
90+
signal:current.signal
8591
});
86-
if(started!==epoch)return null;
87-
if(response.status===Config.unauthenticated||response.status===Config.forbidden){
92+
if (started !== epoch)return null;
93+
if (response.status === Config.unauthenticated || response.status === Config.forbidden) {
8894
disconnect(Text.unauthorized);
8995
return null;
90-
}if(!response.ok)throw new Error(Text.httpError+response.status+Text.closeParen);
91-
const result=await response.json();
92-
return started===epoch?result:null;
93-
}catch(error){
94-
if(started!==epoch||error.name===Api.abort)return null;
96+
}
97+
if (!response.ok)throw new Error(Text.httpError+response.status+Text.closeParen);
98+
const result = await response.json();
99+
return started === epoch?result:null;
100+
} catch (error) {
101+
if (started !== epoch || error.name === Api.abort)return null;
95102
resetMetrics();
96-
write(Id.state,Text.observationUnavailable);
97-
write(Id.captured,Text.stale);
98-
el(Id.refresh).disabled=false;
99-
status(Text.failed,true);
103+
write(Id.state, Text.observationUnavailable);
104+
write(Id.captured, Text.stale);
105+
el(Id.refresh).disabled = false;
106+
status(Text.failed, true);
100107
return null;
101-
}finally{
102-
if(started===epoch){
103-
inFlight=false;
104-
controller=null;
108+
} finally {
109+
if (started === epoch) {
110+
inFlight = false;
111+
controller = null;
105112
schedule();
106113
}
107114
}
108115
}
109-
async function refresh(){
110-
if(!credential||inFlight||document.hidden)return;
116+
async function refresh() {
117+
if (!credential || inFlight || document.hidden)return;
111118
status(Text.loading);
112-
const result=await request(Api.snapshot);
113-
if(!result)return;
119+
const result = await request(Api.snapshot);
120+
if (!result)return;
114121
renderSnapshot(result);
115122
connection(true);
116123
status(Text.ready);
117-
if(view===View.files&&!hasSelectedResource())physicalFiles();
124+
if (view === View.files && !hasSelectedResource())physicalFiles();
118125
}
119-
async function connect(event){
126+
async function connect(event) {
120127
event.preventDefault();
121-
const key=el(Id.key).value.trim();
122-
if(!key)return;
123-
disconnect(Text.disconnectedHint,false);
124-
credential=key;
125-
el(Id.key).value=Text.empty;
126-
write(Id.state,Text.connecting);
127-
el(Id.disconnect).disabled=false;
128+
const key = el(Id.key).value.trim();
129+
if (!key)return;
130+
disconnect(Text.disconnectedHint, false);
131+
credential = key;
132+
el(Id.key).value = Text.empty;
133+
write(Id.state, Text.connecting);
134+
el(Id.disconnect).disabled = false;
128135
await refresh();
129136
}
130-
async function navigate(next){
137+
async function navigate(next) {
131138
cancelPending();
132-
view=next;
139+
view = next;
133140
selectView(view);
134141
viewChanged(view);
135142
schedule();
136-
if(credential&&view!==View.overview&&view!==View.cluster)await loadResources();
143+
if (credential && view !== View.overview && view !== View.cluster)await loadResources();
137144
}
138-
function wireBrowsing(){
139-
el(Id.scope).addEventListener(Dom.submit,event=>{
145+
function wireBrowsing() {
146+
el(Id.scope).addEventListener(Dom.submit, event => {
140147
event.preventDefault();
141148
loadResources();
142149
});
143-
el(Id.resourcesFirst).addEventListener(Dom.click,()=>loadResources());
144-
el(Id.resourcesNext).addEventListener(Dom.click,()=>loadResources(true));
145-
el(Id.dataFirst).addEventListener(Dom.click,()=>loadData());
146-
el(Id.dataNext).addEventListener(Dom.click,()=>loadData(true));
150+
el(Id.resourcesFirst).addEventListener(Dom.click, () => loadResources());
151+
el(Id.resourcesNext).addEventListener(Dom.click, () => loadResources(true));
152+
el(Id.dataFirst).addEventListener(Dom.click, () => loadData());
153+
el(Id.dataNext).addEventListener(Dom.click, () => loadData(true));
147154
}
148-
function start(){
149-
initializeBrowsing(request,cancelPending);
150-
el(Id.form).addEventListener(Dom.submit,connect);
151-
el(Id.disconnect).addEventListener(Dom.click,()=>disconnect());
152-
el(Id.refresh).addEventListener(Dom.click,refresh);
153-
document.querySelectorAll(Dom.nav).forEach(button=>button.addEventListener(Dom.click,()=>navigate(button.dataset.view)));
154-
el(Id.closeDetails).addEventListener(Dom.click,()=>el(Id.dialog).close());
155-
document.addEventListener(Dom.visibility,()=>{
156-
if(document.hidden)stopPolling();
155+
function start() {
156+
initializeBrowsing(request, cancelPending);
157+
el(Id.form).addEventListener(Dom.submit, connect);
158+
el(Id.disconnect).addEventListener(Dom.click, () => disconnect());
159+
el(Id.refresh).addEventListener(Dom.click, refresh);
160+
document.querySelectorAll(Dom.nav).forEach(button => button.addEventListener(Dom.click, () => navigate(button.dataset.view)));
161+
el(Id.closeDetails).addEventListener(Dom.click, () => el(Id.dialog).close());
162+
document.addEventListener(Dom.visibility, () => {
163+
if (document.hidden)stopPolling();
157164
else refresh();
158165
});
159166
wireBrowsing();

0 commit comments

Comments
 (0)