@matdata/yasgui 5.3.0 → 5.4.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/Tab.d.ts +1 -1
- package/build/ts/src/Tab.js +18 -9
- package/build/ts/src/Tab.js.map +1 -1
- package/build/ts/src/TabSettingsModal.d.ts +3 -0
- package/build/ts/src/TabSettingsModal.js +197 -1
- package/build/ts/src/TabSettingsModal.js.map +1 -1
- package/build/ts/src/version.d.ts +1 -0
- package/build/ts/src/version.js +2 -0
- package/build/ts/src/version.js.map +1 -0
- package/build/yasgui.min.css +1 -1
- package/build/yasgui.min.css.map +3 -3
- package/build/yasgui.min.js +118 -104
- package/build/yasgui.min.js.map +4 -4
- package/package.json +1 -1
- package/src/Tab.ts +29 -15
- package/src/TabSettingsModal.scss +184 -2
- package/src/TabSettingsModal.ts +269 -1
- package/src/tab.scss +3 -4
- package/src/themes.scss +1 -1
- package/src/version.ts +3 -0
package/package.json
CHANGED
package/src/Tab.ts
CHANGED
|
@@ -266,7 +266,7 @@ export class Tab extends EventEmitter {
|
|
|
266
266
|
this.controlBarEl.appendChild(this.orientationToggleButton);
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
public updateOrientationToggleIcon() {
|
|
270
270
|
if (!this.orientationToggleButton) return;
|
|
271
271
|
|
|
272
272
|
// Show the icon for the layout we'll switch TO (not the current layout)
|
|
@@ -279,24 +279,38 @@ export class Tab extends EventEmitter {
|
|
|
279
279
|
public toggleOrientation() {
|
|
280
280
|
if (!this.rootEl) return;
|
|
281
281
|
|
|
282
|
-
// Remove old orientation class
|
|
283
|
-
removeClass(this.rootEl, `orientation-${this.currentOrientation}`);
|
|
284
|
-
|
|
285
282
|
// Toggle orientation
|
|
286
|
-
|
|
283
|
+
const newOrientation = this.currentOrientation === "vertical" ? "horizontal" : "vertical";
|
|
287
284
|
|
|
288
|
-
//
|
|
289
|
-
|
|
285
|
+
// Update global config
|
|
286
|
+
this.yasgui.config.orientation = newOrientation;
|
|
290
287
|
|
|
291
|
-
//
|
|
292
|
-
this.
|
|
288
|
+
// Apply to all tabs
|
|
289
|
+
for (const tabId in this.yasgui._tabs) {
|
|
290
|
+
const tab = this.yasgui._tabs[tabId];
|
|
291
|
+
if (tab && tab.rootEl) {
|
|
292
|
+
// Remove old orientation class
|
|
293
|
+
removeClass(tab.rootEl, `orientation-${tab.currentOrientation}`);
|
|
293
294
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
295
|
+
// Update tab's orientation
|
|
296
|
+
tab.currentOrientation = newOrientation;
|
|
297
|
+
|
|
298
|
+
// Add new orientation class
|
|
299
|
+
addClass(tab.rootEl, `orientation-${newOrientation}`);
|
|
300
|
+
|
|
301
|
+
// Update button icon if it exists
|
|
302
|
+
if (tab.orientationToggleButton) {
|
|
303
|
+
tab.updateOrientationToggleIcon();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Refresh components to adjust to new layout
|
|
307
|
+
if (tab.yasqe) {
|
|
308
|
+
tab.yasqe.refresh();
|
|
309
|
+
}
|
|
310
|
+
if (tab.yasr) {
|
|
311
|
+
tab.yasr.refresh();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
300
314
|
}
|
|
301
315
|
}
|
|
302
316
|
public getYasqe() {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
left: 0;
|
|
50
50
|
right: 0;
|
|
51
51
|
bottom: 0;
|
|
52
|
-
background: rgba(0, 0, 0, 0.5);
|
|
52
|
+
background: var(--yasgui-overlay-bg, rgba(0, 0, 0, 0.5));
|
|
53
53
|
z-index: 10000;
|
|
54
54
|
align-items: center;
|
|
55
55
|
justify-content: center;
|
|
@@ -185,7 +185,8 @@
|
|
|
185
185
|
padding: 10px;
|
|
186
186
|
border: 1px solid var(--yasgui-input-border, #ccc);
|
|
187
187
|
border-radius: 4px;
|
|
188
|
-
font-family:
|
|
188
|
+
font-family:
|
|
189
|
+
"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
189
190
|
font-size: 13px;
|
|
190
191
|
resize: vertical;
|
|
191
192
|
box-sizing: border-box;
|
|
@@ -436,3 +437,184 @@
|
|
|
436
437
|
opacity: 1;
|
|
437
438
|
}
|
|
438
439
|
}
|
|
440
|
+
|
|
441
|
+
// Keyboard Shortcuts styles
|
|
442
|
+
.shortcutsSection {
|
|
443
|
+
margin-bottom: 30px;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.shortcutsCategory {
|
|
447
|
+
font-size: 16px;
|
|
448
|
+
font-weight: 600;
|
|
449
|
+
color: var(--yasgui-text-primary, #000);
|
|
450
|
+
margin-bottom: 15px;
|
|
451
|
+
padding-bottom: 8px;
|
|
452
|
+
border-bottom: 2px solid var(--yasgui-border-color, #e0e0e0);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.shortcutsTable {
|
|
456
|
+
width: 100%;
|
|
457
|
+
border-collapse: collapse;
|
|
458
|
+
|
|
459
|
+
thead {
|
|
460
|
+
th {
|
|
461
|
+
padding: 10px 8px;
|
|
462
|
+
text-align: left;
|
|
463
|
+
font-weight: 600;
|
|
464
|
+
font-size: 13px;
|
|
465
|
+
color: var(--yasgui-text-primary, #333);
|
|
466
|
+
background-color: var(--yasgui-bg-secondary, #f5f5f5);
|
|
467
|
+
border-bottom: 2px solid var(--yasgui-border-color, #e0e0e0);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
tbody {
|
|
472
|
+
tr {
|
|
473
|
+
border-bottom: 1px solid var(--yasgui-border-color, #e8e8e8);
|
|
474
|
+
|
|
475
|
+
&:last-child {
|
|
476
|
+
border-bottom: none;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
&:hover {
|
|
480
|
+
background-color: var(--yasgui-bg-secondary, #f9f9f9);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
td {
|
|
486
|
+
padding: 12px 8px;
|
|
487
|
+
vertical-align: middle;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.shortcutsKeys {
|
|
492
|
+
width: 40%;
|
|
493
|
+
font-weight: 500;
|
|
494
|
+
|
|
495
|
+
kbd {
|
|
496
|
+
display: inline-block;
|
|
497
|
+
padding: 4px 8px;
|
|
498
|
+
font-size: 12px;
|
|
499
|
+
font-family:
|
|
500
|
+
SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
501
|
+
line-height: 1.4;
|
|
502
|
+
color: var(--yasgui-text-primary, #333);
|
|
503
|
+
background-color: var(--yasgui-bg-secondary, #f7f7f7);
|
|
504
|
+
border: 1px solid var(--yasgui-border-color, #ccc);
|
|
505
|
+
border-radius: 4px;
|
|
506
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
507
|
+
white-space: nowrap;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.shortcutsSeparator {
|
|
512
|
+
color: var(--yasgui-text-secondary, #999);
|
|
513
|
+
margin: 0 4px;
|
|
514
|
+
font-weight: normal;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.shortcutsDescription {
|
|
518
|
+
width: 60%;
|
|
519
|
+
color: var(--yasgui-text-primary, #333);
|
|
520
|
+
font-size: 14px;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// About tab styles
|
|
524
|
+
.aboutSection {
|
|
525
|
+
text-align: center;
|
|
526
|
+
padding: 20px;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.aboutTitle {
|
|
530
|
+
display: flex;
|
|
531
|
+
align-items: center;
|
|
532
|
+
justify-content: center;
|
|
533
|
+
gap: 15px;
|
|
534
|
+
margin-bottom: 10px;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.aboutMainTitle {
|
|
538
|
+
font-size: 28px;
|
|
539
|
+
font-weight: 700;
|
|
540
|
+
color: var(--yasgui-accent-color, #337ab7);
|
|
541
|
+
margin: 0;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.versionBadge {
|
|
545
|
+
background: var(--yasgui-accent-color, #337ab7);
|
|
546
|
+
color: white;
|
|
547
|
+
padding: 4px 12px;
|
|
548
|
+
border-radius: 12px;
|
|
549
|
+
font-size: 14px;
|
|
550
|
+
font-weight: 600;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.aboutSubtitle {
|
|
554
|
+
font-size: 16px;
|
|
555
|
+
color: var(--yasgui-text-secondary, #666);
|
|
556
|
+
margin: 0 0 30px 0;
|
|
557
|
+
font-style: italic;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.aboutLinks {
|
|
561
|
+
margin: 30px 0;
|
|
562
|
+
display: flex;
|
|
563
|
+
flex-direction: column;
|
|
564
|
+
gap: 20px;
|
|
565
|
+
text-align: left;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.aboutLinkItem {
|
|
569
|
+
padding: 15px;
|
|
570
|
+
border: 1px solid var(--yasgui-border-color, #ddd);
|
|
571
|
+
border-radius: 6px;
|
|
572
|
+
background: var(--yasgui-bg-secondary, #f9f9f9);
|
|
573
|
+
transition: all 0.2s;
|
|
574
|
+
|
|
575
|
+
&:hover {
|
|
576
|
+
border-color: var(--yasgui-accent-color, #337ab7);
|
|
577
|
+
background: var(--yasgui-bg-primary, #fff);
|
|
578
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.aboutLink {
|
|
583
|
+
font-size: 16px;
|
|
584
|
+
font-weight: 600;
|
|
585
|
+
color: var(--yasgui-accent-color, #337ab7);
|
|
586
|
+
text-decoration: none;
|
|
587
|
+
display: block;
|
|
588
|
+
margin-bottom: 5px;
|
|
589
|
+
|
|
590
|
+
&:hover {
|
|
591
|
+
text-decoration: underline;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.aboutLinkDescription {
|
|
596
|
+
font-size: 14px;
|
|
597
|
+
color: var(--yasgui-text-secondary, #666);
|
|
598
|
+
margin: 0;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
.aboutFooter {
|
|
602
|
+
margin-top: 40px;
|
|
603
|
+
padding-top: 20px;
|
|
604
|
+
border-top: 1px solid var(--yasgui-border-color, #e0e0e0);
|
|
605
|
+
font-size: 14px;
|
|
606
|
+
color: var(--yasgui-text-secondary, #666);
|
|
607
|
+
|
|
608
|
+
p {
|
|
609
|
+
margin: 5px 0;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
a {
|
|
613
|
+
color: var(--yasgui-accent-color, #337ab7);
|
|
614
|
+
text-decoration: none;
|
|
615
|
+
|
|
616
|
+
&:hover {
|
|
617
|
+
text-decoration: underline;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
package/src/TabSettingsModal.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { addClass, removeClass } from "@matdata/yasgui-utils";
|
|
|
2
2
|
import "./TabSettingsModal.scss";
|
|
3
3
|
import Tab from "./Tab";
|
|
4
4
|
import * as ConfigExportImport from "./ConfigExportImport";
|
|
5
|
+
import { VERSION } from "./version";
|
|
5
6
|
|
|
6
7
|
// Theme toggle icons
|
|
7
8
|
const MOON_ICON = `<svg viewBox="0 0 24 24" fill="currentColor">
|
|
@@ -142,11 +143,23 @@ export default class TabSettingsModal {
|
|
|
142
143
|
addClass(importExportTab, "modalTabButton");
|
|
143
144
|
importExportTab.onclick = () => this.switchTab("importexport");
|
|
144
145
|
|
|
146
|
+
const shortcutsTab = document.createElement("button");
|
|
147
|
+
shortcutsTab.textContent = "Keyboard Shortcuts";
|
|
148
|
+
addClass(shortcutsTab, "modalTabButton");
|
|
149
|
+
shortcutsTab.onclick = () => this.switchTab("shortcuts");
|
|
150
|
+
|
|
151
|
+
const aboutTab = document.createElement("button");
|
|
152
|
+
aboutTab.textContent = "About";
|
|
153
|
+
addClass(aboutTab, "modalTabButton");
|
|
154
|
+
aboutTab.onclick = () => this.switchTab("about");
|
|
155
|
+
|
|
145
156
|
tabsContainer.appendChild(requestTab);
|
|
146
157
|
tabsContainer.appendChild(prefixTab);
|
|
147
158
|
tabsContainer.appendChild(editorTab);
|
|
148
159
|
tabsContainer.appendChild(endpointsTab);
|
|
149
160
|
tabsContainer.appendChild(importExportTab);
|
|
161
|
+
tabsContainer.appendChild(shortcutsTab);
|
|
162
|
+
tabsContainer.appendChild(aboutTab);
|
|
150
163
|
body.appendChild(tabsContainer);
|
|
151
164
|
|
|
152
165
|
// Tab content containers
|
|
@@ -175,11 +188,23 @@ export default class TabSettingsModal {
|
|
|
175
188
|
importExportContent.id = "importexport-content";
|
|
176
189
|
this.drawImportExportSettings(importExportContent);
|
|
177
190
|
|
|
191
|
+
const shortcutsContent = document.createElement("div");
|
|
192
|
+
addClass(shortcutsContent, "modalTabContent");
|
|
193
|
+
shortcutsContent.id = "shortcuts-content";
|
|
194
|
+
this.drawKeyboardShortcuts(shortcutsContent);
|
|
195
|
+
|
|
196
|
+
const aboutContent = document.createElement("div");
|
|
197
|
+
addClass(aboutContent, "modalTabContent");
|
|
198
|
+
aboutContent.id = "about-content";
|
|
199
|
+
this.drawAboutSettings(aboutContent);
|
|
200
|
+
|
|
178
201
|
body.appendChild(requestContent);
|
|
179
202
|
body.appendChild(prefixContent);
|
|
180
203
|
body.appendChild(editorContent);
|
|
181
204
|
body.appendChild(endpointsContent);
|
|
182
205
|
body.appendChild(importExportContent);
|
|
206
|
+
body.appendChild(shortcutsContent);
|
|
207
|
+
body.appendChild(aboutContent);
|
|
183
208
|
|
|
184
209
|
this.modalContent.appendChild(body);
|
|
185
210
|
|
|
@@ -216,7 +241,9 @@ export default class TabSettingsModal {
|
|
|
216
241
|
(tabName === "prefix" && index === 1) ||
|
|
217
242
|
(tabName === "editor" && index === 2) ||
|
|
218
243
|
(tabName === "endpoints" && index === 3) ||
|
|
219
|
-
(tabName === "importexport" && index === 4)
|
|
244
|
+
(tabName === "importexport" && index === 4) ||
|
|
245
|
+
(tabName === "shortcuts" && index === 5) ||
|
|
246
|
+
(tabName === "about" && index === 6)
|
|
220
247
|
) {
|
|
221
248
|
addClass(btn as HTMLElement, "active");
|
|
222
249
|
} else {
|
|
@@ -378,6 +405,35 @@ export default class TabSettingsModal {
|
|
|
378
405
|
constructValidationSection.appendChild(constructValidationCheckboxContainer);
|
|
379
406
|
constructValidationSection.appendChild(constructValidationHelp);
|
|
380
407
|
container.appendChild(constructValidationSection);
|
|
408
|
+
|
|
409
|
+
// Code Snippets Bar Visibility Section
|
|
410
|
+
const snippetsBarSection = document.createElement("div");
|
|
411
|
+
addClass(snippetsBarSection, "settingsSection");
|
|
412
|
+
|
|
413
|
+
const snippetsBarCheckboxContainer = document.createElement("div");
|
|
414
|
+
addClass(snippetsBarCheckboxContainer, "checkboxContainer");
|
|
415
|
+
|
|
416
|
+
const snippetsBarCheckbox = document.createElement("input");
|
|
417
|
+
snippetsBarCheckbox.type = "checkbox";
|
|
418
|
+
snippetsBarCheckbox.id = "showSnippetsBar";
|
|
419
|
+
snippetsBarCheckbox.checked = yasqe.getSnippetsBarVisible();
|
|
420
|
+
|
|
421
|
+
const snippetsBarLabel = document.createElement("label");
|
|
422
|
+
snippetsBarLabel.htmlFor = "showSnippetsBar";
|
|
423
|
+
snippetsBarLabel.textContent = "Show code snippets bar";
|
|
424
|
+
|
|
425
|
+
const snippetsBarHelp = document.createElement("div");
|
|
426
|
+
snippetsBarHelp.textContent =
|
|
427
|
+
"Display the code snippets bar above the editor for quick insertion of common SPARQL patterns.";
|
|
428
|
+
addClass(snippetsBarHelp, "settingsHelp");
|
|
429
|
+
snippetsBarHelp.style.marginTop = "5px";
|
|
430
|
+
|
|
431
|
+
snippetsBarCheckboxContainer.appendChild(snippetsBarCheckbox);
|
|
432
|
+
snippetsBarCheckboxContainer.appendChild(snippetsBarLabel);
|
|
433
|
+
|
|
434
|
+
snippetsBarSection.appendChild(snippetsBarCheckboxContainer);
|
|
435
|
+
snippetsBarSection.appendChild(snippetsBarHelp);
|
|
436
|
+
container.appendChild(snippetsBarSection);
|
|
381
437
|
}
|
|
382
438
|
|
|
383
439
|
private drawRequestSettings(container: HTMLElement) {
|
|
@@ -499,6 +555,10 @@ export default class TabSettingsModal {
|
|
|
499
555
|
if (constructValidationCheckbox) {
|
|
500
556
|
yasqe.setCheckConstructVariables(constructValidationCheckbox.checked);
|
|
501
557
|
}
|
|
558
|
+
const snippetsBarCheckbox = document.getElementById("showSnippetsBar") as HTMLInputElement;
|
|
559
|
+
if (snippetsBarCheckbox) {
|
|
560
|
+
yasqe.setSnippetsBarVisible(snippetsBarCheckbox.checked);
|
|
561
|
+
}
|
|
502
562
|
yasqe.saveQuery();
|
|
503
563
|
}
|
|
504
564
|
|
|
@@ -885,6 +945,112 @@ export default class TabSettingsModal {
|
|
|
885
945
|
container.appendChild(importSection);
|
|
886
946
|
}
|
|
887
947
|
|
|
948
|
+
private drawKeyboardShortcuts(container: HTMLElement) {
|
|
949
|
+
const shortcutsData = [
|
|
950
|
+
{
|
|
951
|
+
category: "Query Editor (YASQE)",
|
|
952
|
+
shortcuts: [
|
|
953
|
+
{ keys: ["Ctrl+Enter", "Cmd+Enter"], description: "Execute query" },
|
|
954
|
+
{ keys: ["Ctrl+Space", "Cmd+Space"], description: "Trigger autocomplete" },
|
|
955
|
+
{ keys: ["Ctrl+S", "Cmd+S"], description: "Save query to local storage" },
|
|
956
|
+
{ keys: ["Ctrl+Shift+F", "Cmd+Shift+F"], description: "Format query" },
|
|
957
|
+
{ keys: ["Ctrl+/", "Cmd+/"], description: "Toggle comment on selected lines" },
|
|
958
|
+
{ keys: ["Ctrl+Shift+D", "Cmd+Shift+D"], description: "Duplicate current line" },
|
|
959
|
+
{ keys: ["Ctrl+Shift+K", "Cmd+Shift+K"], description: "Delete current line" },
|
|
960
|
+
{ keys: ["Esc"], description: "Remove focus from editor" },
|
|
961
|
+
{ keys: ["Ctrl+Click"], description: "Explore URI connections (on URI)" },
|
|
962
|
+
],
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
category: "Fullscreen",
|
|
966
|
+
shortcuts: [
|
|
967
|
+
{ keys: ["F11"], description: "Toggle YASQE (editor) fullscreen" },
|
|
968
|
+
{ keys: ["F10"], description: "Toggle YASR (results) fullscreen" },
|
|
969
|
+
{ keys: ["F9"], description: "Switch between YASQE and YASR fullscreen" },
|
|
970
|
+
{ keys: ["Esc"], description: "Exit fullscreen mode" },
|
|
971
|
+
],
|
|
972
|
+
},
|
|
973
|
+
];
|
|
974
|
+
|
|
975
|
+
shortcutsData.forEach((section) => {
|
|
976
|
+
const sectionEl = document.createElement("div");
|
|
977
|
+
addClass(sectionEl, "shortcutsSection");
|
|
978
|
+
|
|
979
|
+
const categoryLabel = document.createElement("h3");
|
|
980
|
+
categoryLabel.textContent = section.category;
|
|
981
|
+
addClass(categoryLabel, "shortcutsCategory");
|
|
982
|
+
sectionEl.appendChild(categoryLabel);
|
|
983
|
+
|
|
984
|
+
const table = document.createElement("table");
|
|
985
|
+
addClass(table, "shortcutsTable");
|
|
986
|
+
table.setAttribute("role", "table");
|
|
987
|
+
table.setAttribute("aria-label", `${section.category} keyboard shortcuts`);
|
|
988
|
+
|
|
989
|
+
// Add table caption for screen readers
|
|
990
|
+
const caption = document.createElement("caption");
|
|
991
|
+
caption.textContent = `${section.category} keyboard shortcuts`;
|
|
992
|
+
caption.style.position = "absolute";
|
|
993
|
+
caption.style.left = "-10000px";
|
|
994
|
+
caption.style.width = "1px";
|
|
995
|
+
caption.style.height = "1px";
|
|
996
|
+
caption.style.overflow = "hidden";
|
|
997
|
+
table.appendChild(caption);
|
|
998
|
+
|
|
999
|
+
// Add thead with proper headers
|
|
1000
|
+
const thead = document.createElement("thead");
|
|
1001
|
+
const headerRow = document.createElement("tr");
|
|
1002
|
+
|
|
1003
|
+
const keysHeader = document.createElement("th");
|
|
1004
|
+
keysHeader.textContent = "Keys";
|
|
1005
|
+
keysHeader.setAttribute("scope", "col");
|
|
1006
|
+
addClass(keysHeader, "shortcutsKeysHeader");
|
|
1007
|
+
headerRow.appendChild(keysHeader);
|
|
1008
|
+
|
|
1009
|
+
const descHeader = document.createElement("th");
|
|
1010
|
+
descHeader.textContent = "Description";
|
|
1011
|
+
descHeader.setAttribute("scope", "col");
|
|
1012
|
+
addClass(descHeader, "shortcutsDescHeader");
|
|
1013
|
+
headerRow.appendChild(descHeader);
|
|
1014
|
+
|
|
1015
|
+
thead.appendChild(headerRow);
|
|
1016
|
+
table.appendChild(thead);
|
|
1017
|
+
|
|
1018
|
+
// Add tbody
|
|
1019
|
+
const tbody = document.createElement("tbody");
|
|
1020
|
+
|
|
1021
|
+
section.shortcuts.forEach((shortcut) => {
|
|
1022
|
+
const row = document.createElement("tr");
|
|
1023
|
+
|
|
1024
|
+
const keysCell = document.createElement("td");
|
|
1025
|
+
addClass(keysCell, "shortcutsKeys");
|
|
1026
|
+
shortcut.keys.forEach((key, index) => {
|
|
1027
|
+
if (index > 0) {
|
|
1028
|
+
const separator = document.createElement("span");
|
|
1029
|
+
separator.textContent = " / ";
|
|
1030
|
+
addClass(separator, "shortcutsSeparator");
|
|
1031
|
+
keysCell.appendChild(separator);
|
|
1032
|
+
}
|
|
1033
|
+
const kbd = document.createElement("kbd");
|
|
1034
|
+
kbd.textContent = key;
|
|
1035
|
+
keysCell.appendChild(kbd);
|
|
1036
|
+
});
|
|
1037
|
+
row.appendChild(keysCell);
|
|
1038
|
+
|
|
1039
|
+
const descCell = document.createElement("td");
|
|
1040
|
+
addClass(descCell, "shortcutsDescription");
|
|
1041
|
+
descCell.textContent = shortcut.description;
|
|
1042
|
+
row.appendChild(descCell);
|
|
1043
|
+
|
|
1044
|
+
tbody.appendChild(row);
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
table.appendChild(tbody);
|
|
1048
|
+
|
|
1049
|
+
sectionEl.appendChild(table);
|
|
1050
|
+
container.appendChild(sectionEl);
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
|
|
888
1054
|
private async importConfiguration(turtleContent: string) {
|
|
889
1055
|
try {
|
|
890
1056
|
const parsedConfig = ConfigExportImport.parseFromTurtle(turtleContent);
|
|
@@ -940,6 +1106,108 @@ export default class TabSettingsModal {
|
|
|
940
1106
|
}, 5000);
|
|
941
1107
|
}
|
|
942
1108
|
|
|
1109
|
+
private drawAboutSettings(container: HTMLElement) {
|
|
1110
|
+
// About Section
|
|
1111
|
+
const aboutSection = document.createElement("div");
|
|
1112
|
+
addClass(aboutSection, "settingsSection", "aboutSection");
|
|
1113
|
+
|
|
1114
|
+
// YASGUI Title and Version
|
|
1115
|
+
const titleContainer = document.createElement("div");
|
|
1116
|
+
addClass(titleContainer, "aboutTitle");
|
|
1117
|
+
|
|
1118
|
+
const title = document.createElement("h3");
|
|
1119
|
+
title.textContent = "YASGUI";
|
|
1120
|
+
addClass(title, "aboutMainTitle");
|
|
1121
|
+
|
|
1122
|
+
const versionBadge = document.createElement("span");
|
|
1123
|
+
versionBadge.textContent = `v${VERSION}`;
|
|
1124
|
+
addClass(versionBadge, "versionBadge");
|
|
1125
|
+
|
|
1126
|
+
titleContainer.appendChild(title);
|
|
1127
|
+
titleContainer.appendChild(versionBadge);
|
|
1128
|
+
aboutSection.appendChild(titleContainer);
|
|
1129
|
+
|
|
1130
|
+
// Subtitle
|
|
1131
|
+
const subtitle = document.createElement("p");
|
|
1132
|
+
subtitle.textContent = "Yet Another SPARQL GUI";
|
|
1133
|
+
addClass(subtitle, "aboutSubtitle");
|
|
1134
|
+
aboutSection.appendChild(subtitle);
|
|
1135
|
+
|
|
1136
|
+
// Links Section
|
|
1137
|
+
const linksSection = document.createElement("div");
|
|
1138
|
+
addClass(linksSection, "aboutLinks");
|
|
1139
|
+
|
|
1140
|
+
// Documentation Link
|
|
1141
|
+
const docsLink = this.createAboutLink(
|
|
1142
|
+
"📚 Documentation",
|
|
1143
|
+
"https://yasgui-doc.matdata.eu/docs/",
|
|
1144
|
+
"View the complete documentation and guides",
|
|
1145
|
+
);
|
|
1146
|
+
linksSection.appendChild(docsLink);
|
|
1147
|
+
|
|
1148
|
+
// Release Notes Link
|
|
1149
|
+
const releasesLink = this.createAboutLink(
|
|
1150
|
+
"📝 Release Notes",
|
|
1151
|
+
"https://github.com/Matdata-eu/Yasgui/releases",
|
|
1152
|
+
"See what's new in the latest releases",
|
|
1153
|
+
);
|
|
1154
|
+
linksSection.appendChild(releasesLink);
|
|
1155
|
+
|
|
1156
|
+
// Issues/Support Link
|
|
1157
|
+
const issuesLink = this.createAboutLink(
|
|
1158
|
+
"🐛 Report Issues & Get Support",
|
|
1159
|
+
"https://github.com/Matdata-eu/Yasgui/issues",
|
|
1160
|
+
"Report bugs, request features, or ask for help",
|
|
1161
|
+
);
|
|
1162
|
+
linksSection.appendChild(issuesLink);
|
|
1163
|
+
|
|
1164
|
+
aboutSection.appendChild(linksSection);
|
|
1165
|
+
|
|
1166
|
+
// Footer info
|
|
1167
|
+
const footerInfo = document.createElement("div");
|
|
1168
|
+
addClass(footerInfo, "aboutFooter");
|
|
1169
|
+
|
|
1170
|
+
const paragraph1 = document.createElement("p");
|
|
1171
|
+
paragraph1.textContent = "YASGUI is an open-source project maintained by ";
|
|
1172
|
+
const matdataLink = document.createElement("a");
|
|
1173
|
+
matdataLink.href = "https://matdata.eu";
|
|
1174
|
+
matdataLink.target = "_blank";
|
|
1175
|
+
matdataLink.rel = "noopener noreferrer";
|
|
1176
|
+
matdataLink.textContent = "Matdata";
|
|
1177
|
+
paragraph1.appendChild(matdataLink);
|
|
1178
|
+
paragraph1.appendChild(document.createTextNode("."));
|
|
1179
|
+
|
|
1180
|
+
const paragraph2 = document.createElement("p");
|
|
1181
|
+
paragraph2.textContent = "Licensed under the MIT License.";
|
|
1182
|
+
|
|
1183
|
+
footerInfo.appendChild(paragraph1);
|
|
1184
|
+
footerInfo.appendChild(paragraph2);
|
|
1185
|
+
aboutSection.appendChild(footerInfo);
|
|
1186
|
+
|
|
1187
|
+
container.appendChild(aboutSection);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
private createAboutLink(label: string, url: string, description: string): HTMLElement {
|
|
1191
|
+
const linkContainer = document.createElement("div");
|
|
1192
|
+
addClass(linkContainer, "aboutLinkItem");
|
|
1193
|
+
|
|
1194
|
+
const link = document.createElement("a");
|
|
1195
|
+
link.href = url;
|
|
1196
|
+
link.target = "_blank";
|
|
1197
|
+
link.rel = "noopener noreferrer";
|
|
1198
|
+
link.textContent = label;
|
|
1199
|
+
addClass(link, "aboutLink");
|
|
1200
|
+
|
|
1201
|
+
const desc = document.createElement("p");
|
|
1202
|
+
desc.textContent = description;
|
|
1203
|
+
addClass(desc, "aboutLinkDescription");
|
|
1204
|
+
|
|
1205
|
+
linkContainer.appendChild(link);
|
|
1206
|
+
linkContainer.appendChild(desc);
|
|
1207
|
+
|
|
1208
|
+
return linkContainer;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
943
1211
|
public destroy() {
|
|
944
1212
|
if (this.modalOverlay && this.modalOverlay.parentNode) {
|
|
945
1213
|
this.modalOverlay.parentNode.removeChild(this.modalOverlay);
|
package/src/tab.scss
CHANGED
|
@@ -36,15 +36,13 @@
|
|
|
36
36
|
gap: 10px;
|
|
37
37
|
// Allow flexible height - can use 100vh or be constrained by parent
|
|
38
38
|
min-height: var(--yasgui-min-height);
|
|
39
|
-
height: calc(100vh - var(--yasgui-header-height));
|
|
39
|
+
max-height: calc(100vh - var(--yasgui-header-height));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.editorwrapper {
|
|
43
43
|
flex: 1;
|
|
44
|
-
min-width: 0;
|
|
45
44
|
display: flex;
|
|
46
45
|
flex-direction: column;
|
|
47
|
-
overflow: hidden;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
// Make YASQE fill the vertical space in horizontal mode
|
|
@@ -53,9 +51,10 @@
|
|
|
53
51
|
flex-direction: column;
|
|
54
52
|
flex: 1;
|
|
55
53
|
min-height: 0;
|
|
54
|
+
overflow: hidden;
|
|
56
55
|
|
|
57
56
|
.CodeMirror {
|
|
58
|
-
height:
|
|
57
|
+
height: calc(100vh - var(--yasgui-header-height)) !important;
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
|
package/src/themes.scss
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
--yasgui-match-highlight-bg: #dbdeed;
|
|
40
40
|
|
|
41
41
|
// Layout dimensions (used for horizontal orientation)
|
|
42
|
-
--yasgui-header-height:
|
|
42
|
+
--yasgui-header-height: 150px; // Height to subtract from viewport in horizontal layout
|
|
43
43
|
--yasgui-min-height: 400px; // Minimum height for horizontal layout panels
|
|
44
44
|
|
|
45
45
|
--yasgui-endpoint-button-bg: #337ab7;
|
package/src/version.ts
ADDED