@sumaris-net/ngx-components 18.10.29 → 18.11.0
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/esm2022/src/app/core/services/model/entity.model.mjs +65 -1
- package/esm2022/src/app/shared/dates.mjs +2 -2
- package/esm2022/src/app/shared/inputs.mjs +14 -10
- package/fesm2022/sumaris-net.ngx-components.mjs +76 -9
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app/core/services/model/entity.model.d.ts +23 -0
- package/src/app/shared/dates.d.ts +1 -1
- package/src/app/shared/inputs.d.ts +3 -2
- package/src/assets/manifest.json +1 -1
|
@@ -1250,7 +1250,7 @@ class DateUtils {
|
|
|
1250
1250
|
static isAtDay(date, weekday, timezone) {
|
|
1251
1251
|
let momentDate = date && fromDateISOString(date);
|
|
1252
1252
|
if (!momentDate)
|
|
1253
|
-
return
|
|
1253
|
+
return false;
|
|
1254
1254
|
if (timezone)
|
|
1255
1255
|
momentDate = momentDate.clone().tz(timezone).startOf('day');
|
|
1256
1256
|
return momentDate.day() === weekday;
|
|
@@ -1481,8 +1481,7 @@ function moveInputCaretToSeparator(event, separator, forward) {
|
|
|
1481
1481
|
// DEBUG
|
|
1482
1482
|
//console.debug("Input text value: ", value);
|
|
1483
1483
|
//console.debug("Cursor at: ", caretPosition);
|
|
1484
|
-
//console.debug("Text after cursor: ", value.
|
|
1485
|
-
//console.debug("Next separator at: ", value.indexOf(separator, caretPosition));
|
|
1484
|
+
//console.debug("Text after cursor: ", value.substring(caretPosition));
|
|
1486
1485
|
forward = forward !== false;
|
|
1487
1486
|
const separatorIndex = forward ? value.indexOf(separator, caretPosition) : value.lastIndexOf(separator, caretPosition);
|
|
1488
1487
|
if (separatorIndex !== -1 && ((forward && separatorIndex + 1 < value.length) || (!forward && separatorIndex > 0))) {
|
|
@@ -1517,7 +1516,7 @@ function filterNumberInput(event, allowDecimals, decimalSeparator) {
|
|
|
1517
1516
|
}
|
|
1518
1517
|
else {
|
|
1519
1518
|
//input command entered of delete, backspace or one of the 4 direction up, down, left and right, or negative sign
|
|
1520
|
-
if ((event.keyCode >= 37 && event.keyCode <= 40) || event.keyCode
|
|
1519
|
+
if ((event.keyCode >= 37 && event.keyCode <= 40) || event.keyCode === 46 || event.which === 8 || event.keyCode === 9 || event.keyCode === 45) {
|
|
1521
1520
|
//console.debug('input command entered :' + event.which + ' ' + event.keyCode + ' ' + event.charCode);
|
|
1522
1521
|
// OK
|
|
1523
1522
|
}
|
|
@@ -1571,19 +1570,24 @@ function tabindexComparator(a, b) {
|
|
|
1571
1570
|
function canHaveFocus(input, opts) {
|
|
1572
1571
|
if (!input)
|
|
1573
1572
|
return false;
|
|
1573
|
+
if (opts?.isEmpty && opts.isNotEmpty)
|
|
1574
|
+
throw new Error('Cannot use both options onlyEmptyInput and onlyNotEmptyInput at the same time. Please use only one of them.');
|
|
1575
|
+
return (
|
|
1574
1576
|
// Exclude disabled element
|
|
1575
|
-
|
|
1577
|
+
!toBoolean(input.disabled, false) &&
|
|
1576
1578
|
// Exclude hidden element
|
|
1577
1579
|
!toBoolean(input.hidden, false) &&
|
|
1578
1580
|
// Exclude minTabIndex < element.tabIndex
|
|
1579
|
-
(isNil(opts
|
|
1581
|
+
(isNil(opts?.minTabindex) || toNumber(input.tabIndex, input.tabindex) > opts.minTabindex) &&
|
|
1580
1582
|
// Exclude maxTabIndex > element.tabIndex
|
|
1581
|
-
(isNil(opts
|
|
1583
|
+
(isNil(opts?.maxTabindex) || toNumber(input.tabIndex, input.tabindex) < opts.maxTabindex) &&
|
|
1584
|
+
// Exclude not nil input value
|
|
1585
|
+
(!opts?.isEmpty || isNilOrBlank(input.value)) &&
|
|
1582
1586
|
// Exclude nil input value
|
|
1583
|
-
(!opts
|
|
1587
|
+
(!opts?.isNotEmpty || isNotNilOrBlank(input.value)));
|
|
1584
1588
|
}
|
|
1585
1589
|
function getFocusableInputElements(elements, opts) {
|
|
1586
|
-
opts = { sortByTabIndex: false,
|
|
1590
|
+
opts = { sortByTabIndex: false, ...opts };
|
|
1587
1591
|
// Focus to first input
|
|
1588
1592
|
const filteredElements = elements
|
|
1589
1593
|
// Transform to input
|
|
@@ -8113,6 +8117,69 @@ class EntityUtils {
|
|
|
8113
8117
|
}
|
|
8114
8118
|
return target;
|
|
8115
8119
|
}
|
|
8120
|
+
/**
|
|
8121
|
+
* Recursively converts any object, entity, or array to a plain JavaScript object.
|
|
8122
|
+
* This method handles entities by calling their asObject() method, processes arrays recursively,
|
|
8123
|
+
* and provides protection against circular references.
|
|
8124
|
+
*
|
|
8125
|
+
* @param {any} source - The source object, entity, array, or primitive value to convert
|
|
8126
|
+
* @param {any} [opts] - Optional configuration object passed to entity asObject() methods
|
|
8127
|
+
* @param {WeakSet} [visited=new WeakSet()] - Internal parameter for circular reference detection
|
|
8128
|
+
* @returns {any} A plain JavaScript object representation of the source
|
|
8129
|
+
*
|
|
8130
|
+
* @example
|
|
8131
|
+
* // Convert a simple entity
|
|
8132
|
+
* const plainObject = EntityUtils.asObject(myEntity);
|
|
8133
|
+
*
|
|
8134
|
+
* @example
|
|
8135
|
+
* // Convert an array of entities
|
|
8136
|
+
* const plainArray = EntityUtils.asObject([entity1, entity2]);
|
|
8137
|
+
*
|
|
8138
|
+
* @example
|
|
8139
|
+
* // Convert with options
|
|
8140
|
+
* const result = EntityUtils.asObject(myEntity, { minify: true });
|
|
8141
|
+
*/
|
|
8142
|
+
static asObject(source, opts, visited = new WeakSet()) {
|
|
8143
|
+
if (!source)
|
|
8144
|
+
return source;
|
|
8145
|
+
if (Array.isArray(source))
|
|
8146
|
+
return source.map((item) => EntityUtils.asObject(item, opts, visited));
|
|
8147
|
+
if (EntityUtils.isEntity(source))
|
|
8148
|
+
return source.asObject(opts);
|
|
8149
|
+
if (typeof source === 'function')
|
|
8150
|
+
return undefined;
|
|
8151
|
+
if (typeof source !== 'object')
|
|
8152
|
+
return source;
|
|
8153
|
+
// Protection against circular references
|
|
8154
|
+
if (visited.has(source)) {
|
|
8155
|
+
console.warn('[EntityUtils.asObject] Circular reference detected, skipping object');
|
|
8156
|
+
return {}; // or return null based on your needs
|
|
8157
|
+
}
|
|
8158
|
+
visited.add(source);
|
|
8159
|
+
// Handle special objects
|
|
8160
|
+
if (isMoment(source) || typeof source.toISOString === 'function')
|
|
8161
|
+
return source.toISOString();
|
|
8162
|
+
if (source instanceof RegExp)
|
|
8163
|
+
return source.toString();
|
|
8164
|
+
// Create a copy
|
|
8165
|
+
const target = { ...source };
|
|
8166
|
+
// Serialize all properties recursively
|
|
8167
|
+
Object.keys(target).forEach((key) => {
|
|
8168
|
+
const value = target[key];
|
|
8169
|
+
// Handle arrays
|
|
8170
|
+
if (Array.isArray(value)) {
|
|
8171
|
+
target[key] = value.map((item) => EntityUtils.asObject(item, opts, visited));
|
|
8172
|
+
}
|
|
8173
|
+
// Handle objects (including entities)
|
|
8174
|
+
else if (value && typeof value === 'object') {
|
|
8175
|
+
target[key] = EntityUtils.asObject(value, opts, visited);
|
|
8176
|
+
}
|
|
8177
|
+
// Primitive values are already copied by spread operator
|
|
8178
|
+
});
|
|
8179
|
+
// Remove object from Set after processing
|
|
8180
|
+
visited.delete(source);
|
|
8181
|
+
return target;
|
|
8182
|
+
}
|
|
8116
8183
|
}
|
|
8117
8184
|
|
|
8118
8185
|
function suggestFromArray(items, value, filter, sortBy, sortDirection, opts) {
|