@@ -19,6 +19,7 @@ import {
1919 getServiceUriForCursorPosition ,
2020 compressUri ,
2121 defaultPrefixes ,
22+ generateTabLabel ,
2223 getClassesFallback ,
2324 getPredicatesFallback ,
2425} from "./utils" ;
@@ -69,7 +70,7 @@ export class SparqlEditor extends HTMLElement {
6970 throw new Error ( "No endpoint provided. Please use the 'endpoint' attribute to specify the SPARQL endpoint URL." ) ;
7071
7172 this . addLimit = Number ( this . getAttribute ( "add-limit" ) ) || null ;
72- this . examplesOnMainPage = Number ( this . getAttribute ( "examples-on-main-page" ) ) || 10 ;
73+ this . examplesOnMainPage = Number ( this . getAttribute ( "examples-on-main-page" ) ) || 8 ;
7374 this . examplesRepoAddUrl = this . getAttribute ( "examples-repo-add-url" ) ;
7475 this . examplesRepo = this . getAttribute ( "examples-repository" ) ;
7576 if ( this . examplesRepoAddUrl && ! this . examplesRepo ) this . examplesRepo = this . examplesRepoAddUrl . split ( "/new/" ) [ 0 ] ;
@@ -88,23 +89,20 @@ export class SparqlEditor extends HTMLElement {
8889 }
8990 this . className = "sparql-editor-container" ;
9091 this . innerHTML = `
91- <div id="sparql-text-editor ">
92+ <div style="width: 100%; ">
9293 <a id="status-link" href="" target="_blank" title="Loading..." style="display: inline-flex; width: 16px; height: 16px;">
9394 <div id="status-light" style="width: 10px; height: 10px; background-color: purple; border-radius: 50%; margin: 0 auto;"></div>
9495 </a>
9596 <button id="sparql-add-prefixes-btn" class="btn" style="margin-bottom: 0.3em;">Add common prefixes</button>
9697 <button id="sparql-save-example-btn" class="btn" style="margin-bottom: 0.3em;">Save query as example</button>
98+ <button id="sparql-examples-top-btn" class="btn" style="margin-bottom: 0.3em;">Browse examples</button>
9799 <button id="sparql-clear-cache-btn" class="btn" style="margin-bottom: 0.3em;">Clear cache</button>
98100 <div id="yasgui"></div>
99101 <div id="loading-spinner" style="display: flex; justify-content: center; align-items: center; height: 100px; flex-direction: column;">
100102 <div class="spinner" style="border: 4px solid rgba(0,0,0,0.1); border-left-color: #000; border-radius: 50%; width: 24px; height: 24px; animation: spin 1s linear infinite;"></div>
101103 <p style="margin-top: 10px; text-align: center;">Loading editor...</p>
102104 </div>
103105 </div>
104- <div>
105- <div id="sparql-examples"></div>
106- <slot></slot>
107- </div>
108106 ` ;
109107 this . appendChild ( style ) ;
110108
@@ -181,13 +179,14 @@ export class SparqlEditor extends HTMLElement {
181179 }
182180
183181 // Load current endpoint in the YASGUI input box
184- async loadCurrentEndpoint ( endpoint : string = this . endpointUrl ( ) ) {
182+ async loadCurrentEndpoint ( endpoint : string = this . endpointUrl ( ) , forceExamplesReload : boolean = false ) {
185183 // console.log("Switching endpoint", endpoint);
186184 await this . getMetadata ( endpoint ) ;
187- await this . showExamples ( ) ;
185+ await this . showExamples ( forceExamplesReload ) ;
188186 // @ts -ignore set default query when new tab
189187 this . yasgui . config . yasqe . value =
190188 this . addPrefixesToQuery ( this . currentEndpoint ( ) . examples [ 0 ] ?. query ) || Yasgui . Yasqe . defaults . value ;
189+
191190 Yasgui . Yasr . defaults . prefixes = this . meta [ endpoint ] . prefixes ;
192191 // Update the statusLight
193192 const statusLight = this . querySelector ( "#status-light" ) as HTMLElement ;
@@ -245,7 +244,10 @@ export class SparqlEditor extends HTMLElement {
245244 setTimeout ( ( ) => this . loadCurrentEndpoint ( ) ) ;
246245 } ) ;
247246 this . yasgui ?. on ( "endpointHistoryChange" , ( ) => {
248- setTimeout ( ( ) => this . loadCurrentEndpoint ( ) ) ;
247+ setTimeout ( ( ) => this . loadCurrentEndpoint ( this . endpointUrl ( ) , true ) ) ;
248+ } ) ;
249+ this . yasgui ?. on ( "tabAdd" , ( ) => {
250+ setTimeout ( ( ) => this . showExamples ( ) ) ;
249251 } ) ;
250252
251253 // Button to clear and update cache of SPARQL endpoints metadata
@@ -554,20 +556,37 @@ ex:${exampleUri} a sh:SPARQLExecutable${
554556 }
555557 }
556558
557- async showExamples ( ) {
559+ async showExamples ( forceReload : boolean = false ) {
558560 // Display examples on the main page and in a dialog for the currently selected endpoint
559- const exampleQueriesEl = this . querySelector ( "#sparql-examples" ) as HTMLElement ;
561+ const existingExampleQueriesEl = this . querySelector ( ".active .sparql-examples" ) as HTMLButtonElement ;
562+ const examplesTopBtnEl = this . querySelector ( "#sparql-examples-top-btn" ) as HTMLButtonElement ;
563+ const btnTextContent = `Browse ${ this . currentEndpoint ( ) . examples . length } examples` ;
564+ if ( this . currentEndpoint ( ) . examples . length === 0 ) {
565+ existingExampleQueriesEl ?. remove ( ) ;
566+ examplesTopBtnEl . style . display = "none" ;
567+ return ;
568+ } else {
569+ examplesTopBtnEl . textContent = btnTextContent ;
570+ examplesTopBtnEl . style . display = "inline-block" ;
571+ }
572+ if ( existingExampleQueriesEl && ! forceReload ) {
573+ return ;
574+ }
575+ if ( existingExampleQueriesEl ) existingExampleQueriesEl ?. remove ( ) ;
576+ const yasqeEl = this . querySelector ( ".active .yasqe" ) as HTMLElement ;
577+ const yasqeElParent = yasqeEl . parentElement as HTMLElement ;
578+ const exampleQueriesEl = document . createElement ( "div" ) ;
579+ exampleQueriesEl . className = "sparql-examples" ;
560580 exampleQueriesEl . innerHTML = "" ;
561- if ( this . currentEndpoint ( ) . examples . length === 0 ) return ;
562- // Add title for examples
563- const exQueryTitleDiv = document . createElement ( "div" ) ;
564- exQueryTitleDiv . style . textAlign = "center" ;
565- const exQueryTitle = document . createElement ( "h3" ) ;
566- exQueryTitle . style . margin = "0.1em" ;
567- exQueryTitle . style . fontWeight = "200" ;
568- exQueryTitle . textContent = "Examples" ;
569- exQueryTitleDiv . appendChild ( exQueryTitle ) ;
570- exampleQueriesEl . appendChild ( exQueryTitleDiv ) ;
581+ // TODO: remove title for examples?
582+ // const exQueryTitleDiv = document.createElement("div");
583+ // exQueryTitleDiv.style.textAlign = "center";
584+ // const exQueryTitle = document.createElement("h3");
585+ // exQueryTitle.style.margin = "0.1em";
586+ // exQueryTitle.style.fontWeight = "200";
587+ // exQueryTitle.textContent = "Examples";
588+ // exQueryTitleDiv.appendChild(exQueryTitle);
589+ // exampleQueriesEl.appendChild(exQueryTitleDiv);
571590
572591 // Create dialog for examples
573592 const exQueryDialog = document . createElement ( "dialog" ) ;
@@ -586,7 +605,7 @@ ex:${exampleUri} a sh:SPARQLExecutable${
586605 exDialogCloseBtn . style . top = "1.5em" ;
587606 exDialogCloseBtn . style . right = "2em" ;
588607 exQueryDialog . appendChild ( exDialogCloseBtn ) ;
589- exampleQueriesEl . appendChild ( exQueryDialog ) ;
608+ yasqeElParent . appendChild ( exQueryDialog ) ;
590609
591610 // Add examples to the main page and dialog
592611 this . currentEndpoint ( ) . examples . forEach ( async ( example , index ) => {
@@ -601,7 +620,7 @@ ex:${exampleUri} a sh:SPARQLExecutable${
601620 useBtn . style . marginLeft = "0.5em" ;
602621 useBtn . className = "btn sparqlExampleButton" ;
603622 useBtn . addEventListener ( "click" , ( ) => {
604- this . addTab ( example . query , index ) ;
623+ this . addTab ( example . query , example . comment ) ;
605624 exQueryDialog . close ( ) ;
606625 } ) ;
607626 exQueryP . appendChild ( useBtn ) ;
@@ -614,7 +633,7 @@ ex:${exampleUri} a sh:SPARQLExecutable${
614633 cloneExQueryDiv . className = "main-query-example" ;
615634 // Cloning does not include click event so we need to redo it :(
616635 cloneExQueryDiv . lastChild ?. lastChild ?. addEventListener ( "click" , ( ) => {
617- this . addTab ( example . query , index ) ;
636+ this . addTab ( example . query , example . comment ) ;
618637 } ) ;
619638 exampleQueriesEl . appendChild ( cloneExQueryDiv ) ;
620639 }
@@ -650,10 +669,14 @@ ex:${exampleUri} a sh:SPARQLExecutable${
650669
651670 // Add button to open dialog
652671 const openExDialogBtn = document . createElement ( "button" ) ;
653- openExDialogBtn . textContent = `Browse ${ this . currentEndpoint ( ) . examples . length } examples` ;
672+ openExDialogBtn . textContent = btnTextContent ;
654673 openExDialogBtn . className = "btn" ;
655674 exampleQueriesEl . appendChild ( openExDialogBtn ) ;
656675
676+ examplesTopBtnEl . addEventListener ( "click" , ( ) => {
677+ exQueryDialog . showModal ( ) ;
678+ document . body . style . overflow = "hidden" ;
679+ } ) ;
657680 openExDialogBtn . addEventListener ( "click" , ( ) => {
658681 exQueryDialog . showModal ( ) ;
659682 document . body . style . overflow = "hidden" ;
@@ -665,6 +688,20 @@ ex:${exampleUri} a sh:SPARQLExecutable${
665688 exQueryDialog . addEventListener ( "close" , ( ) => {
666689 document . body . style . overflow = "" ;
667690 } ) ;
691+
692+ // Add the examples next to the YASQE editor
693+ // yasqeEl.style.height = "100%";
694+ yasqeEl . style . width = "100%" ;
695+ exampleQueriesEl . style . width = "50%" ;
696+ yasqeElParent . style . display = "flex" ;
697+ yasqeElParent . appendChild ( exampleQueriesEl ) ;
698+ const yasqe = this . yasgui ?. getTab ( ) ?. getYasqe ( ) ;
699+ yasqe ?. expandEditor ( ) ;
700+ // if (exampleQueriesEl.offsetHeight > 0) {
701+ // Yasgui.Yasqe.defaults.editorHeight = `${exampleQueriesEl.offsetHeight}px`;
702+ // const yasqe = this.yasgui?.getTab()?.getYasqe();
703+ // yasqe?.expandEditor();
704+ // }
668705 }
669706
670707 addPrefixesToQuery ( query : string ) {
@@ -698,10 +735,10 @@ ex:${exampleUri} a sh:SPARQLExecutable${
698735 }
699736 }
700737
701- addTab ( query : string , index : number ) {
738+ addTab ( query : string , label : string ) {
702739 this . yasgui ?. addTab ( true , {
703740 ...Yasgui . Tab . getDefaults ( ) ,
704- name : `Query ${ index + 1 } ` ,
741+ name : generateTabLabel ( label ) ,
705742 requestConfig : {
706743 ...Yasgui . defaults . requestConfig ,
707744 endpoint : this . endpointUrl ( ) ,
0 commit comments