Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ yarn.lock
sparql-test
errors/
# local env files
.env
.env.local
.env.*.local
# Never commit real secrets (local dev overrides)
Expand Down
19 changes: 19 additions & 0 deletions client/public/config/config_qlever_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
MAPBOX_API_KEY: pk.eyJ1IjoidmFsZW50aW5lZHd2IiwiYSI6ImNscnNoNmFncjA3OHcycW8zNXJ4Z3BkNTAifQ.XvgsPncdJRXKsODCheRANA
API_URL: https://qlever-test.geocodes-aws-dev.earthcube.org/ec/api
TENANT_URL: https://oss.geocodes-aws-dev.earthcube.org/test/scheduler/configs/test/tenant.yaml
TRIPLESTORE_URL: https://graph.geocodes-aws.earthcube.org/blazegraph/namespace/earthcube/sparql
ECRR_TRIPLESTORE_URL: http://132.249.238.169:8080/fuseki/ecrr/query
SUMMARYSTORE_URL: https://graph.geocodes-aws.earthcube.org/blazegraph/namespace/earthcube_summary/sparql
S3_REPORTS_URL: https://oss.geocodes-aws.earthcube.org/decoder/reports/
COMMUNITY: all
BLAZEGRAPH_TIMEOUT: 20
ECRR_GRAPH: http://earthcube.org/gleaner-summoned
THROUGHPUTDB_URL: https://throughputdb.com/api/ccdrs/annotations
SPARQL_QUERY: queries/sparql_query.txt
SPARQL_HASTOOLS: queries/sparql_hastools.txt
SPARQL_TOOLS_WEBSERVICE: queries/sparql_gettools_webservice.txt
SPARQL_TOOLS_DOWNLOAD: queries/sparql_gettools_download.txt
JSONLD_PROXY: https://qlever-test.geocodes-aws-dev.earthcube.org/ec/api${o}
SPARQL_NB: https://geocodes-aws.earthcube.org/notebook/mkQ?q=${q}
SPARQL_YASGUI: https://sparqlgui.geocodes-aws.earthcube.org/?
8 changes: 7 additions & 1 deletion client/public/queries/blazegraph/sparql_query.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ PREFIX bds: <http://www.bigdata.com/rdf/search#>
OPTIONAL {?g schema:date ?datep .}
OPTIONAL {?g schema:publisher ?pubname .}
OPTIONAL {?g schema:place ?placenames .}
OPTIONAL {?g schema:keywords ?kw .}
OPTIONAL {
{ ?g schema:keywords ?kw .
FILTER (isLiteral(?kw)) }
UNION
{ ?g schema:keywords ?kwTerm .
?kwTerm schema:name ?kw . }
}

}
GROUP BY ?g ?pubname ?placenames ?kw ?datep ?disurl ?score ?name ?description ?resourceType
Expand Down
8 changes: 7 additions & 1 deletion client/public/queries/blazegraph/sparql_query_2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ SELECT distinct ?subj ?g ?resourceType ?name ?description ?pubname
OPTIONAL {?subj schema:publisher/schema:name|sschema:publisher/sschema:name|sschema:sdPublisher|sschema:provider/schema:name ?pubname .}
OPTIONAL {?subj schema:spatialCoverage/schema:name|sschema:spatialCoverage/sschema:name ?placename .}

OPTIONAL {?subj schema:keywords|sschema:keywords ?kwu .}
OPTIONAL {
{ ?subj schema:keywords|sschema:keywords ?kwu .
FILTER (isLiteral(?kwu)) }
UNION
{ ?subj schema:keywords|sschema:keywords ?kwTerm .
?kwTerm schema:name|sschema:name ?kwu . }
}

}
GROUP BY
Expand Down
8 changes: 7 additions & 1 deletion client/src/assets/sparql_blaze/sparql_query.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ SELECT distinct ?subj ?g ?resourceType ?name ?description ?pubname (GROUP_CONCA
OPTIONAL {?subj schema:spatialCoverage/schema:name|sschema:spatialCoverage/sschema:name ?placename .}
OPTIONAL {?subj schema:spatialCoverage/schema:geo/schema:latitude|sschema:spatialCoverage/sschema:geo/schema:latitude ?lat .}
OPTIONAL {?subj schema:spatialCoverage/schema:geo/schema:longitude|sschema:spatialCoverage/sschema:geo/schema:longitude ?lon .}
OPTIONAL {?subj schema:keywords|sschema:keywords ?kwu .}
OPTIONAL {
{ ?subj schema:keywords|sschema:keywords ?kwu .
FILTER (isLiteral(?kwu)) }
UNION
{ ?subj schema:keywords|sschema:keywords ?kwTerm .
?kwTerm schema:name|sschema:name ?kwu . }
}

}
GROUP BY ?subj ?pubname ?placenames ?kw ?datep ?disurl ?score ?name ?description ?resourceType ?g ?minlat ?maxlat ?minlon ?maxlon
Expand Down
173 changes: 154 additions & 19 deletions client/src/components/dataset/dataset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
</div>

