From b973c186cbd86a6f545de23093287d1428cb212c Mon Sep 17 00:00:00 2001 From: Nathan Zimmerman Date: Tue, 17 Oct 2023 18:17:47 -0500 Subject: [PATCH 1/8] Working syntax highlighting --- package.json | 3 + src/StacBrowser.vue | 8 +- src/components/CodeBox.vue | 56 +++++++++++++ src/views/Search.vue | 165 ++++++++++++++++++++++++++++++------- 4 files changed, 199 insertions(+), 33 deletions(-) create mode 100644 src/components/CodeBox.vue diff --git a/package.json b/package.json index 34fdc1a9a..10c89d556 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,10 @@ "bootstrap-vue": "^2.21.2", "bs58": "^4.0.1", "chart.js": "^4.3.0", + "clipboard": "^2.0.11", "commonmark": "^0.29.3", "core-js": "^3.6.5", + "highlight.js": "^11.9.0", "leaflet": "^1.8.0", "node-polyfill-webpack-plugin": "^2.0.0", "remove-markdown": "^0.5.0", @@ -51,6 +53,7 @@ "v-clipboard": "^3.0.0-next.1", "vue": "^2.6.12", "vue-chartjs": "^5.2.0", + "vue-highlightjs": "^1.3.3", "vue-i18n": "^8.28.2", "vue-multiselect": "^2.1.6", "vue-read-more-smooth": "^0.1.8", diff --git a/src/StacBrowser.vue b/src/StacBrowser.vue index f516c71e6..2809ac324 100644 --- a/src/StacBrowser.vue +++ b/src/StacBrowser.vue @@ -35,6 +35,11 @@ import { import "bootstrap/dist/css/bootstrap.css"; import "bootstrap-vue/dist/bootstrap-vue.css"; +import VueHighlightJS from "vue-highlightjs"; +import highlight from 'highlight.js'; +import 'highlight.js/lib/languages/python'; +import 'highlight.js/styles/github.css'; + import ErrorAlert from './components/ErrorAlert.vue'; import StacHeader from './components/StacHeader.vue'; @@ -49,8 +54,9 @@ import { getBest, prepareSupported } from './locale-id'; Vue.use(AlertPlugin); Vue.use(ButtonGroupPlugin); Vue.use(ButtonPlugin); -Vue.use(BadgePlugin); Vue.use(CardPlugin); +Vue.use(BadgePlugin) +Vue.use(VueHighlightJS); Vue.use(LayoutPlugin); Vue.use(SpinnerPlugin); diff --git a/src/components/CodeBox.vue b/src/components/CodeBox.vue new file mode 100644 index 000000000..782a74f8d --- /dev/null +++ b/src/components/CodeBox.vue @@ -0,0 +1,56 @@ + + + + + \ No newline at end of file diff --git a/src/views/Search.vue b/src/views/Search.vue index 4aa0c9a8f..8843988b8 100644 --- a/src/views/Search.vue +++ b/src/views/Search.vue @@ -17,40 +17,58 @@ @input="setFilters" /> + - {{ error }} - - {{ $t('search.modifyCriteria') }} - {{ $t('search.noItemsFound') }} - + {{ error }} + + {{ $t('search.modifyCriteria') }} + {{ $t('search.noItemsFound') }} + @@ -78,6 +96,7 @@ export default { BTab, BTabs, Catalogs: () => import('../components/Catalogs.vue'), + CodeBox: () => import('../components/CodeBox.vue'), Loading, Items: () => import('../components/Items.vue'), Map: () => import('../components/Map.vue'), @@ -102,7 +121,11 @@ export default { itemFilters: {}, collectionFilters: {}, activeSearch: 0, - selectedCollections: {} + selectedCollections: {}, + + pythonCode: null, + javascriptCode: null, + rCode: null }; }, computed: { @@ -237,13 +260,90 @@ export default { } return false; }, + filterString() { + let obj = this.filters || {} + for (let key in obj) { + if (obj[key] === null || (Array.isArray(obj[key]) && obj[key].length === 0)) { + delete obj[key]; + } + } + return JSON.stringify(obj) + }, + generatePython() { + return ` + from pystac_client import Client + + # Connect to STAC API + stac_endpoint = '${this.searchLink.href}' + client = Client.open(stac_endpoint) + + # Build query + query = ${this.filterString()} + + # Perform search + search_result = client.search(query) + ` + }, + generateJavascript() { + return ` + // Define the STAC API endpoint + const STAC_ENDPOINT = '${this.searchLink.href}'; + + // Define your search parameters + const searchParams = ${this.filterString()}; + + // Perform the search + fetch(STAC_ENDPOINT, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(searchParams) + }) + .then(response => response.json()) + .then(data => { + console.log("STAC search results:", data); + }) + .catch(error => { + console.error("Error fetching STAC data:", error); + }); + ` + }, + generateR() { + let filterString = JSON.stringify(this.filters || {}) + return ` + from pystac_client import Client + + # Connect to STAC API + stac_api_url = '${this.searchLink}' + client = Client.open(stac_api_url) + + # Build query + query = ${filterString} + + # Perform search + search_result = client.search(query) + ` + }, + updateCode() { + this.pythonCode = this.generatePython() + this.javascriptCode = this.generateJavascript() + this.rCode = this.generateR() + }, async loadResults(link) { this.error = null; this.loading = true; try { this.link = Utils.addFiltersToLink(link, this.filters, this.itemsPerPage); + console.log("link", this.link) + this.pythonCode = this.generatePython(this.link) + this.javascriptCode = this.generateJavascript(this.link) + this.rCode = this.generateR(this.link) let key = this.isCollectionSearch ? 'collections' : 'features'; + // console.log(1, this.$store) + // console.log(2, this.link) + // console.log(3, key) let response = await stacRequest(this.$store, this.link); if (response) { this.showPage(response.config.url); @@ -274,6 +374,7 @@ export default { } else { await this.loadResults(this.searchLink); + this.updateCode(this.searchLink) } }, showPage(url) { From 36e86dc15fbb051542e850e6a97c66c1c1d595dc Mon Sep 17 00:00:00 2001 From: Nathan Zimmerman Date: Wed, 18 Oct 2023 09:54:12 -0500 Subject: [PATCH 2/8] Break searchbox out into its own component --- src/StacBrowser.vue | 2 +- src/components/SearchCode.vue | 122 ++++++++++++++++++++++++++++++++++ src/views/Search.vue | 97 +-------------------------- 3 files changed, 125 insertions(+), 96 deletions(-) create mode 100644 src/components/SearchCode.vue diff --git a/src/StacBrowser.vue b/src/StacBrowser.vue index 2809ac324..83b59c64b 100644 --- a/src/StacBrowser.vue +++ b/src/StacBrowser.vue @@ -54,8 +54,8 @@ import { getBest, prepareSupported } from './locale-id'; Vue.use(AlertPlugin); Vue.use(ButtonGroupPlugin); Vue.use(ButtonPlugin); -Vue.use(CardPlugin); Vue.use(BadgePlugin) +Vue.use(CardPlugin); Vue.use(VueHighlightJS); Vue.use(LayoutPlugin); Vue.use(SpinnerPlugin); diff --git a/src/components/SearchCode.vue b/src/components/SearchCode.vue new file mode 100644 index 000000000..44b2b589d --- /dev/null +++ b/src/components/SearchCode.vue @@ -0,0 +1,122 @@ + + + + + \ No newline at end of file diff --git a/src/views/Search.vue b/src/views/Search.vue index 8843988b8..329e15163 100644 --- a/src/views/Search.vue +++ b/src/views/Search.vue @@ -28,17 +28,7 @@ @@ -49,4 +56,4 @@ margin: 0; } - \ No newline at end of file + diff --git a/src/components/SearchCode.vue b/src/components/SearchCode.vue index 4bbe3abf0..567b72d2a 100644 --- a/src/components/SearchCode.vue +++ b/src/components/SearchCode.vue @@ -16,36 +16,55 @@ import { BTabs, BTab } from 'bootstrap-vue'; export default { name: "SearchCode", - props: { - catalogHref: String, - filters: Object, - }, components: { BTab, BTabs, CodeBox: () => import('./CodeBox.vue'), }, + props: { + catalogHref: { + type: String, + default: '', + }, + filters: { + type: Object, + default() { + return {}; + }, + }, + }, data() { return { componentId: `${this.language}Content`, pythonCode: null, javascriptCode: null, rCode: null + }; + }, + watch: { + filters: { + deep: true, + handler() { + this.updateCode(); + } } }, + created() { + this.updateCode(); + }, methods: { dedent(str) { const lines = str.split('\n').map(line => line.trim()); return lines.join('\n').trim(); }, filterString() { - let obj = this.filters || {} + let obj = this.filters || {}; for (let key in obj) { if (obj[key] === null || (Array.isArray(obj[key]) && obj[key].length === 0)) { delete obj[key]; } } - return JSON.stringify(obj) + return JSON.stringify(obj); }, generatePython() { return this.dedent(`from pystac_client import Client @@ -58,7 +77,7 @@ query = ${this.filterString()} # Perform search - search_result = client.search(query )`) + search_result = client.search(query )`); }, generateJavascript() { return this.dedent(`// Define the STAC API endpoint @@ -81,7 +100,7 @@ }) .catch(error => { console.error("Error fetching STAC data:", error); - });`) + });`); }, generateR() { return this.dedent(`from pystac_client import Client @@ -94,28 +113,17 @@ query = ${this.filterString()} # Perform search - search_result = client.search(query)`) + search_result = client.search(query)`); }, updateCode() { - console.log(this.generatePython()) - this.pythonCode = this.generatePython() - this.javascriptCode = this.generateJavascript() - this.rCode = this.generateR() + console.log('updating code'); + this.pythonCode = this.generatePython(); + this.javascriptCode = this.generateJavascript(); + this.rCode = this.generateR(); } }, - watch: { - filters: { - deep: true, - handler() { - this.updateCode(); - } - } - }, - mounted() { - this.updateCode(); - }, }; \ No newline at end of file + diff --git a/src/components/SearchFilter.vue b/src/components/SearchFilter.vue index 82cea1fca..afa655cec 100644 --- a/src/components/SearchFilter.vue +++ b/src/components/SearchFilter.vue @@ -112,11 +112,11 @@ {{ $t('submit') }} {{ $t('reset') }} - Example Code + {{ $t('exampleCode') }} - - + + diff --git a/src/locales/en/texts.json b/src/locales/en/texts.json index 1cfd23c68..5f6f0b853 100644 --- a/src/locales/en/texts.json +++ b/src/locales/en/texts.json @@ -94,6 +94,7 @@ "serverError": "The server encountered an issue. @:errors.contactProvider", "unauthorized": "The request lacks credentials, e.g. an API token. Please provide your credentials and try again." }, + "exampleCode": "Example Code", "featureExperimental": "This feature is still experimental and may give unexpected results!", "fullscreen": { "exit": "Exit Fullscreen", diff --git a/src/views/Search.vue b/src/views/Search.vue index 9f70cb93a..0a2dbad19 100644 --- a/src/views/Search.vue +++ b/src/views/Search.vue @@ -7,58 +7,54 @@ - - {{ error }} - - {{ $t('search.modifyCriteria') }} - {{ $t('search.noItemsFound') }} - + {{ error }} + + {{ $t('search.modifyCriteria') }} + {{ $t('search.noItemsFound') }} + @@ -86,7 +82,6 @@ export default { BTab, BTabs, Catalogs: () => import('../components/Catalogs.vue'), - SearchCode: () => import('../components/SearchCode.vue'), Loading, Items: () => import('../components/Items.vue'), Map: () => import('../components/Map.vue'), From 904cb09bc9235eaf9a8bcc1c96e12ae6cb6ae967 Mon Sep 17 00:00:00 2001 From: Stephen Kilbourn Date: Fri, 20 Oct 2023 13:43:54 -0600 Subject: [PATCH 5/8] remove stray console.log --- src/components/SearchCode.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/SearchCode.vue b/src/components/SearchCode.vue index 567b72d2a..c9439d677 100644 --- a/src/components/SearchCode.vue +++ b/src/components/SearchCode.vue @@ -116,7 +116,6 @@ search_result = client.search(query)`); }, updateCode() { - console.log('updating code'); this.pythonCode = this.generatePython(); this.javascriptCode = this.generateJavascript(); this.rCode = this.generateR(); From 7942f015ce551684d4e272f80e9ad45d26926e5a Mon Sep 17 00:00:00 2001 From: Stephen Kilbourn Date: Fri, 20 Oct 2023 13:44:25 -0600 Subject: [PATCH 6/8] remove unused highlight.js import --- package.json | 1 - src/StacBrowser.vue | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 03a9f7a77..2de832e09 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "chart.js": "^4.3.0", "commonmark": "^0.29.3", "core-js": "^3.6.5", - "highlight.js": "^11.9.0", "leaflet": "^1.8.0", "node-polyfill-webpack-plugin": "^2.0.0", "remove-markdown": "^0.5.0", diff --git a/src/StacBrowser.vue b/src/StacBrowser.vue index 83b59c64b..2deafc46d 100644 --- a/src/StacBrowser.vue +++ b/src/StacBrowser.vue @@ -36,7 +36,6 @@ import "bootstrap/dist/css/bootstrap.css"; import "bootstrap-vue/dist/bootstrap-vue.css"; import VueHighlightJS from "vue-highlightjs"; -import highlight from 'highlight.js'; import 'highlight.js/lib/languages/python'; import 'highlight.js/styles/github.css'; @@ -398,4 +397,4 @@ export default { @import '~bootstrap-vue/src/index.scss'; @import "./theme/page.scss"; @import "./theme/custom.scss"; - \ No newline at end of file + From 9f02d73f764d56e371ebf6d5094ae0677d466fc4 Mon Sep 17 00:00:00 2001 From: Stephen Kilbourn Date: Fri, 20 Oct 2023 13:47:01 -0600 Subject: [PATCH 7/8] remove extra space in python query --- src/components/SearchCode.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SearchCode.vue b/src/components/SearchCode.vue index c9439d677..2b1f6ca12 100644 --- a/src/components/SearchCode.vue +++ b/src/components/SearchCode.vue @@ -77,7 +77,7 @@ query = ${this.filterString()} # Perform search - search_result = client.search(query )`); + search_result = client.search(query)`); }, generateJavascript() { return this.dedent(`// Define the STAC API endpoint From 33d7c2c5ae8af72c1de14c0bad9097bb3a3de2f0 Mon Sep 17 00:00:00 2001 From: Nathan Zimmerman Date: Mon, 30 Oct 2023 10:26:33 -0500 Subject: [PATCH 8/8] Remove R tab --- src/components/SearchCode.vue | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/components/SearchCode.vue b/src/components/SearchCode.vue index 2b1f6ca12..f24a06c21 100644 --- a/src/components/SearchCode.vue +++ b/src/components/SearchCode.vue @@ -6,9 +6,6 @@ - - - @@ -89,9 +86,7 @@ // Perform the search fetch(STAC_ENDPOINT, { method: "POST", - headers: { - "Content-Type": "application/json" - }, + headers: { "Content-Type": "application/json" }, body: JSON.stringify(searchParams) }) .then(response => response.json()) @@ -102,23 +97,9 @@ console.error("Error fetching STAC data:", error); });`); }, - generateR() { - return this.dedent(`from pystac_client import Client - - # Connect to STAC API - stac_api_url = '${this.catalogHref}' - client = Client.open(stac_api_url) - - # Build query - query = ${this.filterString()} - - # Perform search - search_result = client.search(query)`); - }, updateCode() { this.pythonCode = this.generatePython(); this.javascriptCode = this.generateJavascript(); - this.rCode = this.generateR(); } }, };