@matdata/yasgui 5.4.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/ts/src/ConfigExportImport.js +1 -0
- package/build/ts/src/ConfigExportImport.js.map +1 -1
- package/build/ts/src/PersistentConfig.d.ts +7 -1
- package/build/ts/src/PersistentConfig.js +32 -0
- package/build/ts/src/PersistentConfig.js.map +1 -1
- package/build/ts/src/Tab.d.ts +1 -0
- package/build/ts/src/Tab.js +28 -2
- package/build/ts/src/Tab.js.map +1 -1
- package/build/ts/src/TabSettingsModal.d.ts +3 -2
- package/build/ts/src/TabSettingsModal.js +328 -119
- package/build/ts/src/TabSettingsModal.js.map +1 -1
- package/build/ts/src/index.d.ts +10 -0
- package/build/ts/src/index.js.map +1 -1
- package/build/yasgui.min.css +1 -1
- package/build/yasgui.min.css.map +3 -3
- package/build/yasgui.min.js +124 -117
- package/build/yasgui.min.js.map +3 -3
- package/package.json +1 -1
- package/src/ConfigExportImport.ts +1 -0
- package/src/PersistentConfig.ts +44 -2
- package/src/Tab.ts +47 -3
- package/src/TabSettingsModal.scss +385 -16
- package/src/TabSettingsModal.ts +413 -148
- package/src/index.ts +11 -0
|
@@ -90,48 +90,55 @@ export default class TabSettingsModal {
|
|
|
90
90
|
this.modalContent.appendChild(header);
|
|
91
91
|
const body = document.createElement("div");
|
|
92
92
|
addClass(body, "modalBody");
|
|
93
|
-
const
|
|
94
|
-
addClass(
|
|
93
|
+
const sidebar = document.createElement("div");
|
|
94
|
+
addClass(sidebar, "modalSidebar");
|
|
95
95
|
const requestTab = document.createElement("button");
|
|
96
96
|
requestTab.textContent = "Request";
|
|
97
|
-
addClass(requestTab, "
|
|
97
|
+
addClass(requestTab, "modalNavButton", "active");
|
|
98
98
|
requestTab.onclick = () => this.switchTab("request");
|
|
99
|
+
const endpointsTab = document.createElement("button");
|
|
100
|
+
endpointsTab.textContent = "SPARQL Endpoints";
|
|
101
|
+
addClass(endpointsTab, "modalNavButton");
|
|
102
|
+
endpointsTab.onclick = () => this.switchTab("endpoints");
|
|
99
103
|
const prefixTab = document.createElement("button");
|
|
100
104
|
prefixTab.textContent = "Prefixes";
|
|
101
|
-
addClass(prefixTab, "
|
|
105
|
+
addClass(prefixTab, "modalNavButton");
|
|
102
106
|
prefixTab.onclick = () => this.switchTab("prefix");
|
|
103
107
|
const editorTab = document.createElement("button");
|
|
104
108
|
editorTab.textContent = "Editor";
|
|
105
|
-
addClass(editorTab, "
|
|
109
|
+
addClass(editorTab, "modalNavButton");
|
|
106
110
|
editorTab.onclick = () => this.switchTab("editor");
|
|
107
|
-
const endpointsTab = document.createElement("button");
|
|
108
|
-
endpointsTab.textContent = "Endpoint Buttons";
|
|
109
|
-
addClass(endpointsTab, "modalTabButton");
|
|
110
|
-
endpointsTab.onclick = () => this.switchTab("endpoints");
|
|
111
111
|
const importExportTab = document.createElement("button");
|
|
112
112
|
importExportTab.textContent = "Import/Export";
|
|
113
|
-
addClass(importExportTab, "
|
|
113
|
+
addClass(importExportTab, "modalNavButton");
|
|
114
114
|
importExportTab.onclick = () => this.switchTab("importexport");
|
|
115
115
|
const shortcutsTab = document.createElement("button");
|
|
116
116
|
shortcutsTab.textContent = "Keyboard Shortcuts";
|
|
117
|
-
addClass(shortcutsTab, "
|
|
117
|
+
addClass(shortcutsTab, "modalNavButton");
|
|
118
118
|
shortcutsTab.onclick = () => this.switchTab("shortcuts");
|
|
119
119
|
const aboutTab = document.createElement("button");
|
|
120
120
|
aboutTab.textContent = "About";
|
|
121
|
-
addClass(aboutTab, "
|
|
121
|
+
addClass(aboutTab, "modalNavButton");
|
|
122
122
|
aboutTab.onclick = () => this.switchTab("about");
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
sidebar.appendChild(requestTab);
|
|
124
|
+
sidebar.appendChild(endpointsTab);
|
|
125
|
+
sidebar.appendChild(prefixTab);
|
|
126
|
+
sidebar.appendChild(editorTab);
|
|
127
|
+
sidebar.appendChild(importExportTab);
|
|
128
|
+
sidebar.appendChild(shortcutsTab);
|
|
129
|
+
sidebar.appendChild(aboutTab);
|
|
130
|
+
const contentArea = document.createElement("div");
|
|
131
|
+
addClass(contentArea, "modalContentArea");
|
|
132
|
+
body.appendChild(sidebar);
|
|
133
|
+
body.appendChild(contentArea);
|
|
131
134
|
const requestContent = document.createElement("div");
|
|
132
135
|
addClass(requestContent, "modalTabContent", "active");
|
|
133
136
|
requestContent.id = "request-content";
|
|
134
137
|
this.drawRequestSettings(requestContent);
|
|
138
|
+
const endpointsContent = document.createElement("div");
|
|
139
|
+
addClass(endpointsContent, "modalTabContent");
|
|
140
|
+
endpointsContent.id = "endpoints-content";
|
|
141
|
+
this.drawEndpointsSettings(endpointsContent);
|
|
135
142
|
const prefixContent = document.createElement("div");
|
|
136
143
|
addClass(prefixContent, "modalTabContent");
|
|
137
144
|
prefixContent.id = "prefix-content";
|
|
@@ -140,10 +147,6 @@ export default class TabSettingsModal {
|
|
|
140
147
|
addClass(editorContent, "modalTabContent");
|
|
141
148
|
editorContent.id = "editor-content";
|
|
142
149
|
this.drawEditorSettings(editorContent);
|
|
143
|
-
const endpointsContent = document.createElement("div");
|
|
144
|
-
addClass(endpointsContent, "modalTabContent");
|
|
145
|
-
endpointsContent.id = "endpoints-content";
|
|
146
|
-
this.drawEndpointButtonsSettings(endpointsContent);
|
|
147
150
|
const importExportContent = document.createElement("div");
|
|
148
151
|
addClass(importExportContent, "modalTabContent");
|
|
149
152
|
importExportContent.id = "importexport-content";
|
|
@@ -156,13 +159,13 @@ export default class TabSettingsModal {
|
|
|
156
159
|
addClass(aboutContent, "modalTabContent");
|
|
157
160
|
aboutContent.id = "about-content";
|
|
158
161
|
this.drawAboutSettings(aboutContent);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
contentArea.appendChild(requestContent);
|
|
163
|
+
contentArea.appendChild(endpointsContent);
|
|
164
|
+
contentArea.appendChild(prefixContent);
|
|
165
|
+
contentArea.appendChild(editorContent);
|
|
166
|
+
contentArea.appendChild(importExportContent);
|
|
167
|
+
contentArea.appendChild(shortcutsContent);
|
|
168
|
+
contentArea.appendChild(aboutContent);
|
|
166
169
|
this.modalContent.appendChild(body);
|
|
167
170
|
const footer = document.createElement("div");
|
|
168
171
|
addClass(footer, "modalFooter");
|
|
@@ -181,13 +184,13 @@ export default class TabSettingsModal {
|
|
|
181
184
|
document.body.appendChild(this.modalOverlay);
|
|
182
185
|
}
|
|
183
186
|
switchTab(tabName) {
|
|
184
|
-
const buttons = this.modalContent.querySelectorAll(".
|
|
187
|
+
const buttons = this.modalContent.querySelectorAll(".modalNavButton");
|
|
185
188
|
const contents = this.modalContent.querySelectorAll(".modalTabContent");
|
|
186
189
|
buttons.forEach((btn, index) => {
|
|
187
190
|
if ((tabName === "request" && index === 0) ||
|
|
188
|
-
(tabName === "
|
|
189
|
-
(tabName === "
|
|
190
|
-
(tabName === "
|
|
191
|
+
(tabName === "endpoints" && index === 1) ||
|
|
192
|
+
(tabName === "prefix" && index === 2) ||
|
|
193
|
+
(tabName === "editor" && index === 3) ||
|
|
191
194
|
(tabName === "importexport" && index === 4) ||
|
|
192
195
|
(tabName === "shortcuts" && index === 5) ||
|
|
193
196
|
(tabName === "about" && index === 6)) {
|
|
@@ -338,6 +341,296 @@ export default class TabSettingsModal {
|
|
|
338
341
|
snippetsBarSection.appendChild(snippetsBarHelp);
|
|
339
342
|
container.appendChild(snippetsBarSection);
|
|
340
343
|
}
|
|
344
|
+
drawEndpointsSettings(container) {
|
|
345
|
+
const section = document.createElement("div");
|
|
346
|
+
addClass(section, "settingsSection");
|
|
347
|
+
const label = document.createElement("label");
|
|
348
|
+
label.textContent = "SPARQL Endpoints";
|
|
349
|
+
addClass(label, "settingsLabel");
|
|
350
|
+
const help = document.createElement("div");
|
|
351
|
+
help.textContent =
|
|
352
|
+
"Manage your SPARQL endpoints. Each endpoint can have its own authentication and be displayed as a quick-switch button.";
|
|
353
|
+
addClass(help, "settingsHelp");
|
|
354
|
+
section.appendChild(label);
|
|
355
|
+
section.appendChild(help);
|
|
356
|
+
const endpointsList = document.createElement("div");
|
|
357
|
+
addClass(endpointsList, "endpointsTable");
|
|
358
|
+
this.renderEndpointsList(endpointsList);
|
|
359
|
+
section.appendChild(endpointsList);
|
|
360
|
+
container.appendChild(section);
|
|
361
|
+
}
|
|
362
|
+
renderEndpointsList(container) {
|
|
363
|
+
container.innerHTML = "";
|
|
364
|
+
const configs = this.tab.yasgui.persistentConfig.getEndpointConfigs();
|
|
365
|
+
const table = document.createElement("table");
|
|
366
|
+
addClass(table, "endpointsTableElement");
|
|
367
|
+
const thead = document.createElement("thead");
|
|
368
|
+
const headerRow = document.createElement("tr");
|
|
369
|
+
const headers = ["Endpoint", "Label", "Button", "Authentication", "Actions"];
|
|
370
|
+
headers.forEach((h) => {
|
|
371
|
+
const th = document.createElement("th");
|
|
372
|
+
th.textContent = h;
|
|
373
|
+
headerRow.appendChild(th);
|
|
374
|
+
});
|
|
375
|
+
thead.appendChild(headerRow);
|
|
376
|
+
table.appendChild(thead);
|
|
377
|
+
const tbody = document.createElement("tbody");
|
|
378
|
+
if (configs.length === 0) {
|
|
379
|
+
const emptyRow = document.createElement("tr");
|
|
380
|
+
const emptyCell = document.createElement("td");
|
|
381
|
+
emptyCell.colSpan = 5;
|
|
382
|
+
emptyCell.textContent = "No endpoints yet. Add one below or access an endpoint to have it automatically tracked.";
|
|
383
|
+
addClass(emptyCell, "emptyMessage");
|
|
384
|
+
emptyCell.style.textAlign = "center";
|
|
385
|
+
emptyCell.style.padding = "20px";
|
|
386
|
+
emptyRow.appendChild(emptyCell);
|
|
387
|
+
tbody.appendChild(emptyRow);
|
|
388
|
+
}
|
|
389
|
+
configs.forEach((config, index) => {
|
|
390
|
+
const row = document.createElement("tr");
|
|
391
|
+
const endpointCell = document.createElement("td");
|
|
392
|
+
endpointCell.textContent = config.endpoint;
|
|
393
|
+
endpointCell.title = config.endpoint;
|
|
394
|
+
addClass(endpointCell, "endpointCell");
|
|
395
|
+
row.appendChild(endpointCell);
|
|
396
|
+
const labelCell = document.createElement("td");
|
|
397
|
+
const labelInput = document.createElement("input");
|
|
398
|
+
labelInput.type = "text";
|
|
399
|
+
labelInput.value = config.label || "";
|
|
400
|
+
labelInput.placeholder = "Optional label";
|
|
401
|
+
addClass(labelInput, "endpointLabelInput");
|
|
402
|
+
labelInput.onchange = () => {
|
|
403
|
+
this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(config.endpoint, {
|
|
404
|
+
label: labelInput.value.trim() || undefined,
|
|
405
|
+
});
|
|
406
|
+
this.renderEndpointsList(container);
|
|
407
|
+
this.tab.refreshEndpointButtons();
|
|
408
|
+
};
|
|
409
|
+
labelCell.appendChild(labelInput);
|
|
410
|
+
row.appendChild(labelCell);
|
|
411
|
+
const buttonCell = document.createElement("td");
|
|
412
|
+
const buttonCheckbox = document.createElement("input");
|
|
413
|
+
buttonCheckbox.type = "checkbox";
|
|
414
|
+
buttonCheckbox.checked = !!config.showAsButton;
|
|
415
|
+
buttonCheckbox.disabled = !config.label;
|
|
416
|
+
buttonCheckbox.setAttribute("aria-label", config.label ? "Show this endpoint as a quick-switch button" : "Add a label first to enable button");
|
|
417
|
+
buttonCheckbox.title = config.label
|
|
418
|
+
? "Show this endpoint as a quick-switch button"
|
|
419
|
+
: "Add a label first to enable button";
|
|
420
|
+
buttonCheckbox.onchange = () => {
|
|
421
|
+
this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(config.endpoint, {
|
|
422
|
+
showAsButton: buttonCheckbox.checked,
|
|
423
|
+
});
|
|
424
|
+
this.tab.refreshEndpointButtons();
|
|
425
|
+
};
|
|
426
|
+
buttonCell.appendChild(buttonCheckbox);
|
|
427
|
+
addClass(buttonCell, "centerCell");
|
|
428
|
+
row.appendChild(buttonCell);
|
|
429
|
+
const authCell = document.createElement("td");
|
|
430
|
+
const authButton = document.createElement("button");
|
|
431
|
+
authButton.type = "button";
|
|
432
|
+
addClass(authButton, "configureAuthButton");
|
|
433
|
+
if (config.authentication) {
|
|
434
|
+
authButton.textContent = "✓ Configured";
|
|
435
|
+
addClass(authButton, "authenticated");
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
authButton.textContent = "Configure";
|
|
439
|
+
}
|
|
440
|
+
authButton.onclick = () => this.showAuthenticationModal(config.endpoint);
|
|
441
|
+
authCell.appendChild(authButton);
|
|
442
|
+
addClass(authCell, "centerCell");
|
|
443
|
+
row.appendChild(authCell);
|
|
444
|
+
const actionsCell = document.createElement("td");
|
|
445
|
+
const deleteButton = document.createElement("button");
|
|
446
|
+
deleteButton.type = "button";
|
|
447
|
+
deleteButton.textContent = "Delete";
|
|
448
|
+
addClass(deleteButton, "deleteEndpointButton");
|
|
449
|
+
deleteButton.onclick = () => {
|
|
450
|
+
if (confirm(`Delete endpoint "${config.endpoint}"?`)) {
|
|
451
|
+
this.tab.yasgui.persistentConfig.deleteEndpointConfig(config.endpoint);
|
|
452
|
+
this.renderEndpointsList(container);
|
|
453
|
+
this.tab.refreshEndpointButtons();
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
actionsCell.appendChild(deleteButton);
|
|
457
|
+
addClass(actionsCell, "centerCell");
|
|
458
|
+
row.appendChild(actionsCell);
|
|
459
|
+
tbody.appendChild(row);
|
|
460
|
+
});
|
|
461
|
+
table.appendChild(tbody);
|
|
462
|
+
container.appendChild(table);
|
|
463
|
+
const addForm = document.createElement("div");
|
|
464
|
+
addClass(addForm, "addEndpointForm");
|
|
465
|
+
const addFormTitle = document.createElement("div");
|
|
466
|
+
addFormTitle.textContent = "Add New Endpoint";
|
|
467
|
+
addClass(addFormTitle, "addFormTitle");
|
|
468
|
+
addForm.appendChild(addFormTitle);
|
|
469
|
+
const formInputs = document.createElement("div");
|
|
470
|
+
addClass(formInputs, "addFormInputs");
|
|
471
|
+
const endpointInput = document.createElement("input");
|
|
472
|
+
endpointInput.type = "url";
|
|
473
|
+
endpointInput.placeholder = "Endpoint URL (e.g., https://dbpedia.org/sparql)";
|
|
474
|
+
addClass(endpointInput, "addEndpointInput");
|
|
475
|
+
formInputs.appendChild(endpointInput);
|
|
476
|
+
const addButton = document.createElement("button");
|
|
477
|
+
addButton.type = "button";
|
|
478
|
+
addButton.textContent = "+ Add Endpoint";
|
|
479
|
+
addClass(addButton, "addEndpointButton");
|
|
480
|
+
addButton.onclick = () => {
|
|
481
|
+
const endpoint = endpointInput.value.trim();
|
|
482
|
+
if (!endpoint) {
|
|
483
|
+
alert("Please enter an endpoint URL.");
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (!/^https?:\/\//i.test(endpoint)) {
|
|
487
|
+
alert("Endpoint URL must start with http:// or https://");
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
try {
|
|
491
|
+
new URL(endpoint);
|
|
492
|
+
}
|
|
493
|
+
catch (e) {
|
|
494
|
+
alert(e instanceof Error && e.message ? "Malformed URL: " + e.message : "Please enter a valid URL.");
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
const existing = this.tab.yasgui.persistentConfig.getEndpointConfig(endpoint);
|
|
498
|
+
if (existing) {
|
|
499
|
+
alert("This endpoint is already in the list.");
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {});
|
|
503
|
+
endpointInput.value = "";
|
|
504
|
+
this.renderEndpointsList(container);
|
|
505
|
+
this.tab.refreshEndpointButtons();
|
|
506
|
+
};
|
|
507
|
+
formInputs.appendChild(addButton);
|
|
508
|
+
addForm.appendChild(formInputs);
|
|
509
|
+
container.appendChild(addForm);
|
|
510
|
+
}
|
|
511
|
+
showAuthenticationModal(endpoint) {
|
|
512
|
+
const config = this.tab.yasgui.persistentConfig.getEndpointConfig(endpoint);
|
|
513
|
+
const existingAuth = config === null || config === void 0 ? void 0 : config.authentication;
|
|
514
|
+
const authModalOverlay = document.createElement("div");
|
|
515
|
+
addClass(authModalOverlay, "authModalOverlay");
|
|
516
|
+
authModalOverlay.onclick = () => authModalOverlay.remove();
|
|
517
|
+
const authModal = document.createElement("div");
|
|
518
|
+
addClass(authModal, "authModal");
|
|
519
|
+
authModal.onclick = (e) => e.stopPropagation();
|
|
520
|
+
const header = document.createElement("div");
|
|
521
|
+
addClass(header, "authModalHeader");
|
|
522
|
+
const title = document.createElement("h3");
|
|
523
|
+
title.textContent = "Configure Authentication";
|
|
524
|
+
const subtitle = document.createElement("div");
|
|
525
|
+
subtitle.textContent = endpoint;
|
|
526
|
+
addClass(subtitle, "authModalSubtitle");
|
|
527
|
+
header.appendChild(title);
|
|
528
|
+
header.appendChild(subtitle);
|
|
529
|
+
authModal.appendChild(header);
|
|
530
|
+
const body = document.createElement("div");
|
|
531
|
+
addClass(body, "authModalBody");
|
|
532
|
+
const typeSection = document.createElement("div");
|
|
533
|
+
addClass(typeSection, "authModalSection");
|
|
534
|
+
const typeLabel = document.createElement("label");
|
|
535
|
+
typeLabel.textContent = "Authentication Type";
|
|
536
|
+
const typeSelect = document.createElement("select");
|
|
537
|
+
const basicOption = document.createElement("option");
|
|
538
|
+
basicOption.value = "basic";
|
|
539
|
+
basicOption.textContent = "HTTP Basic Authentication";
|
|
540
|
+
typeSelect.appendChild(basicOption);
|
|
541
|
+
typeSection.appendChild(typeLabel);
|
|
542
|
+
typeSection.appendChild(typeSelect);
|
|
543
|
+
body.appendChild(typeSection);
|
|
544
|
+
const usernameSection = document.createElement("div");
|
|
545
|
+
addClass(usernameSection, "authModalSection");
|
|
546
|
+
const usernameLabel = document.createElement("label");
|
|
547
|
+
usernameLabel.textContent = "Username";
|
|
548
|
+
const usernameInput = document.createElement("input");
|
|
549
|
+
usernameInput.type = "text";
|
|
550
|
+
usernameInput.placeholder = "Enter username";
|
|
551
|
+
usernameInput.value = (existingAuth === null || existingAuth === void 0 ? void 0 : existingAuth.username) || "";
|
|
552
|
+
usernameInput.autocomplete = "username";
|
|
553
|
+
usernameSection.appendChild(usernameLabel);
|
|
554
|
+
usernameSection.appendChild(usernameInput);
|
|
555
|
+
body.appendChild(usernameSection);
|
|
556
|
+
const passwordSection = document.createElement("div");
|
|
557
|
+
addClass(passwordSection, "authModalSection");
|
|
558
|
+
const passwordLabel = document.createElement("label");
|
|
559
|
+
passwordLabel.textContent = "Password";
|
|
560
|
+
const passwordInput = document.createElement("input");
|
|
561
|
+
passwordInput.type = "password";
|
|
562
|
+
passwordInput.placeholder = "Enter password";
|
|
563
|
+
passwordInput.value = (existingAuth === null || existingAuth === void 0 ? void 0 : existingAuth.password) || "";
|
|
564
|
+
passwordInput.autocomplete = "current-password";
|
|
565
|
+
passwordSection.appendChild(passwordLabel);
|
|
566
|
+
passwordSection.appendChild(passwordInput);
|
|
567
|
+
body.appendChild(passwordSection);
|
|
568
|
+
const securityNotice = document.createElement("div");
|
|
569
|
+
addClass(securityNotice, "authSecurityNotice");
|
|
570
|
+
securityNotice.innerHTML = `
|
|
571
|
+
<strong>⚠️ Security Notice:</strong>
|
|
572
|
+
<ul>
|
|
573
|
+
<li>Credentials are stored in browser localStorage</li>
|
|
574
|
+
<li>Only use with HTTPS endpoints</li>
|
|
575
|
+
<li>Be cautious when using on shared computers</li>
|
|
576
|
+
</ul>
|
|
577
|
+
`;
|
|
578
|
+
body.appendChild(securityNotice);
|
|
579
|
+
authModal.appendChild(body);
|
|
580
|
+
const footer = document.createElement("div");
|
|
581
|
+
addClass(footer, "authModalFooter");
|
|
582
|
+
const removeButton = document.createElement("button");
|
|
583
|
+
removeButton.textContent = "Remove Authentication";
|
|
584
|
+
removeButton.type = "button";
|
|
585
|
+
addClass(removeButton, "authRemoveButton");
|
|
586
|
+
removeButton.onclick = () => {
|
|
587
|
+
this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
|
|
588
|
+
authentication: undefined,
|
|
589
|
+
});
|
|
590
|
+
authModalOverlay.remove();
|
|
591
|
+
const endpointsList = this.modalContent.querySelector(".endpointsTable");
|
|
592
|
+
if (endpointsList)
|
|
593
|
+
this.renderEndpointsList(endpointsList);
|
|
594
|
+
};
|
|
595
|
+
if (!existingAuth) {
|
|
596
|
+
removeButton.disabled = true;
|
|
597
|
+
}
|
|
598
|
+
const cancelButton = document.createElement("button");
|
|
599
|
+
cancelButton.textContent = "Cancel";
|
|
600
|
+
cancelButton.type = "button";
|
|
601
|
+
addClass(cancelButton, "authCancelButton");
|
|
602
|
+
cancelButton.onclick = () => authModalOverlay.remove();
|
|
603
|
+
const saveButton = document.createElement("button");
|
|
604
|
+
saveButton.textContent = "Save";
|
|
605
|
+
saveButton.type = "button";
|
|
606
|
+
addClass(saveButton, "authSaveButton");
|
|
607
|
+
saveButton.onclick = () => {
|
|
608
|
+
const username = usernameInput.value.trim();
|
|
609
|
+
const password = passwordInput.value;
|
|
610
|
+
if (username && password) {
|
|
611
|
+
this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
|
|
612
|
+
authentication: {
|
|
613
|
+
type: "basic",
|
|
614
|
+
username,
|
|
615
|
+
password,
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
authModalOverlay.remove();
|
|
619
|
+
const endpointsList = this.modalContent.querySelector(".endpointsTable");
|
|
620
|
+
if (endpointsList)
|
|
621
|
+
this.renderEndpointsList(endpointsList);
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
alert("Please enter both username and password.");
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
footer.appendChild(removeButton);
|
|
628
|
+
footer.appendChild(cancelButton);
|
|
629
|
+
footer.appendChild(saveButton);
|
|
630
|
+
authModal.appendChild(footer);
|
|
631
|
+
authModalOverlay.appendChild(authModal);
|
|
632
|
+
document.body.appendChild(authModalOverlay);
|
|
633
|
+
}
|
|
341
634
|
drawRequestSettings(container) {
|
|
342
635
|
const reqConfig = this.tab.getRequestConfig();
|
|
343
636
|
const methodSection = this.createSection("Request Method");
|
|
@@ -523,90 +816,6 @@ export default class TabSettingsModal {
|
|
|
523
816
|
const deduplicated = this.deduplicatePrefixes(combined);
|
|
524
817
|
this.tab.yasgui.persistentConfig.setPrefixes(deduplicated);
|
|
525
818
|
}
|
|
526
|
-
drawEndpointButtonsSettings(container) {
|
|
527
|
-
const section = document.createElement("div");
|
|
528
|
-
addClass(section, "settingsSection");
|
|
529
|
-
const label = document.createElement("label");
|
|
530
|
-
label.textContent = "Custom Endpoint Buttons";
|
|
531
|
-
addClass(label, "settingsLabel");
|
|
532
|
-
const help = document.createElement("div");
|
|
533
|
-
help.textContent = "Add custom endpoint buttons that will appear next to the endpoint textbox.";
|
|
534
|
-
addClass(help, "settingsHelp");
|
|
535
|
-
section.appendChild(label);
|
|
536
|
-
section.appendChild(help);
|
|
537
|
-
const buttonsList = document.createElement("div");
|
|
538
|
-
addClass(buttonsList, "endpointButtonsList");
|
|
539
|
-
this.renderEndpointButtonsList(buttonsList);
|
|
540
|
-
section.appendChild(buttonsList);
|
|
541
|
-
const addForm = document.createElement("div");
|
|
542
|
-
addClass(addForm, "addEndpointButtonForm");
|
|
543
|
-
const labelInput = document.createElement("input");
|
|
544
|
-
labelInput.type = "text";
|
|
545
|
-
labelInput.placeholder = "Button label (e.g., DBpedia)";
|
|
546
|
-
addClass(labelInput, "endpointButtonLabelInput");
|
|
547
|
-
const endpointInput = document.createElement("input");
|
|
548
|
-
endpointInput.type = "url";
|
|
549
|
-
endpointInput.placeholder = "Endpoint URL (e.g., https://dbpedia.org/sparql)";
|
|
550
|
-
addClass(endpointInput, "endpointButtonEndpointInput");
|
|
551
|
-
const addButton = document.createElement("button");
|
|
552
|
-
addButton.textContent = "+ Add Button";
|
|
553
|
-
addClass(addButton, "addEndpointButton");
|
|
554
|
-
addButton.type = "button";
|
|
555
|
-
addButton.onclick = () => {
|
|
556
|
-
const labelValue = labelInput.value.trim();
|
|
557
|
-
const endpointValue = endpointInput.value.trim();
|
|
558
|
-
if (!labelValue || !endpointValue) {
|
|
559
|
-
alert("Please enter both a label and an endpoint URL.");
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
const currentButtons = this.tab.yasgui.persistentConfig.getCustomEndpointButtons();
|
|
563
|
-
currentButtons.push({ label: labelValue, endpoint: endpointValue });
|
|
564
|
-
this.tab.yasgui.persistentConfig.setCustomEndpointButtons(currentButtons);
|
|
565
|
-
labelInput.value = "";
|
|
566
|
-
endpointInput.value = "";
|
|
567
|
-
this.renderEndpointButtonsList(buttonsList);
|
|
568
|
-
};
|
|
569
|
-
addForm.appendChild(labelInput);
|
|
570
|
-
addForm.appendChild(endpointInput);
|
|
571
|
-
addForm.appendChild(addButton);
|
|
572
|
-
section.appendChild(addForm);
|
|
573
|
-
container.appendChild(section);
|
|
574
|
-
}
|
|
575
|
-
renderEndpointButtonsList(container) {
|
|
576
|
-
container.innerHTML = "";
|
|
577
|
-
const customButtons = this.tab.yasgui.persistentConfig.getCustomEndpointButtons();
|
|
578
|
-
if (customButtons.length === 0) {
|
|
579
|
-
const emptyMsg = document.createElement("div");
|
|
580
|
-
emptyMsg.textContent = "No custom buttons yet. Add one below.";
|
|
581
|
-
addClass(emptyMsg, "emptyMessage");
|
|
582
|
-
container.appendChild(emptyMsg);
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
customButtons.forEach((btn, index) => {
|
|
586
|
-
const item = document.createElement("div");
|
|
587
|
-
addClass(item, "endpointButtonItem");
|
|
588
|
-
const labelSpan = document.createElement("span");
|
|
589
|
-
labelSpan.textContent = `${btn.label}`;
|
|
590
|
-
addClass(labelSpan, "buttonLabel");
|
|
591
|
-
const endpointSpan = document.createElement("span");
|
|
592
|
-
endpointSpan.textContent = btn.endpoint;
|
|
593
|
-
addClass(endpointSpan, "buttonEndpoint");
|
|
594
|
-
const removeBtn = document.createElement("button");
|
|
595
|
-
removeBtn.textContent = "×";
|
|
596
|
-
addClass(removeBtn, "removeButton");
|
|
597
|
-
removeBtn.type = "button";
|
|
598
|
-
removeBtn.onclick = () => {
|
|
599
|
-
const currentButtons = this.tab.yasgui.persistentConfig.getCustomEndpointButtons();
|
|
600
|
-
currentButtons.splice(index, 1);
|
|
601
|
-
this.tab.yasgui.persistentConfig.setCustomEndpointButtons(currentButtons);
|
|
602
|
-
this.renderEndpointButtonsList(container);
|
|
603
|
-
};
|
|
604
|
-
item.appendChild(labelSpan);
|
|
605
|
-
item.appendChild(endpointSpan);
|
|
606
|
-
item.appendChild(removeBtn);
|
|
607
|
-
container.appendChild(item);
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
819
|
getThemeToggleIcon() {
|
|
611
820
|
const currentTheme = this.tab.yasgui.getTheme();
|
|
612
821
|
return currentTheme === "dark" ? MOON_ICON : SUN_ICON;
|