@nanoporetech-digital/components 8.18.0 → 8.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{nano-data-table-CiPPql2J.js → nano-data-table-BC1htsdm.js} +47 -7
- package/dist/cjs/nano-data-table.cjs.entry.js +1 -1
- package/dist/cjs/nano-global-nav.cjs.entry.js +16 -12
- package/dist/cjs/{table.worker-D7SJpZlV.js → table.worker-BXs-g6xI.js} +2 -2
- package/dist/{esm/table.worker-TTndpijX.js → cjs/table.worker-DM_2DNEe.js} +1 -1
- package/dist/collection/components/breadcrumb/breadcrumb.js +1 -1
- package/dist/collection/components/data-table/table.property-utils.js +35 -0
- package/dist/collection/components/data-table/table.store.js +11 -5
- package/dist/collection/components/data-table/table.utils.js +6 -1
- package/dist/collection/components/data-table/table.worker.js +16 -10
- package/dist/collection/components/global-nav/global-nav.js +17 -13
- package/dist/components/nano-data-table.js +46 -6
- package/dist/components/nano-global-nav.js +16 -12
- package/dist/components/table.worker.js +1 -1
- package/dist/esm/{nano-data-table-BXdzSqWC.js → nano-data-table-Bn4l0Q3q.js} +47 -7
- package/dist/esm/nano-data-table.entry.js +1 -1
- package/dist/esm/nano-global-nav.entry.js +16 -12
- package/dist/esm/{table.worker-DftFV8Z7.js → table.worker-BMDbprO8.js} +2 -2
- package/dist/{nano-components/table.worker-TTndpijX.js → esm/table.worker-DM_2DNEe.js} +1 -1
- package/dist/nano-components/nano-data-table-Bn4l0Q3q.js +4 -0
- package/dist/nano-components/nano-data-table.entry.js +1 -1
- package/dist/nano-components/nano-global-nav.entry.js +1 -1
- package/dist/nano-components/table.worker-BMDbprO8.js +4 -0
- package/dist/{cjs/table.worker-TTndpijX.js → nano-components/table.worker-DM_2DNEe.js} +1 -1
- package/dist/types/components/data-table/table.property-utils.d.ts +7 -0
- package/dist/types/components/data-table/table.utils.d.ts +2 -1
- package/dist/types/components/global-nav/global-nav.d.ts +1 -1
- package/dist/types/components.d.ts +2 -2
- package/docs-json.json +3 -3
- package/docs-vscode.json +1 -1
- package/hydrate/index.js +77 -28
- package/hydrate/index.mjs +77 -28
- package/package.json +2 -2
- package/dist/nano-components/nano-data-table-BXdzSqWC.js +0 -4
- package/dist/nano-components/table.worker-DftFV8Z7.js +0 -4
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/generate-vue-component.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/index.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/output-vue.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/plugin.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/types.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/plugins/stencil/vue-output/utils.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/stencil.config.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/stencil.config.prod.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/testing/mocks/intersection-observer.d.ts +0 -0
- /package/dist/types/builds/{QrfEi4pt → YtJk83se}/0/Digital/nano-components/packages/components/.stencil/wdio.conf.d.ts +0 -0
|
@@ -114,7 +114,7 @@ const createWorkerProxy = (worker, workerMsgId, exportedMethod) => (
|
|
|
114
114
|
})
|
|
115
115
|
);
|
|
116
116
|
|
|
117
|
-
const workerPromise = Promise.resolve().then(function () { return require('./table.worker-
|
|
117
|
+
const workerPromise = Promise.resolve().then(function () { return require('./table.worker-BXs-g6xI.js'); }).then(m => m.worker);
|
|
118
118
|
const createWorkerStore = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'createWorkerStore');
|
|
119
119
|
const syncConfigToWorker = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'syncConfigToWorker');
|
|
120
120
|
const syncDataToWorker = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'syncDataToWorker');
|
|
@@ -195,8 +195,9 @@ function storeSetData(host, rows) {
|
|
|
195
195
|
// try our best to discern the column type (from first row) if unset
|
|
196
196
|
if (unknownCols.length && i === 0) {
|
|
197
197
|
store.config.state.columns = cols.map((col) => {
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
const val = getNestedProperty(row, col.prop);
|
|
199
|
+
if (unknownCols.includes(col) && val && !col.type) {
|
|
200
|
+
col.type = getDataType(val);
|
|
200
201
|
if (col.type === 'date')
|
|
201
202
|
dateCols.push(col.prop);
|
|
202
203
|
}
|
|
@@ -207,12 +208,16 @@ function storeSetData(host, rows) {
|
|
|
207
208
|
dateCols.forEach((colName) => {
|
|
208
209
|
// coerce any date type;
|
|
209
210
|
// Date(), timestamp, valid date string
|
|
210
|
-
const
|
|
211
|
-
|
|
211
|
+
const cellValue = getNestedProperty(row, colName);
|
|
212
|
+
const coerceDate = new Date(cellValue);
|
|
213
|
+
if (!!coerceDate && Number(coerceDate)) {
|
|
214
|
+
// Store as a flattened property (e.g., row["user.birthDate"])
|
|
215
|
+
// getNestedProperty will check this first before traversing nested structure
|
|
212
216
|
row[colName] = Number(coerceDate);
|
|
217
|
+
}
|
|
213
218
|
});
|
|
214
219
|
row['__index'] = i;
|
|
215
|
-
row['__uuid'] = math.cyrb53(cols.map((c) => row
|
|
220
|
+
row['__uuid'] = math.cyrb53(cols.map((c) => getNestedProperty(row, c.prop)).join());
|
|
216
221
|
return row;
|
|
217
222
|
});
|
|
218
223
|
store.data.state.rows = rows;
|
|
@@ -261,6 +266,39 @@ async function storeSort(host, prop, order) {
|
|
|
261
266
|
}
|
|
262
267
|
}
|
|
263
268
|
|
|
269
|
+
// Separate file (so it's safe to import into the worker)
|
|
270
|
+
/**
|
|
271
|
+
* Accesses a nested property using dot notation.
|
|
272
|
+
* @param obj - the object to access
|
|
273
|
+
* @param path - the property path (e.g., 'props.nested.name')
|
|
274
|
+
* @returns the value at the path, or undefined if not found
|
|
275
|
+
*/
|
|
276
|
+
function getNestedProperty(obj, path) {
|
|
277
|
+
if (!obj || path === null || path === undefined)
|
|
278
|
+
return undefined;
|
|
279
|
+
// Convert to string for consistent handling
|
|
280
|
+
const pathStr = String(path);
|
|
281
|
+
// Check for a flattened property first (optimization for transformed values)
|
|
282
|
+
// e.g., obj["user.birthDate"] takes precedence over obj.user.birthDate
|
|
283
|
+
if (obj[pathStr] !== undefined) {
|
|
284
|
+
return obj[pathStr];
|
|
285
|
+
}
|
|
286
|
+
// If the path doesn't contain a dot, just return the direct property
|
|
287
|
+
if (!pathStr.includes('.')) {
|
|
288
|
+
return obj[path];
|
|
289
|
+
}
|
|
290
|
+
// Split the path and traverse the object
|
|
291
|
+
const keys = pathStr.split('.');
|
|
292
|
+
let result = obj;
|
|
293
|
+
for (const key of keys) {
|
|
294
|
+
if (result === null || result === undefined) {
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
result = result[key];
|
|
298
|
+
}
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
|
|
264
302
|
/**
|
|
265
303
|
* Get a model object for custom cell / property renderers.
|
|
266
304
|
* @param rowIndex - the current row index being rendered
|
|
@@ -274,7 +312,9 @@ function colDataModel(rowIndex, colIndex) {
|
|
|
274
312
|
const column = columns[colIndex];
|
|
275
313
|
const prop = column?.prop;
|
|
276
314
|
const rowModel = rows[rowIndex];
|
|
277
|
-
const cellModel = rowModel
|
|
315
|
+
const cellModel = rowModel
|
|
316
|
+
? getNestedProperty(rowModel, columns[colIndex].prop)
|
|
317
|
+
: '';
|
|
278
318
|
return {
|
|
279
319
|
prop,
|
|
280
320
|
cellModel,
|
|
@@ -30,7 +30,7 @@ const GlobalNav = class {
|
|
|
30
30
|
/** Url to the Nanopore contact page */
|
|
31
31
|
contactUrl = 'https://nanoporetech.com/contact';
|
|
32
32
|
_sessionRedirect = window.location.href;
|
|
33
|
-
/** A url to take the user after login
|
|
33
|
+
/** A url to take the user after login or logout. Defaults to current URL. Is automatically URI encoded */
|
|
34
34
|
get sessionRedirect() {
|
|
35
35
|
return encodeURIComponent(this._sessionRedirect);
|
|
36
36
|
}
|
|
@@ -439,7 +439,11 @@ const GlobalNav = class {
|
|
|
439
439
|
return;
|
|
440
440
|
return (renderer.h("div", { part: "user-panel", class: `gn__user-panel nano-theme-dark` }, renderer.h("div", { class: "gn__user-panel-head", slot: "label" }, renderer.h("nano-avatar", { initials: this.myAccountUser.first_name?.charAt(0) +
|
|
441
441
|
this.myAccountUser.last_name?.charAt(0) }, this.myAccountUser.small_avatar_url &&
|
|
442
|
-
!this.myAccountUser.small_avatar_url.includes('generic') && (renderer.h("img", { src: this.myAccountUser.small_avatar_url, alt: "User Avatar", height: 40, width: 40 }))), renderer.h("div", null, this.myAccountUser.name, renderer.h("br", null), this.myAccountUser.job_title
|
|
442
|
+
!this.myAccountUser.small_avatar_url.includes('generic') && (renderer.h("img", { src: this.myAccountUser.small_avatar_url, alt: "User Avatar", height: 40, width: 40 }))), renderer.h("div", null, this.myAccountUser.name, renderer.h("br", null), this.myAccountUser.job_title && this.myAccountUser?.company
|
|
443
|
+
? `${this.myAccountUser.job_title}, ${this.myAccountUser.company}`
|
|
444
|
+
: this.myAccountUser.job_title ||
|
|
445
|
+
this.myAccountUser.company ||
|
|
446
|
+
'')), renderer.h("div", { class: "gn__user-panel-body" }, this.userLinks.map((link) => (renderer.h("a", { href: link.address, target: link.target || undefined }, link.title, (link.title === 'Messages' ||
|
|
443
447
|
link.address.includes(this.msgUrl) ||
|
|
444
448
|
this.msgUrl.includes(link.address)) &&
|
|
445
449
|
this.msgCount > 0 && (renderer.h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount)))))), renderer.h("div", { class: "gn__user-panel-foot" }, renderer.h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, renderer.h("a", { href: this.formatLoginLink(this.logoutUrl) }, "Logout")))));
|
|
@@ -484,21 +488,21 @@ const GlobalNav = class {
|
|
|
484
488
|
}
|
|
485
489
|
render() {
|
|
486
490
|
const bpps = this.bpPartials;
|
|
487
|
-
return (renderer.h(index.Host, { key: '
|
|
491
|
+
return (renderer.h(index.Host, { key: '63e6202a06bc4bc7a6a63f88d1923c3321a2b47c', class: {
|
|
488
492
|
'overflow-menu': this.breakpoint > bpps.mainMenu.breakpoint,
|
|
489
493
|
'bar-menu': this.breakpoint <= bpps.mainMenu.breakpoint,
|
|
490
494
|
'nano-global-nav': true,
|
|
491
|
-
} }, renderer.h("div", { key: '
|
|
495
|
+
} }, renderer.h("div", { key: '7fe0cb9446b86233ed7727fdc9aade6b94cb72eb', class: {
|
|
492
496
|
gn: true,
|
|
493
497
|
'gn__search-open': this.searchBarShown,
|
|
494
|
-
} }, renderer.h("nano-drawer", { key: '
|
|
498
|
+
} }, renderer.h("nano-drawer", { key: 'ef476cfee137ebbee63c2f7a99935d4aafd2f7e4', ref: (el) => (this.overflowMenu = el), label: "Main menu", part: "drawer", class: "gn__drawer nano-theme-dark", placement: "start", open: this.overflowOpen, onNanoAfterHide: () => (this.overflowOpen = false), onNanoAfterShow: () => (this.overflowOpen = true) }, renderer.h("div", { key: 'c4cbe27955caffeb4f4a7dc755b6b08bf40a7f48', class: "gn__drawer-header", part: "overflow-header", slot: "label" }, "Main menu"), renderer.h("nav", { key: '26ec816c93427ce9f9cc4025e327b5e6cf9ba3e2', class: "gn__drawer-menu", part: "overflow-menu" }, this.breakpoint > bpps.mainMenu.breakpoint
|
|
495
499
|
? bpps.mainMenu.tpl()
|
|
496
|
-
: '', renderer.h("slot", { key: '
|
|
500
|
+
: '', renderer.h("slot", { key: '0693a9f4afdf63e63151b3f3fd4d3a0bbedde4ef', name: "overflow" }))), renderer.h("div", { key: 'd9ff383fb0f91876a533e8eb98bc47817b044729', class: "gn__menu-bar-wrapper" }, renderer.h("div", { key: '4536fd7593626672f20191b197a55b3d7b10b633', class: "gn__menu-bar", part: "menu-bar", ref: (el) => (this.mainMenuBar = el) }, renderer.h("nav", { key: 'ad22eb106a5d9c0ffd8eac8e5e995833f8adcd7e', "aria-label": "Global navigation", class: `gn__main-menu ${this.shouldResize ? 'resizing' : ''}`, part: "main-menu", ref: (el) => (this.mainMenu = el) }, this.breakpoint > bpps.mainMenu.breakpoint && (renderer.h("nano-icon-button", { key: 'c399d0e0c2a909a94a0b93ad00ebc5cb34e8c224', class: "gn__overflow-button", iconName: "light/bars", label: "Open Menu", onClick: () => this.overflowMenu.show() })), renderer.h("slot", { key: 'ee03de047e3937687e722a88e34356ffc151a9e9', name: "logo" }, renderer.h("a", { key: 'a39aad67426cdc5ce75fa334a303229bfab9e58c', href: this.logoUrl, class: "gn__logo-link", part: "logo-link" }, this.breakpoint <= bpps.logo.breakpoint ? (renderer.h("img", { src: index.getAssetPath('../nano-assets/ont-logo.svg'), alt: `Oxford Nanopore Technologies logo. Features a stylised representation of a nanopore,
|
|
497
501
|
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--large", width: "152", height: "36", part: "logo logo--large" })) : (renderer.h("img", { src: index.getAssetPath('../nano-assets/ont-wheel.svg'), alt: `Oxford Nanopore Technologies logo. A stylised representation of a nanopore,
|
|
498
|
-
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--small", width: "36", height: "36", part: "logo logo--small" })))), this.breakpoint <= bpps.mainMenu.breakpoint && (renderer.h("div", { key: '
|
|
499
|
-
(!!this.searchIndices.length && (renderer.h("nano-dropdown", { key: '
|
|
502
|
+
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--small", width: "36", height: "36", part: "logo logo--small" })))), this.breakpoint <= bpps.mainMenu.breakpoint && (renderer.h("div", { key: '46a926ede075e0bfde746fa174c0700a48bc308e', class: "gn__main-menu-links" }, bpps.mainMenu.tpl())), renderer.h("div", { key: 'e473ba724a01a0f596f6494b7bb452eef0c4ba53', class: "gn__main-menu-actions" }, !this.myAccountData ||
|
|
503
|
+
(!!this.searchIndices.length && (renderer.h("nano-dropdown", { key: '90fa8c9cc0566374afce5f8c722aa98176372d7d', dialogTitle: "Search Oxford Nanopore Technologies", placement: "bottom", class: "gn__search-dropdown", skidding: -30, distance: 25, open: this.searchBarShown, onNanoAfterShow: this.handleSearchOpenEvent, onNanoAfterHide: this.handleSearchCloseEvent, autoOpen: !!this.searchIndices.length }, renderer.h("nano-icon-button", { key: '73c7c855dd6baf3259429d55c9bf3d58c2e8ec03', class: "gn__search-button", slot: "trigger", iconName: "light/magnifying-glass", label: "Search" }), renderer.h("form", { key: 'f265a2ba3269f22c2efcbe73c7ffe4328fe9d0e8', ref: (form) => (this.searchForm = form), class: "gn__search-form", part: "search-form", onSubmit: this.onSearchSubmit }, this.searchIndices.length > 1 && (renderer.h("nano-select", { key: '498ea9e7b0dd5bb10dd92b2df0fccc76295b1042', part: "search-select", label: "Which site do you wish to search in?", mask: true, hideLabel: true, value: this.activeIndex?.index, onNanoChange: this.handleSearchIndexChangeEvent }, this.searchIndices.map((index) => (renderer.h("nano-option", { selected: index.name === this.searchIndex, value: index.index }, index.name || index.index))))), renderer.h("nano-input", { key: '78baa1860b433e8ee36cd6f2d34d026a7c1e8b21', ref: (ele) => (this.searchInput = ele), part: "search-input", label: "Search Oxford Nanopore Technologies", placeholder: "Search Oxford Nanopore...", hideLabel: true, clearable: true, showInlineError: false, onNanoChange: (e) => {
|
|
500
504
|
this.handleSearchTermChangeEvent(e.detail.value);
|
|
501
|
-
}, onNanoInput: this.handleSearchTermInputEvent, debounce: 500, value: this._searchValue }, renderer.h("nano-icon", { key: '
|
|
505
|
+
}, onNanoInput: this.handleSearchTermInputEvent, debounce: 500, value: this._searchValue }, renderer.h("nano-icon", { key: 'f3b612bba31b0b1a930b170711080bce93324322', slot: "end", name: "light/magnifying-glass" }), renderer.h("nano-datalist", { key: 'a264479248b83b20cb42155e09c3033356a221b4', class: "gn__search-results", onNanoSelect: (e) => e.preventDefault(), dropDownConfig: { tetherTo: this.searchForm }, disableFilter: true }, this.searchLoading && (renderer.h("div", { key: '21d365a6554c31144d57900ec8cf50e6caa105b2', slot: "no-result", class: "gn__search-loading" }, renderer.h("nano-spinner", { key: 'b4f28c952fcfe765dea3ab7e4c0691e10de1317e' }, "Searching..."))), this.noResultPartial(), !!this.autocompleteResults?.hits.length && [
|
|
502
506
|
this.autocompleteResults.hits.map((hit, i) => (renderer.h("nano-option", { href: hit.url, class: "gn__search-result", onClick: () => {
|
|
503
507
|
searchInsights.searchInsight.sendClick({
|
|
504
508
|
index: this.activeIndex.index,
|
|
@@ -508,10 +512,10 @@ const GlobalNav = class {
|
|
|
508
512
|
positions: [i + 1],
|
|
509
513
|
});
|
|
510
514
|
} }, renderer.h("span", { innerHTML: this.autocompleteSnippet(hit) })))),
|
|
511
|
-
renderer.h("nano-option", { key: '
|
|
512
|
-
])))))), renderer.h("div", { key: '
|
|
515
|
+
renderer.h("nano-option", { key: 'b2a1dc7ff83c80599377850136d6233fa64cee3c', class: "gn__search-viewall", onNanoSelect: this.onSearchSubmit }, "View all results"),
|
|
516
|
+
])))))), renderer.h("div", { key: '38bc65edb00ef4876340fdfc1f308a6805a1e1ec', class: "gn__cart" }, renderer.h("nano-icon-button", { key: 'b590faedc935181b9230c82509360ddc2a19f1cf', iconName: "light/cart-shopping", label: "View your cart", href: this.cartUrl }), !!this.cartCount && (renderer.h("nano-badge", { key: 'c7f45eea27607c6d4380ccdf3a7f2cacfd26bc80', theme: "danger", strength: "2" }, this.cartCount > 9 ? '9+' : this.cartCount))), this.breakpoint <= bpps.contact.breakpoint
|
|
513
517
|
? bpps.contact.tpl()
|
|
514
|
-
: '', this.isLoggedIn ? (renderer.h("nano-dropdown", { dialogTitle: "User menu", class: "gn__user-dropdown", distance: 10, placement: "bottom-end" }, renderer.h("button", { slot: "trigger", class: "gn__user-dropdown-trigger" }, renderer.h("nano-icon", { name: "light/user" }), renderer.h("nano-icon", { name: "light/chevron-down", class: "gn__user-dropdown-chevron" }), !!this.msgCount && (renderer.h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount > 9 ? '9+' : this.msgCount))), this.loggedInPanel())) : (renderer.h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, renderer.h("a", { href: this.formatLoginLink(this.loginUrl) }, "Login"))))))), renderer.h("nano-global-search-results", { key: '
|
|
518
|
+
: '', this.isLoggedIn ? (renderer.h("nano-dropdown", { dialogTitle: "User menu", class: "gn__user-dropdown", distance: 10, placement: "bottom-end" }, renderer.h("button", { slot: "trigger", class: "gn__user-dropdown-trigger" }, renderer.h("nano-icon", { name: "light/user" }), renderer.h("nano-icon", { name: "light/chevron-down", class: "gn__user-dropdown-chevron" }), !!this.msgCount && (renderer.h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount > 9 ? '9+' : this.msgCount))), this.loggedInPanel())) : (renderer.h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, renderer.h("a", { href: this.formatLoginLink(this.loginUrl) }, "Login"))))))), renderer.h("nano-global-search-results", { key: '6443d9f0199f87ba5ca73b62b6c3c9e5700731b4', part: "site-search-results" }, renderer.h("div", { key: 'db0ce2d9157f7144b0c50d0833386ed4eeabdd02', class: "gn__site", part: "site-wrapper" }, renderer.h("slot", { key: 'a9ac7197c149153532f16f8f0f428b5e46d11b72' }))))));
|
|
515
519
|
}
|
|
516
520
|
static get assetsDirs() { return ["assets"]; }
|
|
517
521
|
static get watchers() { return {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
var nanoDataTable_entry = require('./nano-data-table-
|
|
6
|
+
var nanoDataTable_entry = require('./nano-data-table-BC1htsdm.js');
|
|
7
7
|
require('./index-DGttnXif.js');
|
|
8
8
|
require('./renderer-jVpDRMfV.js');
|
|
9
9
|
require('./math-DIjJ3V87.js');
|
|
@@ -14,7 +14,7 @@ require('./index-CkLcAUj-.js');
|
|
|
14
14
|
|
|
15
15
|
const workerName = 'table.worker';
|
|
16
16
|
const workerMsgId = 'stencil.table.worker';
|
|
17
|
-
const workerPath = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__dirname + '/table.worker-
|
|
17
|
+
const workerPath = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__dirname + '/table.worker-DM_2DNEe.js').href : new URL('table.worker-DM_2DNEe.js', document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || document.baseURI).href);
|
|
18
18
|
exports.worker = void 0;
|
|
19
19
|
try {
|
|
20
20
|
// first try directly starting the worker with the URL
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Custom elements for Nanopore-Digital Web applications
|
|
3
3
|
*/
|
|
4
|
-
(()=>{const n=(n,t)=>{const r=globalThis[t];return null!=r&&n instanceof r},t=r=>{if(null!=r){if(n(r,"ArrayBuffer")||n(r,"MessagePort")||n(r,"ImageBitmap")||n(r,"OffscreenCanvas"))return[r];if("object"==typeof r)return r.constructor===Object&&(r=Object.values(r)),Array.isArray(r)?r.flatMap(t):t(r.buffer)}return[]},r={},e="stencil.table.worker",o=e+".cb";addEventListener("message",(async({data:n})=>{if(n&&n[0]===e){let u,i,c=n[1],s=n[2],f=n[3],a=0,l=f.length;try{for(;a<l;a++)if(Array.isArray(f[a])&&f[a][0]===o){const n=f[a][1];f[a]=(...t)=>{postMessage([o,n,t])}}u=await r[s](...f)}catch(n){u=null,i=n instanceof Error?{isError:!0,value:{message:n.message,name:n.name,stack:n.stack}}:{isError:!1,value:n},u=void 0}const p=t(u);postMessage([e,c,u,i],p)}}));var u,i,c="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function s(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var f=s(function(){if(i)return u;i=1;var n=/[\\^$.*+?()[\]{}|]/g,t=RegExp(n.source),r="object"==typeof self&&self&&self.Object===Object&&self,e="object"==typeof c&&c&&c.Object===Object&&c||r||Function("return this")(),o=Object.prototype.toString,s=e.Symbol,f=s?s.prototype:void 0,a=f?f.toString:void 0;return u=function(r){var e;return(r=null==(e=r)?"":function(n){if("string"==typeof n)return n;if(function(n){return"symbol"==typeof n||function(n){return!!n&&"object"==typeof n}(n)&&"[object Symbol]"==o.call(n)}(n))return a?a.call(n):"";var t=n+"";return"0"==t&&1/n==-1/0?"-0":t}(e))&&t.test(r)?r.replace(n,"\\$&"):r}}());function a(n,t,r,e){if("object"!=typeof n){if("exists"===t.type)return!!t.key.test(r.join("."))&&!!n;{const o=r.join(".");for(const n of e.ignorePaths)if(n.test(o))return!1;if(e.includePaths){let n=!1;for(const t of e.includePaths)if(t.test(o)){n=!0;break}if(!n)return!1}return!(t.key&&!t.key.test(o))&&function(n,t){return"string"==typeof n?t.checkString(n):"number"==typeof n&&t.checkNumber(n)}(n,t)}}if(Array.isArray(n)){for(const o of n)if(a(o,t,r,e))return!0}else for(const o in n){r.push(o);const u=a(n[o],t,r,e);if(r.pop(),u)return!0}return!1}function l(n,t,r,e){if(t.length>0){let o=!1;for(const u of t)if(a(n,u,[],e)?!u.negate:u.negate){if("OR"===r)return!0;o=!0}else if("AND"===r)return!1;return o}return!0}function p(n,t){const r=[];let e=!1,o=0,u="";for(let i=0;i<n.length;i++){const c=n[i];e?c===u&&(e=!1,u=""):'"'===c||"'"===c?(e=!0,u=c):c.match(t)&&!e&&(r.push(n.slice(o,i).trim()),o=i+1),i===n.length-1&&r.push(n.slice(o).trim())}return r.map((n=>n.startsWith('"')&&n.endsWith('"')||n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n)).filter(Boolean)}const d={"<":function(n){const t=Number(n[0]);return n=>n<t},"<=":function(n){const t=Number(n[0]);return n=>n<=t},"=":function(n){const t=n[0].split(",").filter(Boolean).map(Number);return n=>{for(const r of t)if(n===r)return!0;return!1}},">=":function(n){const t=Number(n[0]);return n=>n>=t},">":function(n){const t=Number(n[0]);return n=>n>t},"..":function(n){const t=Number(n[0]),r=Number(n[1]);return n=>n>=t&&n<=r}};function w(n){const{values:t,operator:r}=function(n){const t=/^\s*\(?\s*(?<startOperator><=|>=|<|=|>|\.\.\s*)?\s*(?<firstValue>-?\d*\.?\d+)\s*(?:(?<afterDots>\.\.)\s*(?<secondValue>-?\d*\.?\d*))?\s*\)?\s*$/.exec(n);if(!t)return{operator:"=",values:[n]};if(!t.groups)throw new Error("unreachable");const{startOperator:r,firstValue:e,afterDots:o,secondValue:u}=t.groups;let i=r;const c=e?[e]:[];return".."===r?i="<=":r||!o||u?o&&(i=".."):i=">=",u&&(Number(u)<Number(e)?c.unshift(u):c.push(u)),{values:c,operator:i||"="}}(n),e=d[r];if(!e)throw new Error(`unknown operator ${r}`);return e(t)}const h={"<":function(n){return t=>t<n[0]},"<=":function(n){return t=>t<=n[0]},"=":function(n,t){const r=p(n[0],",").filter(Boolean).map((n=>new RegExp(`^${f(n)}$`,t)));return n=>{for(const t of r)if(t.test(n))return!0;return!1}},"~":function(n,t){const r=p(n[0],",").filter(Boolean).map((n=>new RegExp(f(n),t)));return n=>{for(const t of r)if(t.test(n))return!0;return!1}},">=":function(n){return t=>t>=n[0]},">":function(n){return t=>t>n[0]},"..":function(n){return t=>t>=n[0]&&t<=n[1]}};function y(n,t){const{values:r,operator:e}=function(n){const t=n.split(".."),r=/^\s*\(?(?<operator><=|<|=|>=|>)?\s*(?<value>\S*)\s*\)?$/.exec(t[0]);if(!r)return{operator:"~",values:[n]};if(!r.groups)throw new Error("unreachable");const{value:e}=r.groups;let{operator:o}=r.groups;const u=t[1]?.trim();let i=[e];return t.length>1&&(o="..",u?e?e<u?i.push(u):i.unshift(u):(i=[u],o="<="):o=">="),{operator:o||"~",values:i}}(n),o=h[e];if(!o)throw new Error(`unreachable unknown operator ${e}`);return o(r,t)}function
|
|
4
|
+
(()=>{const n=(n,t)=>{const r=globalThis[t];return null!=r&&n instanceof r},t=r=>{if(null!=r){if(n(r,"ArrayBuffer")||n(r,"MessagePort")||n(r,"ImageBitmap")||n(r,"OffscreenCanvas"))return[r];if("object"==typeof r)return r.constructor===Object&&(r=Object.values(r)),Array.isArray(r)?r.flatMap(t):t(r.buffer)}return[]},r={},e="stencil.table.worker",o=e+".cb";addEventListener("message",(async({data:n})=>{if(n&&n[0]===e){let u,i,c=n[1],s=n[2],f=n[3],a=0,l=f.length;try{for(;a<l;a++)if(Array.isArray(f[a])&&f[a][0]===o){const n=f[a][1];f[a]=(...t)=>{postMessage([o,n,t])}}u=await r[s](...f)}catch(n){u=null,i=n instanceof Error?{isError:!0,value:{message:n.message,name:n.name,stack:n.stack}}:{isError:!1,value:n},u=void 0}const p=t(u);postMessage([e,c,u,i],p)}}));var u,i,c="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function s(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var f=s(function(){if(i)return u;i=1;var n=/[\\^$.*+?()[\]{}|]/g,t=RegExp(n.source),r="object"==typeof self&&self&&self.Object===Object&&self,e="object"==typeof c&&c&&c.Object===Object&&c||r||Function("return this")(),o=Object.prototype.toString,s=e.Symbol,f=s?s.prototype:void 0,a=f?f.toString:void 0;return u=function(r){var e;return(r=null==(e=r)?"":function(n){if("string"==typeof n)return n;if(function(n){return"symbol"==typeof n||function(n){return!!n&&"object"==typeof n}(n)&&"[object Symbol]"==o.call(n)}(n))return a?a.call(n):"";var t=n+"";return"0"==t&&1/n==-1/0?"-0":t}(e))&&t.test(r)?r.replace(n,"\\$&"):r}}());function a(n,t,r,e){if("object"!=typeof n){if("exists"===t.type)return!!t.key.test(r.join("."))&&!!n;{const o=r.join(".");for(const n of e.ignorePaths)if(n.test(o))return!1;if(e.includePaths){let n=!1;for(const t of e.includePaths)if(t.test(o)){n=!0;break}if(!n)return!1}return!(t.key&&!t.key.test(o))&&function(n,t){return"string"==typeof n?t.checkString(n):"number"==typeof n&&t.checkNumber(n)}(n,t)}}if(Array.isArray(n)){for(const o of n)if(a(o,t,r,e))return!0}else for(const o in n){r.push(o);const u=a(n[o],t,r,e);if(r.pop(),u)return!0}return!1}function l(n,t,r,e){if(t.length>0){let o=!1;for(const u of t)if(a(n,u,[],e)?!u.negate:u.negate){if("OR"===r)return!0;o=!0}else if("AND"===r)return!1;return o}return!0}function p(n,t){const r=[];let e=!1,o=0,u="";for(let i=0;i<n.length;i++){const c=n[i];e?c===u&&(e=!1,u=""):'"'===c||"'"===c?(e=!0,u=c):c.match(t)&&!e&&(r.push(n.slice(o,i).trim()),o=i+1),i===n.length-1&&r.push(n.slice(o).trim())}return r.map((n=>n.startsWith('"')&&n.endsWith('"')||n.startsWith("'")&&n.endsWith("'")?n.slice(1,-1):n)).filter(Boolean)}const d={"<":function(n){const t=Number(n[0]);return n=>n<t},"<=":function(n){const t=Number(n[0]);return n=>n<=t},"=":function(n){const t=n[0].split(",").filter(Boolean).map(Number);return n=>{for(const r of t)if(n===r)return!0;return!1}},">=":function(n){const t=Number(n[0]);return n=>n>=t},">":function(n){const t=Number(n[0]);return n=>n>t},"..":function(n){const t=Number(n[0]),r=Number(n[1]);return n=>n>=t&&n<=r}};function w(n){const{values:t,operator:r}=function(n){const t=/^\s*\(?\s*(?<startOperator><=|>=|<|=|>|\.\.\s*)?\s*(?<firstValue>-?\d*\.?\d+)\s*(?:(?<afterDots>\.\.)\s*(?<secondValue>-?\d*\.?\d*))?\s*\)?\s*$/.exec(n);if(!t)return{operator:"=",values:[n]};if(!t.groups)throw new Error("unreachable");const{startOperator:r,firstValue:e,afterDots:o,secondValue:u}=t.groups;let i=r;const c=e?[e]:[];return".."===r?i="<=":r||!o||u?o&&(i=".."):i=">=",u&&(Number(u)<Number(e)?c.unshift(u):c.push(u)),{values:c,operator:i||"="}}(n),e=d[r];if(!e)throw new Error(`unknown operator ${r}`);return e(t)}const h={"<":function(n){return t=>t<n[0]},"<=":function(n){return t=>t<=n[0]},"=":function(n,t){const r=p(n[0],",").filter(Boolean).map((n=>new RegExp(`^${f(n)}$`,t)));return n=>{for(const t of r)if(t.test(n))return!0;return!1}},"~":function(n,t){const r=p(n[0],",").filter(Boolean).map((n=>new RegExp(f(n),t)));return n=>{for(const t of r)if(t.test(n))return!0;return!1}},">=":function(n){return t=>t>=n[0]},">":function(n){return t=>t>n[0]},"..":function(n){return t=>t>=n[0]&&t<=n[1]}};function y(n,t){const{values:r,operator:e}=function(n){const t=n.split(".."),r=/^\s*\(?(?<operator><=|<|=|>=|>)?\s*(?<value>\S*)\s*\)?$/.exec(t[0]);if(!r)return{operator:"~",values:[n]};if(!r.groups)throw new Error("unreachable");const{value:e}=r.groups;let{operator:o}=r.groups;const u=t[1]?.trim();let i=[e];return t.length>1&&(o="..",u?e?e<u?i.push(u):i.unshift(u):(i=[u],o="<="):o=">="),{operator:o||"~",values:i}}(n),o=h[e];if(!o)throw new Error(`unreachable unknown operator ${e}`);return o(r,t)}function g(n,t={}){const{index:r=!1,predicate:e="AND",ignorePaths:o=[],includePaths:u,pathAlias:i={}}=t,c=t.limit||1/0,s=t.caseSensitive?"":"i";let a=t.keywords||[];const d=function(n,t){const{insensitive:r}=t,e={};for(const[t,o]of Object.entries(n))e[t]=o instanceof RegExp?o:new RegExp(`(^|\\.)${f(o)}(\\.|$)`,r);return e}(i,{insensitive:s}),h=o.map((n=>"string"==typeof n?new RegExp(`(^|\\.)${f(n)}(\\.|$)`,s):n)),g=u?u.map((n=>"string"==typeof n?new RegExp(`(^|\\.)${f(n)}(\\.|$)`,s):n)):void 0;"string"==typeof a&&(a=p(a,/[\t\n\r ]/));const b=function(n,t={}){return n.map((n=>function(n,t={}){const{caseSensitive:r,pathAlias:e={}}=t,o=r?"":"i";let u=!1;n.startsWith("-")&&(u=!0,n=n.slice(1));const i=n.indexOf(":");if(-1!==i){const t=n.slice(Math.max(0,i+1));if(i>0){const r=n.slice(0,Math.max(0,i));return"is"===r?{type:"exists",negate:u,key:new RegExp(`(^|\\.)${f(t)}(\\.|$)`,o)}:{type:"matches",negate:u,key:e[r]||new RegExp(`(^|\\.)${f(r)}(\\.|$)`,o),checkNumber:w(t),checkString:y(t,o)}}}return{type:"matches",negate:u,checkNumber:w(n),checkString:y(n,o)}}(n,t)))}(a,{caseSensitive:t.caseSensitive,pathAlias:d});let v=0;if(r){const t=[];for(let r=0;r<n.length&&v<c;r++)l(n[r],b,e,{ignorePaths:h,includePaths:g})&&(v=t.push(r));return t}{const t=[];for(let r=0;r<n.length&&v<c;r++)l(n[r],b,e,{ignorePaths:h,includePaths:g})&&(v=t.push(n[r]));return t}}function b(n,t){if(!n||null==t)return;const r=String(t);if(void 0!==n[r])return n[r];if(!r.includes("."))return n[t];const e=r.split(".");let o=n;for(const n of e){if(null==o)return;o=o[n]}return o}const v=new Map;async function m(n,t){const r=v.get(n);if(!r)throw new Error("cannot find worker with ID "+n);if(r.searchTerm=t,!t||!t.length)return r.filterRows=r.rows,$(r,r.rows);const e=r.columns.filter((n=>!1!==n.searchable));return r.filterRows=g(r.rows,{keywords:t,predicate:"OR",includePaths:[...e.map((n=>n.prop))],ignorePaths:["__uuid","__index"]}),$(r,r.filterRows)}function E(n,t,r=[],e=!1){return r&&r.length||e||(r=function(n){return n.columns.filter((n=>null!=n.filter)).reduce(((n,t)=>{const{prop:r,filter:e}=t;return n.push({prop:r,filter:e}),n}),[])}(n)),r&&r.length?(r.forEach((n=>{t="boolean"==typeof n.filter?t.filter((t=>b(t,n.prop)===n.filter)):g(t,{predicate:"string"==typeof n.filter?"AND":"OR",keywords:n.filter,includePaths:[n.prop],ignorePaths:["__uuid","__index"]})})),t):t}function k(n,t,r,e){if(!r&&!e){const t=function(n){const t=n.columns.find((n=>!!n.order));if(t){const{prop:n,order:r}=t;return{prop:n,order:r}}return null}(n);t&&({prop:r,order:e}=t)}if(!r||!e||!t.length)return t;const o=n.columns.find((n=>n.prop===r));return o?.sortCompareFn&&"function"==typeof o.sortCompareFn?t.slice().sort(o.sortCompareFn(r,e)):"text"===o?.type&&"string"==typeof b(t[0],r)?t.slice().sort(((n,t)=>{const o=b(n,r),u=b(t,r);return o?u?"asc"===e?o.localeCompare(u):u.localeCompare(o):-1:1})):t.slice().sort(((n,t)=>{const o=b(n,r),u=b(t,r);return[void 0,null].includes(o)?1:[void 0,null].includes(u)?-1:o<u?"asc"===e?-1:1:o>u?"asc"===e?1:-1:0}))}function $(n,t){return k(n,t=E(n,t))}function x(n){return n.map((n=>(n?.sortCompareFn&&"string"==typeof n.sortCompareFn&&(n.sortCompareFn=new Function("return "+n.sortCompareFn)()),n)))}async function N(n){v.delete(n)}r.createWorkerStore=async function(n,t){const r=Date.now().toString(36)+Math.random().toString(36).substring(2);return v.set(r,{rows:n,columns:x(t)}),r},r.destroyWorkerStore=N,r.syncConfigToWorker=async function(n,t){const r=v.get(n);if(!r)throw new Error("cannot find worker with ID "+n);return r.columns=x(t),r.rows||r.columns||N(n),!0},r.syncDataToWorker=async function(n,t){const r=v.get(n);if(!r)throw new Error("cannot find worker with ID "+n);return r.rows=t,r.rows||r.columns||N(n),!0},r.workerFilter=async function(n,t){const r=v.get(n);if(!r)throw new Error("cannot find worker with ID "+n);const e=t&&t.length||!r.searchTerm?r.searchTerm?r.filterRows:r.rows:await m(n,r.searchTerm);return r.filterRows=E(r,e,t,!0),k(r,r.filterRows)},r.workerSearch=m,r.workerSort=async function(n,t,r){const e=v.get(n);if(!e)throw new Error("cannot find worker with ID "+n);return k(e,e.filterRows||e.rows,t,r)}})();
|
|
@@ -89,7 +89,7 @@ export class NanoBreadcrumb {
|
|
|
89
89
|
"references": {
|
|
90
90
|
"Breadcrumb": {
|
|
91
91
|
"location": "local",
|
|
92
|
-
"path": "/builds/
|
|
92
|
+
"path": "/builds/YtJk83se/0/Digital/nano-components/packages/components/src/components/breadcrumb/breadcrumb.tsx",
|
|
93
93
|
"id": "src/components/breadcrumb/breadcrumb.tsx::Breadcrumb"
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Custom elements for Nanopore-Digital Web applications
|
|
3
|
+
*/
|
|
4
|
+
// Separate file (so it's safe to import into the worker)
|
|
5
|
+
/**
|
|
6
|
+
* Accesses a nested property using dot notation.
|
|
7
|
+
* @param obj - the object to access
|
|
8
|
+
* @param path - the property path (e.g., 'props.nested.name')
|
|
9
|
+
* @returns the value at the path, or undefined if not found
|
|
10
|
+
*/
|
|
11
|
+
export function getNestedProperty(obj, path) {
|
|
12
|
+
if (!obj || path === null || path === undefined)
|
|
13
|
+
return undefined;
|
|
14
|
+
// Convert to string for consistent handling
|
|
15
|
+
const pathStr = String(path);
|
|
16
|
+
// Check for a flattened property first (optimization for transformed values)
|
|
17
|
+
// e.g., obj["user.birthDate"] takes precedence over obj.user.birthDate
|
|
18
|
+
if (obj[pathStr] !== undefined) {
|
|
19
|
+
return obj[pathStr];
|
|
20
|
+
}
|
|
21
|
+
// If the path doesn't contain a dot, just return the direct property
|
|
22
|
+
if (!pathStr.includes('.')) {
|
|
23
|
+
return obj[path];
|
|
24
|
+
}
|
|
25
|
+
// Split the path and traverse the object
|
|
26
|
+
const keys = pathStr.split('.');
|
|
27
|
+
let result = obj;
|
|
28
|
+
for (const key of keys) {
|
|
29
|
+
if (result === null || result === undefined) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
result = result[key];
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { createStore } from "@stencil/store";
|
|
5
5
|
import { cyrb53 } from "../../utils/math";
|
|
6
6
|
import { createWorkerStore, syncConfigToWorker, syncDataToWorker, workerFilter, workerSearch, workerSort, } from "./table.worker";
|
|
7
|
+
import { getNestedProperty } from "./table.utils";
|
|
7
8
|
function colsToWorker(columns) {
|
|
8
9
|
const safeColumns = JSON.parse(JSON.stringify(columns));
|
|
9
10
|
columns.forEach((c) => {
|
|
@@ -77,8 +78,9 @@ export function storeSetData(host, rows) {
|
|
|
77
78
|
// try our best to discern the column type (from first row) if unset
|
|
78
79
|
if (unknownCols.length && i === 0) {
|
|
79
80
|
store.config.state.columns = cols.map((col) => {
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
const val = getNestedProperty(row, col.prop);
|
|
82
|
+
if (unknownCols.includes(col) && val && !col.type) {
|
|
83
|
+
col.type = getDataType(val);
|
|
82
84
|
if (col.type === 'date')
|
|
83
85
|
dateCols.push(col.prop);
|
|
84
86
|
}
|
|
@@ -89,12 +91,16 @@ export function storeSetData(host, rows) {
|
|
|
89
91
|
dateCols.forEach((colName) => {
|
|
90
92
|
// coerce any date type;
|
|
91
93
|
// Date(), timestamp, valid date string
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
+
const cellValue = getNestedProperty(row, colName);
|
|
95
|
+
const coerceDate = new Date(cellValue);
|
|
96
|
+
if (!!coerceDate && Number(coerceDate)) {
|
|
97
|
+
// Store as a flattened property (e.g., row["user.birthDate"])
|
|
98
|
+
// getNestedProperty will check this first before traversing nested structure
|
|
94
99
|
row[colName] = Number(coerceDate);
|
|
100
|
+
}
|
|
95
101
|
});
|
|
96
102
|
row['__index'] = i;
|
|
97
|
-
row['__uuid'] = cyrb53(cols.map((c) => row
|
|
103
|
+
row['__uuid'] = cyrb53(cols.map((c) => getNestedProperty(row, c.prop)).join());
|
|
98
104
|
return row;
|
|
99
105
|
});
|
|
100
106
|
store.data.state.rows = rows;
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import { getRenderingRef, getElement, h, Fragment } from "@stencil/core";
|
|
5
5
|
import { getStore } from "./table.store";
|
|
6
6
|
import { CSSNAMESPACE } from "./table.constants";
|
|
7
|
+
import { getNestedProperty } from "./table.property-utils";
|
|
8
|
+
// Re-export for convenience
|
|
9
|
+
export { getNestedProperty };
|
|
7
10
|
/**
|
|
8
11
|
* Get a model object for custom cell / property renderers.
|
|
9
12
|
* @param rowIndex - the current row index being rendered
|
|
@@ -17,7 +20,9 @@ export function colDataModel(rowIndex, colIndex) {
|
|
|
17
20
|
const column = columns[colIndex];
|
|
18
21
|
const prop = column?.prop;
|
|
19
22
|
const rowModel = rows[rowIndex];
|
|
20
|
-
const cellModel = rowModel
|
|
23
|
+
const cellModel = rowModel
|
|
24
|
+
? getNestedProperty(rowModel, columns[colIndex].prop)
|
|
25
|
+
: '';
|
|
21
26
|
return {
|
|
22
27
|
prop,
|
|
23
28
|
cellModel,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Custom elements for Nanopore-Digital Web applications
|
|
3
3
|
*/
|
|
4
4
|
import { filter as smartFilter } from "smart-array-filter";
|
|
5
|
+
import { getNestedProperty } from "./table.property-utils";
|
|
5
6
|
const dataWorkers = new Map();
|
|
6
7
|
function uid() {
|
|
7
8
|
return Date.now().toString(36) + Math.random().toString(36).substring(2);
|
|
@@ -91,7 +92,7 @@ function filter(workerStore, rows, filters = [], force = false) {
|
|
|
91
92
|
return rows;
|
|
92
93
|
filters.forEach((filter) => {
|
|
93
94
|
if (typeof filter.filter === 'boolean') {
|
|
94
|
-
rows = rows.filter((row) => row
|
|
95
|
+
rows = rows.filter((row) => getNestedProperty(row, filter.prop) === filter.filter);
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
98
|
rows = smartFilter(rows, {
|
|
@@ -154,27 +155,32 @@ function sort(workerStore, rows, prop, order) {
|
|
|
154
155
|
return sorted;
|
|
155
156
|
}
|
|
156
157
|
// text sort
|
|
157
|
-
if (col?.type === 'text' &&
|
|
158
|
+
if (col?.type === 'text' &&
|
|
159
|
+
typeof getNestedProperty(rows[0], prop) === 'string') {
|
|
158
160
|
const sorted = rows.slice().sort((a, b) => {
|
|
159
|
-
|
|
161
|
+
const aVal = getNestedProperty(a, prop);
|
|
162
|
+
const bVal = getNestedProperty(b, prop);
|
|
163
|
+
if (!aVal)
|
|
160
164
|
return 1;
|
|
161
|
-
if (!
|
|
165
|
+
if (!bVal)
|
|
162
166
|
return -1;
|
|
163
167
|
return order === 'asc'
|
|
164
|
-
?
|
|
165
|
-
:
|
|
168
|
+
? aVal.localeCompare(bVal)
|
|
169
|
+
: bVal.localeCompare(aVal);
|
|
166
170
|
});
|
|
167
171
|
return sorted;
|
|
168
172
|
}
|
|
169
173
|
// catch-all - number / date / string sort
|
|
170
174
|
const sorted = rows.slice().sort((a, b) => {
|
|
171
|
-
|
|
175
|
+
const aVal = getNestedProperty(a, prop);
|
|
176
|
+
const bVal = getNestedProperty(b, prop);
|
|
177
|
+
if ([undefined, null].includes(aVal))
|
|
172
178
|
return 1;
|
|
173
|
-
if ([undefined, null].includes(
|
|
179
|
+
if ([undefined, null].includes(bVal))
|
|
174
180
|
return -1;
|
|
175
|
-
if (
|
|
181
|
+
if (aVal < bVal)
|
|
176
182
|
return order === 'asc' ? -1 : 1;
|
|
177
|
-
if (
|
|
183
|
+
if (aVal > bVal)
|
|
178
184
|
return order === 'asc' ? 1 : -1;
|
|
179
185
|
return 0;
|
|
180
186
|
});
|
|
@@ -50,7 +50,7 @@ export class GlobalNav {
|
|
|
50
50
|
/** Url to the Nanopore contact page */
|
|
51
51
|
contactUrl = 'https://nanoporetech.com/contact';
|
|
52
52
|
_sessionRedirect = window.location.href;
|
|
53
|
-
/** A url to take the user after login
|
|
53
|
+
/** A url to take the user after login or logout. Defaults to current URL. Is automatically URI encoded */
|
|
54
54
|
get sessionRedirect() {
|
|
55
55
|
return encodeURIComponent(this._sessionRedirect);
|
|
56
56
|
}
|
|
@@ -455,7 +455,11 @@ export class GlobalNav {
|
|
|
455
455
|
return;
|
|
456
456
|
return (h("div", { part: "user-panel", class: `gn__user-panel nano-theme-dark` }, h("div", { class: "gn__user-panel-head", slot: "label" }, h("nano-avatar", { initials: this.myAccountUser.first_name?.charAt(0) +
|
|
457
457
|
this.myAccountUser.last_name?.charAt(0) }, this.myAccountUser.small_avatar_url &&
|
|
458
|
-
!this.myAccountUser.small_avatar_url.includes('generic') && (h("img", { src: this.myAccountUser.small_avatar_url, alt: "User Avatar", height: 40, width: 40 }))), h("div", null, this.myAccountUser.name, h("br", null), this.myAccountUser.job_title
|
|
458
|
+
!this.myAccountUser.small_avatar_url.includes('generic') && (h("img", { src: this.myAccountUser.small_avatar_url, alt: "User Avatar", height: 40, width: 40 }))), h("div", null, this.myAccountUser.name, h("br", null), this.myAccountUser.job_title && this.myAccountUser?.company
|
|
459
|
+
? `${this.myAccountUser.job_title}, ${this.myAccountUser.company}`
|
|
460
|
+
: this.myAccountUser.job_title ||
|
|
461
|
+
this.myAccountUser.company ||
|
|
462
|
+
'')), h("div", { class: "gn__user-panel-body" }, this.userLinks.map((link) => (h("a", { href: link.address, target: link.target || undefined }, link.title, (link.title === 'Messages' ||
|
|
459
463
|
link.address.includes(this.msgUrl) ||
|
|
460
464
|
this.msgUrl.includes(link.address)) &&
|
|
461
465
|
this.msgCount > 0 && (h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount)))))), h("div", { class: "gn__user-panel-foot" }, h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, h("a", { href: this.formatLoginLink(this.logoutUrl) }, "Logout")))));
|
|
@@ -500,21 +504,21 @@ export class GlobalNav {
|
|
|
500
504
|
}
|
|
501
505
|
render() {
|
|
502
506
|
const bpps = this.bpPartials;
|
|
503
|
-
return (h(Host, { key: '
|
|
507
|
+
return (h(Host, { key: '63e6202a06bc4bc7a6a63f88d1923c3321a2b47c', class: {
|
|
504
508
|
'overflow-menu': this.breakpoint > bpps.mainMenu.breakpoint,
|
|
505
509
|
'bar-menu': this.breakpoint <= bpps.mainMenu.breakpoint,
|
|
506
510
|
'nano-global-nav': true,
|
|
507
|
-
} }, h("div", { key: '
|
|
511
|
+
} }, h("div", { key: '7fe0cb9446b86233ed7727fdc9aade6b94cb72eb', class: {
|
|
508
512
|
gn: true,
|
|
509
513
|
'gn__search-open': this.searchBarShown,
|
|
510
|
-
} }, h("nano-drawer", { key: '
|
|
514
|
+
} }, h("nano-drawer", { key: 'ef476cfee137ebbee63c2f7a99935d4aafd2f7e4', ref: (el) => (this.overflowMenu = el), label: "Main menu", part: "drawer", class: "gn__drawer nano-theme-dark", placement: "start", open: this.overflowOpen, onNanoAfterHide: () => (this.overflowOpen = false), onNanoAfterShow: () => (this.overflowOpen = true) }, h("div", { key: 'c4cbe27955caffeb4f4a7dc755b6b08bf40a7f48', class: "gn__drawer-header", part: "overflow-header", slot: "label" }, "Main menu"), h("nav", { key: '26ec816c93427ce9f9cc4025e327b5e6cf9ba3e2', class: "gn__drawer-menu", part: "overflow-menu" }, this.breakpoint > bpps.mainMenu.breakpoint
|
|
511
515
|
? bpps.mainMenu.tpl()
|
|
512
|
-
: '', h("slot", { key: '
|
|
516
|
+
: '', h("slot", { key: '0693a9f4afdf63e63151b3f3fd4d3a0bbedde4ef', name: "overflow" }))), h("div", { key: 'd9ff383fb0f91876a533e8eb98bc47817b044729', class: "gn__menu-bar-wrapper" }, h("div", { key: '4536fd7593626672f20191b197a55b3d7b10b633', class: "gn__menu-bar", part: "menu-bar", ref: (el) => (this.mainMenuBar = el) }, h("nav", { key: 'ad22eb106a5d9c0ffd8eac8e5e995833f8adcd7e', "aria-label": "Global navigation", class: `gn__main-menu ${this.shouldResize ? 'resizing' : ''}`, part: "main-menu", ref: (el) => (this.mainMenu = el) }, this.breakpoint > bpps.mainMenu.breakpoint && (h("nano-icon-button", { key: 'c399d0e0c2a909a94a0b93ad00ebc5cb34e8c224', class: "gn__overflow-button", iconName: "light/bars", label: "Open Menu", onClick: () => this.overflowMenu.show() })), h("slot", { key: 'ee03de047e3937687e722a88e34356ffc151a9e9', name: "logo" }, h("a", { key: 'a39aad67426cdc5ce75fa334a303229bfab9e58c', href: this.logoUrl, class: "gn__logo-link", part: "logo-link" }, this.breakpoint <= bpps.logo.breakpoint ? (h("img", { src: getAssetPath('../nano-assets/ont-logo.svg'), alt: `Oxford Nanopore Technologies logo. Features a stylised representation of a nanopore,
|
|
513
517
|
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--large", width: "152", height: "36", part: "logo logo--large" })) : (h("img", { src: getAssetPath('../nano-assets/ont-wheel.svg'), alt: `Oxford Nanopore Technologies logo. A stylised representation of a nanopore,
|
|
514
|
-
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--small", width: "36", height: "36", part: "logo logo--small" })))), this.breakpoint <= bpps.mainMenu.breakpoint && (h("div", { key: '
|
|
515
|
-
(!!this.searchIndices.length && (h("nano-dropdown", { key: '
|
|
518
|
+
(a tiny protein channel embedded in a membrane) through which DNA or RNA molecules are passed in for sequencing.`, class: "gn__logo gn__logo--small", width: "36", height: "36", part: "logo logo--small" })))), this.breakpoint <= bpps.mainMenu.breakpoint && (h("div", { key: '46a926ede075e0bfde746fa174c0700a48bc308e', class: "gn__main-menu-links" }, bpps.mainMenu.tpl())), h("div", { key: 'e473ba724a01a0f596f6494b7bb452eef0c4ba53', class: "gn__main-menu-actions" }, !this.myAccountData ||
|
|
519
|
+
(!!this.searchIndices.length && (h("nano-dropdown", { key: '90fa8c9cc0566374afce5f8c722aa98176372d7d', dialogTitle: "Search Oxford Nanopore Technologies", placement: "bottom", class: "gn__search-dropdown", skidding: -30, distance: 25, open: this.searchBarShown, onNanoAfterShow: this.handleSearchOpenEvent, onNanoAfterHide: this.handleSearchCloseEvent, autoOpen: !!this.searchIndices.length }, h("nano-icon-button", { key: '73c7c855dd6baf3259429d55c9bf3d58c2e8ec03', class: "gn__search-button", slot: "trigger", iconName: "light/magnifying-glass", label: "Search" }), h("form", { key: 'f265a2ba3269f22c2efcbe73c7ffe4328fe9d0e8', ref: (form) => (this.searchForm = form), class: "gn__search-form", part: "search-form", onSubmit: this.onSearchSubmit }, this.searchIndices.length > 1 && (h("nano-select", { key: '498ea9e7b0dd5bb10dd92b2df0fccc76295b1042', part: "search-select", label: "Which site do you wish to search in?", mask: true, hideLabel: true, value: this.activeIndex?.index, onNanoChange: this.handleSearchIndexChangeEvent }, this.searchIndices.map((index) => (h("nano-option", { selected: index.name === this.searchIndex, value: index.index }, index.name || index.index))))), h("nano-input", { key: '78baa1860b433e8ee36cd6f2d34d026a7c1e8b21', ref: (ele) => (this.searchInput = ele), part: "search-input", label: "Search Oxford Nanopore Technologies", placeholder: "Search Oxford Nanopore...", hideLabel: true, clearable: true, showInlineError: false, onNanoChange: (e) => {
|
|
516
520
|
this.handleSearchTermChangeEvent(e.detail.value);
|
|
517
|
-
}, onNanoInput: this.handleSearchTermInputEvent, debounce: 500, value: this._searchValue }, h("nano-icon", { key: '
|
|
521
|
+
}, onNanoInput: this.handleSearchTermInputEvent, debounce: 500, value: this._searchValue }, h("nano-icon", { key: 'f3b612bba31b0b1a930b170711080bce93324322', slot: "end", name: "light/magnifying-glass" }), h("nano-datalist", { key: 'a264479248b83b20cb42155e09c3033356a221b4', class: "gn__search-results", onNanoSelect: (e) => e.preventDefault(), dropDownConfig: { tetherTo: this.searchForm }, disableFilter: true }, this.searchLoading && (h("div", { key: '21d365a6554c31144d57900ec8cf50e6caa105b2', slot: "no-result", class: "gn__search-loading" }, h("nano-spinner", { key: 'b4f28c952fcfe765dea3ab7e4c0691e10de1317e' }, "Searching..."))), this.noResultPartial(), !!this.autocompleteResults?.hits.length && [
|
|
518
522
|
this.autocompleteResults.hits.map((hit, i) => (h("nano-option", { href: hit.url, class: "gn__search-result", onClick: () => {
|
|
519
523
|
searchInsight.sendClick({
|
|
520
524
|
index: this.activeIndex.index,
|
|
@@ -524,10 +528,10 @@ export class GlobalNav {
|
|
|
524
528
|
positions: [i + 1],
|
|
525
529
|
});
|
|
526
530
|
} }, h("span", { innerHTML: this.autocompleteSnippet(hit) })))),
|
|
527
|
-
h("nano-option", { key: '
|
|
528
|
-
])))))), h("div", { key: '
|
|
531
|
+
h("nano-option", { key: 'b2a1dc7ff83c80599377850136d6233fa64cee3c', class: "gn__search-viewall", onNanoSelect: this.onSearchSubmit }, "View all results"),
|
|
532
|
+
])))))), h("div", { key: '38bc65edb00ef4876340fdfc1f308a6805a1e1ec', class: "gn__cart" }, h("nano-icon-button", { key: 'b590faedc935181b9230c82509360ddc2a19f1cf', iconName: "light/cart-shopping", label: "View your cart", href: this.cartUrl }), !!this.cartCount && (h("nano-badge", { key: 'c7f45eea27607c6d4380ccdf3a7f2cacfd26bc80', theme: "danger", strength: "2" }, this.cartCount > 9 ? '9+' : this.cartCount))), this.breakpoint <= bpps.contact.breakpoint
|
|
529
533
|
? bpps.contact.tpl()
|
|
530
|
-
: '', this.isLoggedIn ? (h("nano-dropdown", { dialogTitle: "User menu", class: "gn__user-dropdown", distance: 10, placement: "bottom-end" }, h("button", { slot: "trigger", class: "gn__user-dropdown-trigger" }, h("nano-icon", { name: "light/user" }), h("nano-icon", { name: "light/chevron-down", class: "gn__user-dropdown-chevron" }), !!this.msgCount && (h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount > 9 ? '9+' : this.msgCount))), this.loggedInPanel())) : (h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, h("a", { href: this.formatLoginLink(this.loginUrl) }, "Login"))))))), h("nano-global-search-results", { key: '
|
|
534
|
+
: '', this.isLoggedIn ? (h("nano-dropdown", { dialogTitle: "User menu", class: "gn__user-dropdown", distance: 10, placement: "bottom-end" }, h("button", { slot: "trigger", class: "gn__user-dropdown-trigger" }, h("nano-icon", { name: "light/user" }), h("nano-icon", { name: "light/chevron-down", class: "gn__user-dropdown-chevron" }), !!this.msgCount && (h("nano-badge", { theme: "danger", strength: "2" }, this.msgCount > 9 ? '9+' : this.msgCount))), this.loggedInPanel())) : (h("nano-cta", { secondary: true, size: "small", icon: "false", class: "gn__login-cta" }, h("a", { href: this.formatLoginLink(this.loginUrl) }, "Login"))))))), h("nano-global-search-results", { key: '6443d9f0199f87ba5ca73b62b6c3c9e5700731b4', part: "site-search-results" }, h("div", { key: 'db0ce2d9157f7144b0c50d0833386ed4eeabdd02', class: "gn__site", part: "site-wrapper" }, h("slot", { key: 'a9ac7197c149153532f16f8f0f428b5e46d11b72' }))))));
|
|
531
535
|
}
|
|
532
536
|
static get is() { return "nano-global-nav"; }
|
|
533
537
|
static get encapsulation() { return "shadow"; }
|
|
@@ -677,7 +681,7 @@ export class GlobalNav {
|
|
|
677
681
|
"optional": false,
|
|
678
682
|
"docs": {
|
|
679
683
|
"tags": [],
|
|
680
|
-
"text": "A url to take the user after login
|
|
684
|
+
"text": "A url to take the user after login or logout. Defaults to current URL. Is automatically URI encoded"
|
|
681
685
|
},
|
|
682
686
|
"getter": true,
|
|
683
687
|
"setter": true,
|