+
))}
- {queryGroups.map((group) => {
- const [open, setOpen] = useState(false)
- return (
-
- { setOpen(!open) }}>
-
- {getIconComponent(group.icon)}
-
-
- {open ? : }
-
-
-
- {group.queries.map((id) => (
-
- }
- >
-
-
-
-
- ))}
-
-
-
- )
- })}
+ {queryGroups.map((group) => (
+
+ handleGroupToggle(group.id)}>
+
+ {getIconComponent(group.icon)}
+
+
+ {openGroups[group.id] ? : }
+
+
+
+ {group.queries.map((id) => (
+ }
+ >
+
+
+
+
+ ))}
+
+
+
+ ))}
);
-}
+};
const menuItemTheme = createTheme({
components: {
@@ -110,53 +121,31 @@ const menuItemTheme = createTheme({
display: "block",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
- }
+ },
},
},
- }
+ },
},
});
const getIconComponent = (iconKey) => {
const IconComponent = IconProvider[iconKey];
- if (IconComponent) {
- return
+
);
@@ -83,23 +88,25 @@ function reduceDataToObject(data) {
}
const Aside = (props) => {
- const {changeVariables} = props;
- return(
-
-
-
-)}
+ const { changeVariables } = props;
+ return (
+
+
+
+
+ )
+}
const NoValuesDisplay = () => {
- return(
-
-
-
- The result list is empty.
-
+ return (
+
+
+
+ The result list is empty.
+
-
+
)
}
-
+
export default QueryResultList;
diff --git a/src/components/ListResultTable/QueryResultList/TableHeader/TableHeader.jsx b/src/components/ListResultTable/QueryResultList/TableHeader/TableHeader.jsx
index aff92d7..ad2ba02 100644
--- a/src/components/ListResultTable/QueryResultList/TableHeader/TableHeader.jsx
+++ b/src/components/ListResultTable/QueryResultList/TableHeader/TableHeader.jsx
@@ -54,7 +54,7 @@ function TableHeader({ children }) {
>
{child.props.label}
- {variableOntology[child.props.source] && (
+ {!!variableOntology && variableOntology[child.props.source] && (
(
@@ -22,15 +23,17 @@ const TemplatedQueryForm = (props) => {
searchPar,
} = props;
+ const resourceDef = useResourceDefinition();
+
useEffect(() => {
if (submitted){
onSubmit(searchPar);
}
}, [submitted])
-
return (
} onSubmit={onSubmit}>
+ {!!resourceDef.options && resourceDef.options.queryGroupId === 'cstm' && }
{Object.entries(variableOptions).map(([name, options]) => (
({
diff --git a/src/config.json b/src/config.json
index 088c6d2..6aaece5 100644
--- a/src/config.json
+++ b/src/config.json
@@ -11,7 +11,7 @@
"showMilliseconds": false,
"defaultIDP": "http://localhost:8080",
"footer": "IDLab - imec - UGent
",
- "introductionText": "Please select a query from the menu on the left.",
+ "introductionText": "Please log in as the appropriate actor and make your choice in the menu on the left.",
"queryGroups" : [
{
"id": "a-ex",
diff --git a/src/configManager/configManager.js b/src/configManager/configManager.js
index ae3e29f..2f3f719 100644
--- a/src/configManager/configManager.js
+++ b/src/configManager/configManager.js
@@ -54,8 +54,22 @@ class ConfigManager extends EventEmitter {
this.emit('configChanged', this.config);
}
+ addNewQueryGroup(id, name, icon = null) {
+
+ const groupExists = this.config.queryGroups.find(group => group.id === id);
+
+ if (groupExists === undefined) {
+ const newGroup = { id, name };
+ if (icon) {
+ newGroup.icon = icon;
+ }
+ this.config.queryGroups = [...this.config.queryGroups, newGroup];
+ this.emit('configChanged', this.config);
+ }
+ }
+
/**
- * Adds as query element to the config.queries array in the configuration
+ * Adds a query element to the config.queries array in the configuration
*
* @param {object} newQuery - the query element to be added
*/
@@ -100,6 +114,58 @@ class ConfigManager extends EventEmitter {
}
return query.queryString;
}
+
+
+ /**
+ * Updates a query element to the config.queries array in the configuration
+ * @param {Object} updatedQuery - the updated query element to replace
+ */
+ updateQuery(updatedQuery) {
+ let index = this.config.queries.findIndex(query => query.id === updatedQuery.id);
+ if (index !== -1) {
+ this.config.queries[index] = updatedQuery;
+ }
+ this.queryWorkingCopies = {};
+ this.emit('configChanged', this.config);
+ }
+
+ /**
+ * Deletes the query with the given id in the config.queries array in the configuration
+ * @param {string} id - id property of the query to delete
+ */
+ deleteQueryById(id) {
+ let index = this.config.queries.findIndex(query => query.id === id);
+ if (index !== -1) {
+ this.config.queries.splice(index, 1);
+ }
+ this.queryWorkingCopies = {};
+ this.emit('configChanged', this.config);
+ }
+
+
+ /**
+ * Gets the query with the given id in the config.queries array in the configuration
+ * @param {string} id - id property a query
+ * @returns {object} the query
+ */
+ getQueryById(id) {
+ return this.config.queries.find((query) => query.id === id);
+ }
+
+ /**
+ * Gets the query text from a query
+ * @param {object} query - the input query
+ * @returns {string} the query text
+ */
+ async getQueryText(query) {
+
+ if (query.queryLocation) {
+ const fetchResult = await fetch(`${this.config.queryFolder}${query.queryLocation}`);
+ return await fetchResult.text();
+ }
+ return query.queryString;
+ }
+
}
const configManager = new ConfigManager();
diff --git a/src/dataProvider/SparqlDataProvider.js b/src/dataProvider/SparqlDataProvider.js
index 078e066..99b8060 100644
--- a/src/dataProvider/SparqlDataProvider.js
+++ b/src/dataProvider/SparqlDataProvider.js
@@ -343,18 +343,28 @@ async function configureBindingStream(bindingStream, variables) {
const addComunicaContextSourcesFromSourcesIndex = async (sourcesIndex) => {
const sourcesList = [];
try {
- const result = await fetch(`${config.queryFolder}${sourcesIndex.queryLocation}`);
- const queryStringIndexSource = await result.text();
+ let queryStringIndexSource;
+ if (sourcesIndex.queryLocation){
+ const result = await fetch(`${config.queryFolder}${sourcesIndex.queryLocation}`);
+ queryStringIndexSource = await result.text();
+ }else{
+ queryStringIndexSource = sourcesIndex.queryString;
+ }
const bindingsStream = await myEngine.queryBindings(queryStringIndexSource, {
sources: [sourcesIndex.url],
});
await new Promise((resolve, reject) => {
- bindingsStream.on('data', (binding) => {
- const source = binding.get('object').value;
- if (!sourcesList.includes(source)) {
- sourcesList.push(source);
+ bindingsStream.on('data', (bindings) => {
+ // the bindings should have exactly one key (any name is allowed) and we accept the value as a source
+ if (bindings.size == 1) {
+ for (const term of bindings.values()) {
+ const source = term.value;
+ if (!sourcesList.includes(source)) {
+ sourcesList.push(source);
+ }
+ }
}
});
bindingsStream.on('end', resolve);
@@ -365,6 +375,10 @@ const addComunicaContextSourcesFromSourcesIndex = async (sourcesIndex) => {
throw new Error(`Error adding sources from index: ${error.message}`);
}
+ if (sourcesList.length == 0) {
+ throw new Error(`The resulting list of sources is empty`);
+ }
+
return sourcesList;
};