<div v-if="mapping.s_datePublished" class="metadata">
<div class="label">Date</div>
<div class="label">Publication Date</div>
<div class="value">{{ mapping.s_datePublished }}</div>
</div>

Expand All @@ -151,10 +151,28 @@
<div class="value" v-html="formatCitation(mapping)"></div>
</div>

<div v-if="mapping.s_providers?.length" class="metadata">
<div class="label">Providers</div>
<div class="value">
<div v-for="(p, i) in mapping.s_providers" :key="i">
<a :href="p.url" target="_blank" rel="noopener">{{ p.name }}</a>
</div>
</div>
</div>

<div v-if="mapping.s_keywords?.length" class="metadata">
<div class="label">Keywords</div>
<div class="value">
{{ mapping.s_keywords.join(", ") }}
<span v-for="(kw, idx) in mapping.s_keywords" :key="idx">
<template v-if="typeof kw === 'object' && kw !== null">
<a v-if="kw.url" :href="kw.url" target="_blank" rel="noopener" class="keyword-link">
{{ kw.name }}
</a>
<span v-else>{{ kw.name }}</span>
</template>
<span v-else>{{ kw }}</span>
<span v-if="idx < mapping.s_keywords.length - 1">, </span>
</span>
</div>
</div>

Expand Down Expand Up @@ -410,7 +428,6 @@ export default {
raw_json: "",
mappings: [],
geolink: "",

collapsedIndices: [], // keeps track of collapsed panels
};
},
Expand Down Expand Up @@ -624,7 +641,32 @@ export default {
}
this.name = jp["name"];
this.description = jp["description"];
this.keywords = jp["keywords"];

// Handle keywords - can be strings or DefinedTerm objects
const rawKeywords = jp["keywords"];
if (rawKeywords) {
const arr = Array.isArray(rawKeywords) ? rawKeywords : [rawKeywords];
this.keywords = arr.map((kw) => {
// If it's a string, return as is
if (typeof kw === "string") {
return kw;
}

// If it's a DefinedTerm object, extract name
if (typeof kw === "object" && kw !== null) {
const name =
(hasSchemaProperty("name", kw) ? schemaItem("name", kw) : "") ||
kw.name ||
"";
return name || String(kw);
}

return String(kw);
}).filter(Boolean);
} else {
this.keywords = [];
}

this.vocab = jp["@vocab"];
this.geolink = jp["geolink"];

Expand Down Expand Up @@ -730,12 +772,104 @@ export default {
mapping.has_citation = true;
}

const rawKw = schemaItem("keywords", dataset);
mapping.s_keywords = Array.isArray(rawKw)
? rawKw
: rawKw != null && rawKw !== ""
? [String(rawKw)]
: [];
// Keywords
if (hasSchemaProperty("keywords", dataset)) {
const c = schemaItem("keywords", dataset);
const arr = Array.isArray(c) ? c : [c];

// Handle both string keywords and DefinedTerm objects
mapping.s_keywords = arr.map((kw) => {
// If it's a string, return as is
if (typeof kw === "string") {
return kw;
}

// If it's a DefinedTerm object, extract name and optionally URL
if (typeof kw === "object" && kw !== null) {
// Try multiple ways to get the name
let name = "";
if (hasSchemaProperty("name", kw)) {
name = schemaItem("name", kw);
} else if (kw.name) {
name = kw.name;
} else if (typeof kw === "object" && "@value" in kw) {
// Handle JSON-LD value objects
name = kw["@value"];
}

// Try multiple ways to get the URL
let url = "";
if (hasSchemaProperty("url", kw)) {
url = schemaItem("url", kw);
} else if (kw.url) {
url = kw.url;
} else if (kw["@id"]) {
url = kw["@id"];
}

// Return object with name and url if available
if (name) {
return { name: String(name), url: url || null };
} else if (url) {
// If we have a URL but no name, use the URL as the name
return { name: url, url: url };
}
}

// Fallback: try to stringify if it's something else
// This handles cases where the object doesn't have expected structure
try {
return String(kw);
} catch (e) {
return "[Invalid Keyword]";
}
}).filter((kw) => {
// Filter out invalid keywords
if (!kw || kw === "[Invalid Keyword]") return false;
// Keep strings
if (typeof kw === "string") return true;
// Keep objects that have a name property
if (typeof kw === "object" && kw !== null && kw.name) return true;
return false;
});
}

