From b504cc4d6d07576e19f92d3c2ab97451f03475e7 Mon Sep 17 00:00:00 2001 From: Patrick Kalita Date: Tue, 27 Sep 2022 08:43:54 -0700 Subject: [PATCH 1/2] Add uiConfig option to DH constructor, allow specifying a custom widget for a field --- lib/DataHarmonizer.js | 6 +++-- lib/utils/fields.js | 57 +++++++++++++++++++++++++++++++++++++++++++ web/index.js | 12 +++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) 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..cf840a8e 100644 --- a/lib/utils/fields.js +++ b/lib/utils/fields.js @@ -98,3 +98,60 @@ 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 +} \ No newline at end of file diff --git a/web/index.js b/web/index.js index 1f464b9e..09d49da0 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); From 5f8b685fb44b1c199101b4e35906dc242f8fe8bb Mon Sep 17 00:00:00 2001 From: Patrick Kalita Date: Tue, 27 Sep 2022 09:22:43 -0700 Subject: [PATCH 2/2] FIx linter issues --- lib/utils/fields.js | 60 +++++++++++++++++++++++---------------------- web/index.js | 12 ++++----- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/lib/utils/fields.js b/lib/utils/fields.js index cf840a8e..a3ea688b 100644 --- a/lib/utils/fields.js +++ b/lib/utils/fields.js @@ -100,7 +100,7 @@ export function dataObjectToArray(dataObject, fields, options = {}) { } function olsAutocompleteFieldSettings(config) { - const { ontology } = config + const { ontology } = config; return { getColumn: (dh, col) => { let timer = null; @@ -111,47 +111,49 @@ function olsAutocompleteFieldSettings(config) { allowInvalid: false, sortByRelevance: false, source: (query, next) => { - clearTimeout(timer) + clearTimeout(timer); if (!query) { - return next([]) + 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) + 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 -} + 'ols-autocomplete': olsAutocompleteFieldSettings, +}; export function getFieldSettingsFromUiConfig(uiConfig) { - const fieldSettings = {} + 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) + const settingsFn = WIDGET_REGISTRY[config.widget]; + fieldSettings[field] = settingsFn(config); } else { - console.warn(`Unknown widget type: ${config.widget}`) + console.warn(`Unknown widget type: ${config.widget}`); } } } - return fieldSettings -} \ No newline at end of file + return fieldSettings; +} diff --git a/web/index.js b/web/index.js index 09d49da0..78d78251 100644 --- a/web/index.js +++ b/web/index.js @@ -12,13 +12,13 @@ document.addEventListener('DOMContentLoaded', function () { // this is defined inline for convenience but could just as easily be // imported from a JSON file const uiConfig = { - 'fields': { + fields: { 'third party lab service provider name': { - 'widget': 'ols-autocomplete', - 'ontology': 'zfa,zfs' - } - } - } + widget: 'ols-autocomplete', + ontology: 'zfa,zfs', + }, + }, + }; const dh = new DataHarmonizer(dhRoot, { loadingScreenRoot: document.querySelector('body'),