From c4b4f82cabf17d7fe0a82f66a462fa32be3df796 Mon Sep 17 00:00:00 2001 From: Kenneth Bruskiewicz Date: Wed, 21 Aug 2024 13:31:16 -0700 Subject: [PATCH 1/2] didn't pass in proper value to autocomplete renderer --- lib/editors/KeyValueEditor.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/editors/KeyValueEditor.js b/lib/editors/KeyValueEditor.js index deedfee2..86961b94 100644 --- a/lib/editors/KeyValueEditor.js +++ b/lib/editors/KeyValueEditor.js @@ -1,5 +1,6 @@ import Handsontable from 'handsontable'; import { MULTIVALUED_DELIMITER, titleOverText } from '@/lib/utils/fields'; +import { isEmptyUnitVal } from '@/lib/utils/general'; // Derived from: https://jsfiddle.net/handsoncode/f0b41jug/ @@ -134,11 +135,11 @@ export const keyValueListRenderer = function ( cellProperties ) { // Call the autocomplete renderer to ensure default styles and behavior are applied - - const item = cellProperties.source.find(({ _id }) => _id === value); Handsontable.renderers .getRenderer('autocomplete') - .apply(this, [hot, TD, row, col, prop, item, cellProperties]); + .apply(this, [hot, TD, row, col, prop, value, cellProperties]); + + const item = cellProperties.source.find(({ _id }) => _id === value); if (item) { // Use the label as the display value but keep the _id as the stored value const label = item.label; @@ -156,7 +157,7 @@ export const multiKeyValueListRenderer = (field) => { .getRenderer('autocomplete') .apply(this, [hot, TD, row, col, prop, value, cellProperties]); - if (!(value === null || value === '' || typeof value === 'undefined')) { + if (!(isEmptyUnitVal(value))) { const label = value .split(MULTIVALUED_DELIMITER) .map((key) => titleOverText(merged_permissible_values[key])) From d7a9533c5fddf932e8b02d8249bfbba3510a935c Mon Sep 17 00:00:00 2001 From: Kenneth Bruskiewicz Date: Wed, 21 Aug 2024 13:36:50 -0700 Subject: [PATCH 2/2] format prettier, small bug in createRowManager --- lib/AppContext.js | 109 ++++----- lib/Toolbar.js | 7 +- lib/editors/KeyValueEditor.js | 2 +- lib/utils/1m.js | 401 +++++++++++++++++----------------- lib/utils/fields.js | 2 +- lib/utils/objects.js | 4 +- lib/utils/templates.js | 6 +- web/index.js | 1 - 8 files changed, 263 insertions(+), 269 deletions(-) diff --git a/lib/AppContext.js b/lib/AppContext.js index a3f88cbb..4894c3a4 100644 --- a/lib/AppContext.js +++ b/lib/AppContext.js @@ -7,10 +7,7 @@ import { findLocalesForLangcodes } from '@/lib/utils/i18n'; import { Template, findSlotNamesForClass } from '@/lib/utils/templates'; import { wait } from '@/lib/utils/general'; import { invert, removeNumericKeys } from '@/lib/utils/objects'; -import { - setup1M, - buildSchemaTree -} from '@/lib/utils/1m'; +import { setup1M, buildSchemaTree } from '@/lib/utils/1m'; import { createDataHarmonizerContainer, createDataHarmonizerTab } from '@/web'; function getTemplatePath() { @@ -23,7 +20,8 @@ function getTemplatePath() { } if (templatePath === null || typeof templatePath === 'undefined') { const schema_name = Object.keys(menu)[0]; - const template_name = Object.keys(menu[schema_name])[0]; return `${schema_name}/${template_name}`; + const template_name = Object.keys(menu[schema_name])[0]; + return `${schema_name}/${template_name}`; } return templatePath; } @@ -49,23 +47,21 @@ export class AppContext { // Method to bind event listeners bindEventListeners() { - $(document).on('dhTabChange', (event, data) => { const { specName } = data; - this.setCurrentDataHarmonizer(specName); + this.setCurrentDataHarmonizer(specName); // Should trigger Toolbar to refresh sections $(document).trigger('dhCurrentChange', { - dh: this.getCurrentDataHarmonizer() + dh: this.getCurrentDataHarmonizer(), }); }); - + $(document).on('dhCurrentSelectionChange', (event, data) => { const { currentSelection } = data; this.currentSelection = currentSelection; }); - } - + async reload( template_path, overrides = { locale: null, forced_schema: null } @@ -76,7 +72,10 @@ export class AppContext { const isForcedSchemaProvided = overrides.forced_schema !== null; const isLocaleChange = overrides.locale !== null; - const clearAndSetup = async (data_harmonizers = {}, forced_schema = null) => { + const clearAndSetup = async ( + data_harmonizers = {}, + forced_schema = null + ) => { this.clearInterface(); return this.setupDataHarmonizers({ data_harmonizers, @@ -116,8 +115,8 @@ export class AppContext { this.template = await Template.create(template_name, options); return this; } - - /** + + /** * Run void function behind loading screen. * Adds function to end of call queue. Does not handle functions with return * vals, unless the return value is a promise. Even then, it only waits for the @@ -218,7 +217,7 @@ export class AppContext { return acc; } ); - + let translated_sections = {}; let default_sections = {}; Object.keys(translation.schema.classes) @@ -317,44 +316,33 @@ export class AppContext { schema_name, export_formats ) { - let data_harmonizers = {}; Object.entries(schema_tree) - .filter(([cls_key]) => cls_key !== 'Container') - .forEach((obj, index) => { - if (obj.length > 0) { - const [cls_key, spec] = obj; - - // if it shares a key with another class which is its parent, this DH must be a child - const is_child = spec.shared_keys.some( - (shared_key_spec) => shared_key_spec.relation === 'parent' - ); - - const dhId = `data-harmonizer-grid-${index}`; - if (!document.getElementById(dhId)) { - const dhSubroot = createDataHarmonizerContainer( - dhId, - index === 0 + .filter(([cls_key]) => cls_key !== 'Container') + .forEach((obj, index) => { + if (obj.length > 0) { + const [cls_key, spec] = obj; + + // if it shares a key with another class which is its parent, this DH must be a child + const is_child = spec.shared_keys.some( + (shared_key_spec) => shared_key_spec.relation === 'parent' ); - - const dhTab = createDataHarmonizerTab( - dhId, - spec.name, - index === 0 - ); - dhTab.addEventListener('click', () => { - $(document).trigger('dhTabChange', { - specName: spec.name, + + const dhId = `data-harmonizer-grid-${index}`; + if (!document.getElementById(dhId)) { + const dhSubroot = createDataHarmonizerContainer(dhId, index === 0); + + const dhTab = createDataHarmonizerTab(dhId, spec.name, index === 0); + dhTab.addEventListener('click', () => { + $(document).trigger('dhTabChange', { + specName: spec.name, + }); }); - }); - - // Different classes have different slots allocated to them. field_filters narrows to those slots. - // idempotent: running this over the same initialization twice is expensive but shouldn't lose state - // in 1-M, different DataHarmonizers have fewer rows to start with and visible if a child. Override the default HoT settings. - data_harmonizers[spec.name] = new DataHarmonizer( - dhSubroot, - this, - { + + // Different classes have different slots allocated to them. field_filters narrows to those slots. + // idempotent: running this over the same initialization twice is expensive but shouldn't lose state + // in 1-M, different DataHarmonizers have fewer rows to start with and visible if a child. Override the default HoT settings. + data_harmonizers[spec.name] = new DataHarmonizer(dhSubroot, this, { loadingScreenRoot: document.body, class_assignment: cls_key, field_filters: findSlotNamesForClass(schema, cls_key), @@ -364,21 +352,20 @@ export class AppContext { // colWidths: is_child ? 256 : undefined, // TODO: Workaround, possibly due to too small section column on child tables colWidths: 256, }, + }); + data_harmonizers[spec.name].useSchema( + schema, + export_formats, + schema_name + ); + + // hide the single row if child + if (is_child) { + data_harmonizers[spec.name].filterAll(); } - ); - data_harmonizers[spec.name].useSchema( - schema, - export_formats, - schema_name - ); - - // hide the single row if child - if (is_child) { - data_harmonizers[spec.name].filterAll(); } } - } - }); + }); delete data_harmonizers[undefined]; return data_harmonizers; // Return the created data harmonizers if needed } diff --git a/lib/Toolbar.js b/lib/Toolbar.js index 6a7eabda..eeae6677 100644 --- a/lib/Toolbar.js +++ b/lib/Toolbar.js @@ -14,15 +14,12 @@ import { importJsonFile, } from '@/lib/utils/files'; import { nullValuesToString, isEmptyUnitVal } from '@/lib/utils/general'; -import { - MULTIVALUED_DELIMITER, - titleOverText, -} from '@/lib/utils/fields'; +import { MULTIVALUED_DELIMITER, titleOverText } from '@/lib/utils/fields'; import { findBestLocaleMatch, templatePathForSchemaURI, rangeToContainerClass, - LocaleNotSupportedError + LocaleNotSupportedError, } from '@/lib/utils/templates'; import { diff --git a/lib/editors/KeyValueEditor.js b/lib/editors/KeyValueEditor.js index 86961b94..cab97e40 100644 --- a/lib/editors/KeyValueEditor.js +++ b/lib/editors/KeyValueEditor.js @@ -157,7 +157,7 @@ export const multiKeyValueListRenderer = (field) => { .getRenderer('autocomplete') .apply(this, [hot, TD, row, col, prop, value, cellProperties]); - if (!(isEmptyUnitVal(value))) { + if (!isEmptyUnitVal(value)) { const label = value .split(MULTIVALUED_DELIMITER) .map((key) => titleOverText(merged_permissible_values[key])) diff --git a/lib/utils/1m.js b/lib/utils/1m.js index 370bb157..58a0bdaa 100644 --- a/lib/utils/1m.js +++ b/lib/utils/1m.js @@ -1,4 +1,3 @@ - import * as $ from 'jquery'; import { looseMatchInObject } from '@/lib/utils/objects'; import { tap, isEmptyUnitVal } from '@/lib/utils/general'; @@ -17,10 +16,10 @@ function getColumnIndexByFieldName(data_harmonizer, shared_slot_name) { } function getSharedKeyName(schemaTree, parentName, childName) { - const sharedKey = schemaTree[parentName].shared_keys.find( - (el) => el.related_concept === childName - ); - return sharedKey ? sharedKey.name : null; + const sharedKey = schemaTree[parentName].shared_keys.find( + (el) => el.related_concept === childName + ); + return sharedKey ? sharedKey.name : null; } /** @@ -103,38 +102,43 @@ function visitSchemaTree(schema_tree, callback = tap, next = 'Container') { */ function makeColumnReadOnly(data_harmonizer, shared_key_name) { const hot = data_harmonizer.hot; - const columnIndex = getColumnIndexByFieldName(data_harmonizer, shared_key_name); + const columnIndex = getColumnIndexByFieldName( + data_harmonizer, + shared_key_name + ); if (columnIndex >= 0 && columnIndex < hot.countCols()) { updateColumnSettings(hot, columnIndex, { readOnly: true }); } else { - console.error(`makeColumnReadOnly: Column not found for '${shared_key_name}'`); + console.error( + `makeColumnReadOnly: Column not found for '${shared_key_name}'` + ); } } // closure to keep track of row data before removal -const createRowDataManager = (contex_menu_callback) => { - let rowDataBeforeRemoval = {}; - - return { - beforeRemoveRow: function (index, amount, physicalRows) { - for (let i = 0; i < amount; i++) { - let rowIndex = physicalRows[i]; - let rowData = hot.getDataAtRow(rowIndex); - rowDataBeforeRemoval[rowIndex] = rowData; // Store the row data - } - }, - afterRemoveRow: function (index, amount, physicalRows, source) { - for (let i = 0; i < amount; i++) { - let rowIndex = physicalRows[i]; - let rowData = rowDataBeforeRemoval[rowIndex]; - // Custom logic using the rowData - contex_menu_callback(rowData, source); - } - // Clear the temporary storage - rowDataBeforeRemoval = {}; - }, - }; +const createRowDataManager = (hot, contex_menu_callback) => { + let rowDataBeforeRemoval = {}; + + return { + beforeRemoveRow: function (index, amount, physicalRows) { + for (let i = 0; i < amount; i++) { + let rowIndex = physicalRows[i]; + let rowData = hot.getDataAtRow(rowIndex); + rowDataBeforeRemoval[rowIndex] = rowData; // Store the row data + } + }, + afterRemoveRow: function (index, amount, physicalRows, source) { + for (let i = 0; i < amount; i++) { + let rowIndex = physicalRows[i]; + let rowData = rowDataBeforeRemoval[rowIndex]; + // Custom logic using the rowData + contex_menu_callback(rowData, source); + } + // Clear the temporary storage + rowDataBeforeRemoval = {}; + }, + }; }; /** @@ -165,7 +169,7 @@ function setupSharedColumn( ); } else { // Initialize the row data manager - const rowDataManager = createRowDataManager(contex_menu_callback); + const rowDataManager = createRowDataManager(hot, contex_menu_callback); // Add the beforeRemoveRow and afterRemoveRow hooks using addHook hot.addHook('beforeRemoveRow', rowDataManager.beforeRemoveRow); @@ -418,115 +422,113 @@ function propagateFilter( } function createFlatSchemaTree(classNames) { - return { - Container: { - tree_root: true, - children: [...classNames], - }, - ...classNames.reduce((acc, key) => { - acc[key] = { - name: key, - children: [], - shared_keys: [], - }; - return acc; - }, {}), - }; - } + return { + Container: { + tree_root: true, + children: [...classNames], + }, + ...classNames.reduce((acc, key) => { + acc[key] = { + name: key, + children: [], + shared_keys: [], + }; + return acc; + }, {}), + }; +} function createPreSchemaTree(classNames, sharedKeysPerClass) { - const treeBase = { - Container: { tree_root: true, children: classNames }, - }; + const treeBase = { + Container: { tree_root: true, children: classNames }, + }; - return classNames.reduce((acc, classKey) => { - const sharedKeys = sharedKeysPerClass[classKey] || []; - acc[classKey] = { - name: classKey, - shared_keys: sharedKeys, - children: sharedKeys - .map((item) => item.range) - .filter((range) => range !== classKey && typeof range !== 'undefined'), - }; - return acc; - }, treeBase); - } + return classNames.reduce((acc, classKey) => { + const sharedKeys = sharedKeysPerClass[classKey] || []; + acc[classKey] = { + name: classKey, + shared_keys: sharedKeys, + children: sharedKeys + .map((item) => item.range) + .filter((range) => range !== classKey && typeof range !== 'undefined'), + }; + return acc; + }, treeBase); +} function updateWithChildrenAndSharedKeys(data) { - // Use a deep clone to avoid mutating the original object - const result = JSON.parse(JSON.stringify(data)); - - Object.keys(result).forEach((key) => { - const elem = result[key]; - (elem.shared_keys || []).forEach((sk) => { - if (sk.relation === 'parent' && result[sk.related_concept]) { - const parent = result[sk.related_concept]; - - // Ensure 'children' array exists - if (!parent.children) { - parent.children = []; - } + // Use a deep clone to avoid mutating the original object + const result = JSON.parse(JSON.stringify(data)); + + Object.keys(result).forEach((key) => { + const elem = result[key]; + (elem.shared_keys || []).forEach((sk) => { + if (sk.relation === 'parent' && result[sk.related_concept]) { + const parent = result[sk.related_concept]; + + // Ensure 'children' array exists + if (!parent.children) { + parent.children = []; + } - // Add key to parent’s 'children' array if not already present - if (!parent.children.includes(key)) { - parent.children.push(key); - } + // Add key to parent’s 'children' array if not already present + if (!parent.children.includes(key)) { + parent.children.push(key); + } - // Ensure 'shared_keys' array exists - if (!parent.shared_keys) { - parent.shared_keys = []; - } + // Ensure 'shared_keys' array exists + if (!parent.shared_keys) { + parent.shared_keys = []; + } - // Check if reciprocal shared key already exists - const reciprocalExists = parent.shared_keys.some( - (rsk) => rsk.name === sk.name && rsk.related_concept === key - ); + // Check if reciprocal shared key already exists + const reciprocalExists = parent.shared_keys.some( + (rsk) => rsk.name === sk.name && rsk.related_concept === key + ); - // Add reciprocal shared key if it doesn't exist - if (!reciprocalExists) { - parent.shared_keys.push({ - name: sk.name, - related_concept: key, - relation: 'child', - }); - } + // Add reciprocal shared key if it doesn't exist + if (!reciprocalExists) { + parent.shared_keys.push({ + name: sk.name, + related_concept: key, + relation: 'child', + }); } - }); + } }); + }); - return result; - } + return result; +} - /** - * Builds a schema tree from the given schema. - * @param {Object} schema - The schema object containing "classes". - * @returns {Object|null} The schema tree object, or null if no "Container" classes are found. - */ +/** + * Builds a schema tree from the given schema. + * @param {Object} schema - The schema object containing "classes". + * @returns {Object|null} The schema tree object, or null if no "Container" classes are found. + */ export function buildSchemaTree(schema) { + const isContainerMissing = typeof schema.classes['Container'] === 'undefined'; - const isContainerMissing = typeof schema.classes['Container'] === 'undefined'; - - const classNames = Object.keys(schema.classes).filter( - (key) => key !== 'dh_interface' && key !== 'Container' - ); + const classNames = Object.keys(schema.classes).filter( + (key) => key !== 'dh_interface' && key !== 'Container' + ); - if (isContainerMissing) { - return createFlatSchemaTree(classNames); - } + if (isContainerMissing) { + return createFlatSchemaTree(classNames); + } - const sharedKeysPerClass = findSharedKeys(schema); - const preSchemaTree = createPreSchemaTree(classNames, sharedKeysPerClass); + const sharedKeysPerClass = findSharedKeys(schema); + const preSchemaTree = createPreSchemaTree(classNames, sharedKeysPerClass); - return updateWithChildrenAndSharedKeys(preSchemaTree); - - } + return updateWithChildrenAndSharedKeys(preSchemaTree); +} - // Utility to set column read-only +// Utility to set column read-only function updateColumnSettings(hot, columnIndex, options) { - const currentColumns = hot.getSettings().columns || []; - currentColumns[columnIndex] = { ...currentColumns[columnIndex], ...options }; - hot.updateSettings({ columns: currentColumns }); - } + const currentColumns = hot.getSettings().columns || []; + currentColumns[columnIndex] = { ...currentColumns[columnIndex], ...options }; + hot.updateSettings({ columns: currentColumns }); +} // Two kinds of edits to be dealt with in 1-M: // - multiedit inside of a column @@ -538,99 +540,108 @@ function updateColumnSettings(hot, columnIndex, options) { * @returns {Object} The same object with event handlers attached. */ export function attachPropagationEventHandlersToDataHarmonizers( - data_harmonizers, - schema_tree - ) { - visitSchemaTree(schema_tree, (schema_tree_node) => { - // Propagation: - // - If has children with shared_keys, add handler - // - visit children -> lock field from being edited by user (DH methods can modify it) - if (schema_tree_node.children.length > 0) { - if (!schema_tree_node.tree_root) { - makeSharedKeyHandler( - data_harmonizers, - data_harmonizers[schema_tree_node.name], - schema_tree_node - ); - schema_tree_node.children.forEach((child) => { - schema_tree[child].shared_keys.forEach((shared_key_spec_child) => { - makeColumnReadOnly( - data_harmonizers[child], - shared_key_spec_child.name - ); - }); + data_harmonizers, + schema_tree +) { + visitSchemaTree(schema_tree, (schema_tree_node) => { + // Propagation: + // - If has children with shared_keys, add handler + // - visit children -> lock field from being edited by user (DH methods can modify it) + if (schema_tree_node.children.length > 0) { + if (!schema_tree_node.tree_root) { + makeSharedKeyHandler( + data_harmonizers, + data_harmonizers[schema_tree_node.name], + schema_tree_node + ); + schema_tree_node.children.forEach((child) => { + schema_tree[child].shared_keys.forEach((shared_key_spec_child) => { + makeColumnReadOnly( + data_harmonizers[child], + shared_key_spec_child.name + ); }); - } + }); } - }); - - // NOTE: preserve memory of selection between tabs! in DH? => using outsideClickDeselects: false, // for maintaining selection between tabs - return data_harmonizers; - } + } + }); -export function attachSelectionHandlersToDataHarmonizers(data_harmonizers, schema_tree) { - Object.values(data_harmonizers).forEach((dh) => { - - dh.hot.addHook('afterSelection', (row, col) => { - const valueToMatch = dh.hot.getDataAtCell(row, col); - if (!isEmptyUnitVal(valueToMatch)) { - // get value at cell - // filter other data harmonizer at cell - const parent_name = dh.class_assignment; - schema_tree[parent_name].children.forEach((child_name) => { - // filter for other data in data harmonizers matching the shared ID iff the selection is not empty - // else return an empty list - const shared_key_name = getSharedKeyName(schema_tree, parent_name, child_name); - - $(document).trigger('dhCurrentSelectionChange', { - currentSelection: { - source: dh.class_assignment, - shared_key_name, - valueToMatch, - col, - } - }); - - propagateFilter( - data_harmonizers, - shared_key_name, - schema_tree, - child_name, - valueToMatch - ); - }); - } else { - schema_tree[dh.class_assignment].children.forEach((child_name) => { - data_harmonizers[child_name].filterAll(); - }); - } - }); - - dh.hot.addHook('afterDeselect', () => { + // NOTE: preserve memory of selection between tabs! in DH? => using outsideClickDeselects: false, // for maintaining selection between tabs + return data_harmonizers; +} - $(document).trigger('dhCurrentSelectionChange', { - currentSelection: null - }); - +export function attachSelectionHandlersToDataHarmonizers( + data_harmonizers, + schema_tree +) { + Object.values(data_harmonizers).forEach((dh) => { + dh.hot.addHook('afterSelection', (row, col) => { + const valueToMatch = dh.hot.getDataAtCell(row, col); + if (!isEmptyUnitVal(valueToMatch)) { // get value at cell // filter other data harmonizer at cell const parent_name = dh.class_assignment; schema_tree[parent_name].children.forEach((child_name) => { - const shared_key_name = getSharedKeyName(schema_tree, parent_name, child_name); + // filter for other data in data harmonizers matching the shared ID iff the selection is not empty + // else return an empty list + const shared_key_name = getSharedKeyName( + schema_tree, + parent_name, + child_name + ); + + $(document).trigger('dhCurrentSelectionChange', { + currentSelection: { + source: dh.class_assignment, + shared_key_name, + valueToMatch, + col, + }, + }); + propagateFilter( data_harmonizers, shared_key_name, schema_tree, - child_name + child_name, + valueToMatch ); }); + } else { + schema_tree[dh.class_assignment].children.forEach((child_name) => { + data_harmonizers[child_name].filterAll(); + }); + } + }); + + dh.hot.addHook('afterDeselect', () => { + $(document).trigger('dhCurrentSelectionChange', { + currentSelection: null, + }); + + // get value at cell + // filter other data harmonizer at cell + const parent_name = dh.class_assignment; + schema_tree[parent_name].children.forEach((child_name) => { + const shared_key_name = getSharedKeyName( + schema_tree, + parent_name, + child_name + ); + propagateFilter( + data_harmonizers, + shared_key_name, + schema_tree, + child_name + ); }); }); - - return data_harmonizers; - } + }); + + return data_harmonizers; +} export const setup1M = (dhs, schema_tree) => { attachPropagationEventHandlersToDataHarmonizers(dhs, schema_tree); attachSelectionHandlersToDataHarmonizers(dhs, schema_tree); -} \ No newline at end of file +}; diff --git a/lib/utils/fields.js b/lib/utils/fields.js index 7aabbfe5..7f7cf306 100644 --- a/lib/utils/fields.js +++ b/lib/utils/fields.js @@ -260,4 +260,4 @@ export const formatEscapeHTML = (string) => { export function titleOverText(enm) { return typeof enm.title !== 'undefined' ? enm.title : enm.text; -} \ No newline at end of file +} diff --git a/lib/utils/objects.js b/lib/utils/objects.js index 0c78aae5..0f06d3b7 100644 --- a/lib/utils/objects.js +++ b/lib/utils/objects.js @@ -228,9 +228,9 @@ export function removeNumericKeys(obj) { return obj; } -export function looseMatchInObject (keys) { +export function looseMatchInObject(keys) { return (obj) => (matchKey) => { const returnIf = (obj) => (key) => key in obj ? [obj[key]] : []; return keys.flatMap(returnIf(obj)).includes(matchKey); }; -} \ No newline at end of file +} diff --git a/lib/utils/templates.js b/lib/utils/templates.js index 076856f9..98060e5a 100644 --- a/lib/utils/templates.js +++ b/lib/utils/templates.js @@ -14,7 +14,7 @@ export async function templatePathForSchemaURI(schemaURI) { // for now, this is just the manifest for (let i = 0; i < template_manifest.children.length; i++) { const template = template_manifest.children[i]; - if (!!template.children) { + if (typeof template.children !== 'undefined') { const schema = await importSchema(template.name); if (schema.id === schemaURI) { return `${template.path.split('/').slice(-1)}/${schemaURI @@ -422,13 +422,13 @@ export const rangeToContainerClass = (Container, cls_key) => { .filter((v) => v.range === cls_key)[0].name; }; - /** +/** * Finds the slot names for a given class within the schema. * @param {Object} schema - The schema object containing "classes". * @param {string} class_name - The name of the class to search for slot names. * @returns {Array} An array of slot names. */ - export function findSlotNamesForClass(schema, class_name) { +export function findSlotNamesForClass(schema, class_name) { return Object.keys(schema.classes[class_name].slot_usage).map((field) => { return schema.classes[class_name].slot_usage[field].name; }); diff --git a/web/index.js b/web/index.js index 4aa92764..9b374126 100644 --- a/web/index.js +++ b/web/index.js @@ -66,7 +66,6 @@ const main = async function () { context .reload(context.appConfig.template_path, { locale: 'en' }) .then(async (context) => { - // // internationalize // // TODO: connect to locale of browser! // // Takes `lang` as argument (unused)