// Providers: keep only {name, url} (support provider/providers; string or object)
if (hasSchemaProperty("providers", dataset) || hasSchemaProperty("provider", dataset)) {
const raw = hasSchemaProperty("providers", dataset)
? schemaItem("providers", dataset)
: schemaItem("provider", dataset);

const arr = Array.isArray(raw) ? raw : [raw];

const toProvider = (p) => {
if (!p) return null;

// if it ever comes in as a string, we can't reliably split name/url
if (typeof p === "string") {
return { name: p, url: p }; // best-effort: link to itself
}

const name =
(hasSchemaProperty("name", p) ? schemaItem("name", p) : "") ||
(hasSchemaProperty("legalName", p) ? schemaItem("legalName", p) : "") ||
p.name ||
p.legalName ||
"";

const url =
(hasSchemaProperty("url", p) ? schemaItem("url", p) : "") ||
p.url ||
p["@id"] ||
"";

if (!name && !url) return null;
return { name: name || url, url: url || name };
};

mapping.s_providers = arr.map(toProvider).filter(Boolean);
}

mapping.s_landingpage = schemaItem("description", dataset);
mapping.updated = schemaItem("updated", dataset);
mapping.start_datetime = formatDateToYYYYMMDD(
Expand All @@ -758,15 +892,16 @@ export default {

const variableMeasured = schemaItem("variableMeasured", dataset);
if (variableMeasured) {
const vmArr = Array.isArray(variableMeasured)
? variableMeasured
: [variableMeasured];
mapping.s_variableMeasuredNames = vmArr.map((item) =>
_.truncate(schemaItem("name", item), {
length: 80,
omission: "***",
})
);
const arr = Array.isArray(variableMeasured) ? variableMeasured : [variableMeasured];
mapping.s_variableMeasuredNames = arr.map((item) => {
// Handle both objects and strings
if (typeof item === "string") {
return _.truncate(item, { length: 80, omission: "***" });
}
// Extract name from object (DefinedTerm, PropertyValue, etc.)
const name = hasSchemaProperty("name", item) ? schemaItem("name", item) : (item.name || String(item));
return _.truncate(name, { length: 80, omission: "***" });
}).filter(Boolean);
}

if (
Expand Down
4 changes: 2 additions & 2 deletions client/src/config/development.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default {
NODE_ENV: process.env.NODE_ENV || "unknown",
API_URL: "http://localhost:3000",
API_URL: process.env.VITE_APP_API_URL || "http://localhost:3000",
TRIPLESTORE_URL:
"https://graph.geocodes.earthcube.org/blazegraph/namespace/earthcube/sparql",
//TRIPLESTORE_URL:'https://graphdb.geodex.org/repositories/geocodes',
Expand All @@ -15,7 +15,7 @@ export default {
SPARQL_HASTOOLS: "queries/sparql_hastools.txt",
SPARQL_TOOLS_WEBSERVICE: "queries/sparql_gettools_webservice.txt",
SPARQL_TOOLS_DOWNLOAD: "queries/sparql_gettools_download.txt",
JSONLD_PROXY: "http://localhost:3000/${o}",
JSONLD_PROXY: process.env.VITE_APP_JSONLD_PROXY || "http://localhost:3000/${o}",
SPARQL_NB: "https://beta.geocodes.earthcube.org/notebook/mkQ?q=${q}",
SPARQL_YASGUI: "https://geocodes.earthcube.org/sparqlgui?",
// allow us to use the same delimiters as lithtml
Expand Down
Loading