From 14d1ad5c2068cbd76f08839b3cce7e5f90e85840 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Fri, 6 Sep 2024 13:42:15 -0700 Subject: [PATCH 1/9] Unbundle gifs --- web/webpack.config.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/webpack.config.js b/web/webpack.config.js index 5e6c2eb4..c8596945 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -9,7 +9,6 @@ module.exports = (env, argv) => { output: { path: path.resolve(__dirname, 'dist'), filename: 'scripts/[name].js', - assetModuleFilename: 'assets/[hash][ext][query]', }, plugins: [ new HtmlWebpackPlugin({ @@ -52,6 +51,12 @@ module.exports = (env, argv) => { { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset/resource', + generator: { + // Will throw a file not found error if ``dist`` folder not in + // ``{project root}/web/``. + filename: '../[file]', + emit: false, + } }, ], }, From 1ffecfe747002fa4540cb7e5f79690735b235ae4 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Tue, 17 Sep 2024 10:44:59 -0700 Subject: [PATCH 2/9] Prettier --- web/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/webpack.config.js b/web/webpack.config.js index c8596945..ca93d771 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -56,7 +56,7 @@ module.exports = (env, argv) => { // ``{project root}/web/``. filename: '../[file]', emit: false, - } + }, }, ], }, From f1fc7eca4fb46368549619bdfc8a33e973b0ff69 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Mon, 25 Nov 2024 11:15:16 -0800 Subject: [PATCH 3/9] Separate build command for schemas --- package.json | 4 +++- web/index.html | 2 ++ web/index.js | 11 ++++------- web/schemas.js | 9 +++++++++ web/webpack.config.js | 41 ++++++++++++++++++++++++++--------------- web/webpack.schemas.js | 29 +++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 web/schemas.js create mode 100644 web/webpack.schemas.js diff --git a/package.json b/package.json index 7a0a2af3..2e38e4d7 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,11 @@ "lint": "prettier --check . && eslint .", "clean:lib": "rimraf lib/dist", "clean:web": "rimraf web/dist", + "clean:schemas": "rimraf web/dist/dist-schemas web/dist/templates", "clean": "yarn clean:lib && yarn clean:web", "build:lib": "yarn clean:lib && rollup --config lib/rollup.config.js", - "build:web": "yarn clean:web && webpack --mode=production --config web/webpack.config.js", + "build:web": "yarn clean:web && webpack --mode=production --config web/webpack.config.js && yarn build:schemas", + "build:schemas": "yarn clean:schemas && webpack --config web/webpack.schemas.js", "dev": "webpack serve --mode=development --config web/webpack.config.js", "test": "jest tests/" }, diff --git a/web/index.html b/web/index.html index 6d6dc3ad..92dfb169 100644 --- a/web/index.html +++ b/web/index.html @@ -5,6 +5,8 @@ DataHarmonizer + +
diff --git a/web/index.js b/web/index.js index 52925b25..75f4ac5a 100644 --- a/web/index.js +++ b/web/index.js @@ -1,9 +1,10 @@ import { DataHarmonizer, Footer, Toolbar } from '../lib'; -import menu from './templates/menu.json'; import 'bootstrap/dist/css/bootstrap.min.css'; import './index.css'; +import {menu, getSchema, getExportFormats} from 'schemas'; + document.addEventListener('DOMContentLoaded', function () { const dhRoot = document.querySelector('#data-harmonizer-grid'); const dhFooterRoot = document.querySelector('#data-harmonizer-footer'); @@ -25,11 +26,7 @@ document.addEventListener('DOMContentLoaded', function () { new Toolbar(dhToolbarRoot, dh, menu, { templatePath: templatePath, releasesURL: 'https://github.com/cidgoh/pathogen-genomics-package/releases', - getSchema: async (schema) => { - return (await import(`./templates/${schema}/schema.json`)).default; - }, - getExportFormats: async (schema) => { - return (await import(`./templates/${schema}/export.js`)).default; - }, + getSchema: getSchema, + getExportFormats: getExportFormats, }); }); diff --git a/web/schemas.js b/web/schemas.js new file mode 100644 index 00000000..c5338f82 --- /dev/null +++ b/web/schemas.js @@ -0,0 +1,9 @@ +import menu_ from './templates/menu.json' + +export const menu = menu_; +export const getSchema = async (schema) => { + return (await import(`./templates/${schema}/schema.json`)).default; +}; +export const getExportFormats = async (schema) => { + return (await import(`./templates/${schema}/export.js`)).default; +}; diff --git a/web/webpack.config.js b/web/webpack.config.js index ca93d771..d022bfd2 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -10,27 +10,15 @@ module.exports = (env, argv) => { path: path.resolve(__dirname, 'dist'), filename: 'scripts/[name].js', }, + externals: { + schemas: 'schemas', + }, plugins: [ new HtmlWebpackPlugin({ template: './index.html', }), new CopyPlugin({ patterns: [ - { - context: 'templates', - from: '**/*.pdf', - to: 'templates/[path][name][ext]', - }, - { - context: 'templates', - from: '**/schema.yaml', - to: 'templates/[path][name][ext]', - }, - { - context: 'templates', - from: '**/exampleInput/*', - to: 'templates/[path][name][ext]', - }, { from: 'main.html', }, @@ -68,6 +56,29 @@ module.exports = (env, argv) => { if (argv.mode === 'development') { config.devtool = 'eval-source-map'; + config.resolve = { + alias: { + 'schemas': path.resolve(__dirname, 'schemas.js'), + }, + } + delete config.externals; + config.plugins.push( + new CopyPlugin({ + patterns: [ + { + context: 'templates', + from: '**/*.pdf', + to: 'templates/[path][name][ext]', + }, + ], + }), + ); + for (const rule of config.module.rules) { + if (rule.hasOwnProperty('generator')) { + delete rule.generator.filename; + delete rule.generator.emit; + } + } } return config; diff --git a/web/webpack.schemas.js b/web/webpack.schemas.js new file mode 100644 index 00000000..81be76fa --- /dev/null +++ b/web/webpack.schemas.js @@ -0,0 +1,29 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + context: path.resolve(__dirname), + entry: { + schemas: './schemas.js', + }, + output: { + path: path.resolve(__dirname, 'dist', 'dist-schemas'), + filename: '[name].js', + globalObject: 'this', + library: { + name: 'schemas', + type: 'umd', + }, + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { + context: 'templates', + from: '**/*.pdf', + to: '../templates/[path][name][ext]', + }, + ], + }), + ], +}; From faecdb6cf7a208d44f4213b85d035f243b63b4f5 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Mon, 25 Nov 2024 11:19:17 -0800 Subject: [PATCH 4/9] Prettier --- web/index.js | 2 +- web/schemas.js | 2 +- web/webpack.config.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/index.js b/web/index.js index 75f4ac5a..df455311 100644 --- a/web/index.js +++ b/web/index.js @@ -3,7 +3,7 @@ import { DataHarmonizer, Footer, Toolbar } from '../lib'; import 'bootstrap/dist/css/bootstrap.min.css'; import './index.css'; -import {menu, getSchema, getExportFormats} from 'schemas'; +import { menu, getSchema, getExportFormats } from 'schemas'; document.addEventListener('DOMContentLoaded', function () { const dhRoot = document.querySelector('#data-harmonizer-grid'); diff --git a/web/schemas.js b/web/schemas.js index c5338f82..87282349 100644 --- a/web/schemas.js +++ b/web/schemas.js @@ -1,4 +1,4 @@ -import menu_ from './templates/menu.json' +import menu_ from './templates/menu.json'; export const menu = menu_; export const getSchema = async (schema) => { diff --git a/web/webpack.config.js b/web/webpack.config.js index d022bfd2..2624b4fc 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -58,9 +58,9 @@ module.exports = (env, argv) => { config.devtool = 'eval-source-map'; config.resolve = { alias: { - 'schemas': path.resolve(__dirname, 'schemas.js'), + schemas: path.resolve(__dirname, 'schemas.js'), }, - } + }; delete config.externals; config.plugins.push( new CopyPlugin({ @@ -71,7 +71,7 @@ module.exports = (env, argv) => { to: 'templates/[path][name][ext]', }, ], - }), + }) ); for (const rule of config.module.rules) { if (rule.hasOwnProperty('generator')) { From f04c02a7ab22972eec224409f9b9269d45740fde Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Mon, 25 Nov 2024 11:23:22 -0800 Subject: [PATCH 5/9] Include schemas webpack file in eslintrc ignore --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 2b2592de..64e5283d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,6 +2,7 @@ module.exports = { ignorePatterns: [ '.eslintrc.js', 'web/webpack.config.js', + 'web/webpack.schemas.js', 'lib/rollup.config.js', '**/dist/**/*.js', '.venv', From a5f1463c41bc2644a0fdee359b21b27104cb7138 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Mon, 25 Nov 2024 13:18:04 -0800 Subject: [PATCH 6/9] Some comments --- web/index.html | 2 +- web/webpack.config.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/web/index.html b/web/index.html index 92dfb169..78a1a14a 100644 --- a/web/index.html +++ b/web/index.html @@ -5,7 +5,7 @@ DataHarmonizer - + diff --git a/web/webpack.config.js b/web/webpack.config.js index 2624b4fc..3cffcf63 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -11,6 +11,7 @@ module.exports = (env, argv) => { filename: 'scripts/[name].js', }, externals: { + // Schemas lib external to this webpack build. Imported in html file. schemas: 'schemas', }, plugins: [ @@ -54,14 +55,25 @@ module.exports = (env, argv) => { }, }; + // Difficult to run two webpack instances on a single dev server (i.e., this + // file, and the other webpack file that builds schemas). So for dev servers, + // we will insert all schema content into the webpack build generated by this + // file, and this singular build serves the entirety of the application. This + // is fine, because the whole point of having a separate build for schema + // content was to reduce production build times when users are only editing + // schema files (and not the rest of the application), but the dev server + // already gets around this problem through hot loading. if (argv.mode === 'development') { config.devtool = 'eval-source-map'; + // The schemas lib will come from a direct import of the javascript, instead + // of embedding an external lib into the html config.resolve = { alias: { schemas: path.resolve(__dirname, 'schemas.js'), }, }; delete config.externals; + // Need pdf SOPs that schema build previously supplied config.plugins.push( new CopyPlugin({ patterns: [ @@ -73,6 +85,7 @@ module.exports = (env, argv) => { ], }) ); + // False emits don't play nice with dev servers either for (const rule of config.module.rules) { if (rule.hasOwnProperty('generator')) { delete rule.generator.filename; From 7524716919c2ab01d74e1da8852f24a8b7a9fbc8 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Wed, 11 Dec 2024 13:42:48 -0800 Subject: [PATCH 7/9] Prettier --- lib/DataHarmonizer.js | 24 +++++++++++++++++------- lib/Validator.js | 4 +--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/DataHarmonizer.js b/lib/DataHarmonizer.js index 020d9511..a52df76b 100644 --- a/lib/DataHarmonizer.js +++ b/lib/DataHarmonizer.js @@ -1757,17 +1757,27 @@ class DataHarmonizer { // if sources exist, fetch transformed Value if (field.sources) { - if (field.multivalued === true) { //Map list of semicolon-delimited choices + if (field.multivalued === true) { + // Map list of semicolon-delimited choices // ISSUE: relying on semicolon delimiter in input for (let cellVal of mappedCellVal.split(';')) { - mappedCell.push( self.getTransformedField(headerName, cellVal.trim(), field, prefix)); + mappedCell.push( + self.getTransformedField( + headerName, + cellVal.trim(), + field, + prefix + ) + ); } + } else { + // Map single choice + mappedCell.push( + self.getTransformedField(headerName, mappedCellVal, field, prefix) + ); } - else { // Map single choice - mappedCell.push(self.getTransformedField(headerName, mappedCellVal, field, prefix)); - } - } - else { // No mapping. + } else { + // No mapping. mappedCell.push(mappedCellVal); } } diff --git a/lib/Validator.js b/lib/Validator.js index 36c29c73..7e785ca1 100644 --- a/lib/Validator.js +++ b/lib/Validator.js @@ -140,7 +140,6 @@ class Validator { this.#valueValidatorMap = new Map(); } - /* This returns a single primitve data type for a slot - a decimal, date, string etc. or possibly an enumeration. Enumerations are handled separately however (by const slotEnum = ...). Slots either use "range" @@ -150,7 +149,6 @@ class Validator { may be undefined if that is a menu too. */ getSlotType(slotDefinition) { - var slotType = this.#schema.types?.[slotDefinition.range]; if (slotType === undefined) { @@ -163,7 +161,7 @@ class Validator { } } - return slotType + return slotType; } getValidatorForSlot(slot, options = {}) { From 127e66ec607295302b384a98bc26205fdcf7cd60 Mon Sep 17 00:00:00 2001 From: Ivan S Gill Date: Mon, 16 Dec 2024 14:36:14 -0800 Subject: [PATCH 8/9] Update in-code docs --- web/webpack.config.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/web/webpack.config.js b/web/webpack.config.js index 3cffcf63..14201de3 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -11,7 +11,13 @@ module.exports = (env, argv) => { filename: 'scripts/[name].js', }, externals: { - // Schemas lib external to this webpack build. Imported in html file. + // Without declaring `schemas` as external, Webpack will attempt to look + // for the `schemas` library and bundle it. However, we want our schemas + // bundle to be separate from this one. This external config tells webpack + // that the schemas library will instead be supplied at runtime. External + // libraries can be provided in multiple ways, but we provide it through a + // script reference in the HTML file outputted by this bundle. + // https://webpack.js.org/configuration/externals/#externals schemas: 'schemas', }, plugins: [ @@ -57,16 +63,17 @@ module.exports = (env, argv) => { // Difficult to run two webpack instances on a single dev server (i.e., this // file, and the other webpack file that builds schemas). So for dev servers, - // we will insert all schema content into the webpack build generated by this - // file, and this singular build serves the entirety of the application. This - // is fine, because the whole point of having a separate build for schema - // content was to reduce production build times when users are only editing - // schema files (and not the rest of the application), but the dev server - // already gets around this problem through hot loading. + // we will stick to a singular build that concatenates both application and + // schema content. This is fine, because the whole point of having a separate + // build for schema content was to reduce production build times when users + // are only editing schema files (and not the rest of the application), but + // the dev server already gets around this problem through hot loading. if (argv.mode === 'development') { config.devtool = 'eval-source-map'; - // The schemas lib will come from a direct import of the javascript, instead - // of embedding an external lib into the html + // The external schemas lib is replaced by a direct reference to the + // schemas entrypoint. When you directly reference the schemas entrypoint in + // this bundle, a separate schemas library is not needed, because this + // bundle will now include all schema content as well. config.resolve = { alias: { schemas: path.resolve(__dirname, 'schemas.js'), From f10a1d13b6f81743032f2ac0814e50db1630b424 Mon Sep 17 00:00:00 2001 From: Kenneth Bruskiewicz Date: Mon, 16 Dec 2024 15:47:19 -0800 Subject: [PATCH 9/9] display tabs --- web/index.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/index.css b/web/index.css index 1b913b13..17b469af 100644 --- a/web/index.css +++ b/web/index.css @@ -9,7 +9,7 @@ body { /* For dh2-i18n-rc1 only! */ #data-harmonizer-tabs { - display: none; + /* display: none; */ } .data-harmonizer-grid .secondary-header-cell:hover {