diff --git a/lib/DataHarmonizer.js b/lib/DataHarmonizer.js index 8edea6db..f554a243 100644 --- a/lib/DataHarmonizer.js +++ b/lib/DataHarmonizer.js @@ -10,6 +10,7 @@ import { dataArrayToObject, dataObjectToArray, fieldUnitBinTest, + getFieldSettingsFromUiConfig, } from './utils/fields'; import { parseDatatype } from './utils/datatypes'; import { @@ -51,8 +52,9 @@ class DataHarmonizer { this.schema = options.schema; this.loadingScreenRoot = options.loadingScreenRoot || this.root; this.modalsRoot = options.modalsRoot || document.querySelector('body'); - this.field_settings = options.fieldSettings || {}; - this.self = this; + + const fieldSettings = getFieldSettingsFromUiConfig(options.uiConfig); + this.field_settings = Object.assign(fieldSettings, options.fieldSettings); this.injectLoadingScreen(); diff --git a/lib/utils/fields.js b/lib/utils/fields.js index 04308ad6..a3ea688b 100644 --- a/lib/utils/fields.js +++ b/lib/utils/fields.js @@ -98,3 +98,62 @@ export function dataObjectToArray(dataObject, fields, options = {}) { } return dataArray; } + +function olsAutocompleteFieldSettings(config) { + const { ontology } = config; + return { + getColumn: (dh, col) => { + let timer = null; + return { + ...col, + type: 'autocomplete', + strict: true, + allowInvalid: false, + sortByRelevance: false, + source: (query, next) => { + clearTimeout(timer); + if (!query) { + return next([]); + } + timer = setTimeout(() => { + fetch( + `https://www.ebi.ac.uk/ols/api/select?q=${query}&ontology=${ontology}&type=class&rows=50` + ) + .then((response) => { + if (!response.ok) { + throw new Error('API Error: ' + response.status); + } + return response.json(); + }) + .then((body) => { + const options = body.response.docs.map((doc) => doc.label); + next(options); + }) + .catch(() => { + next([]); + }); + }, 300); + }, + }; + }, + }; +} + +const WIDGET_REGISTRY = { + 'ols-autocomplete': olsAutocompleteFieldSettings, +}; + +export function getFieldSettingsFromUiConfig(uiConfig) { + const fieldSettings = {}; + if (uiConfig && uiConfig.fields) { + for (const [field, config] of Object.entries(uiConfig.fields)) { + if (config.widget in WIDGET_REGISTRY) { + const settingsFn = WIDGET_REGISTRY[config.widget]; + fieldSettings[field] = settingsFn(config); + } else { + console.warn(`Unknown widget type: ${config.widget}`); + } + } + } + return fieldSettings; +} diff --git a/web/index.js b/web/index.js index 1f464b9e..78d78251 100644 --- a/web/index.js +++ b/web/index.js @@ -9,8 +9,20 @@ document.addEventListener('DOMContentLoaded', function () { const dhFooterRoot = document.querySelector('#data-harmonizer-footer'); const dhToolbarRoot = document.querySelector('#data-harmonizer-toolbar'); + // this is defined inline for convenience but could just as easily be + // imported from a JSON file + const uiConfig = { + fields: { + 'third party lab service provider name': { + widget: 'ols-autocomplete', + ontology: 'zfa,zfs', + }, + }, + }; + const dh = new DataHarmonizer(dhRoot, { loadingScreenRoot: document.querySelector('body'), + uiConfig: uiConfig, }); new Footer(dhFooterRoot, dh);