@logimaxx/kviews.js 1.2.3 → 1.3.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/CHANGELOG.md +10 -0
- package/README.md +2 -2
- package/dist/index.js +243 -33
- package/dist/index.js.map +2 -2
- package/dist/kviews.js +245 -35
- package/dist/kviews.js.map +2 -2
- package/dist/kviews.min.js +6 -6
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`showLoader`** option on `Item` and `Collection` — set to `false` to skip the loading overlay during `loadFromRemote()` (default: `true`).
|
|
13
|
+
|
|
10
14
|
### Changed
|
|
11
15
|
|
|
16
|
+
- **`Item.loadFromRemote()`** — on an already loaded item, views re-render only when fetched data differs from the current state; the `load` event still fires when the request completes.
|
|
17
|
+
- **`Item.loadFromRemoteDoc()`** — skips updating internal fields when parsed data equals the current item state.
|
|
12
18
|
- npm package name is **`@logimaxx/kviews.js`** (renamed from `@logimaxx/kviews`). Install with `npm install @logimaxx/kviews.js`.
|
|
13
19
|
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **`Item.perform_update()`** — failed PATCH requests now reject with the original storage/HTTP error instead of masking it with `ReferenceError: patchData is not defined`.
|
|
23
|
+
|
|
14
24
|
## [1.2.1]
|
|
15
25
|
|
|
16
26
|
### Changed
|
package/README.md
CHANGED
|
@@ -222,7 +222,7 @@ With jQuery, `$.fn.kviews.baseUrl`, `basePath`, and `defaultHeaders` mirror the
|
|
|
222
222
|
|
|
223
223
|
### Collection
|
|
224
224
|
|
|
225
|
-
- `loadFromRemote()` - Load data from API
|
|
225
|
+
- `loadFromRemote()` - Load data from API (optional loading overlay via `showLoader`, default `true`)
|
|
226
226
|
- `append(itemData)` - Add new item
|
|
227
227
|
- `render()` - Render collection
|
|
228
228
|
- `on(event, callback)` - Event listeners
|
|
@@ -230,7 +230,7 @@ With jQuery, `$.fn.kviews.baseUrl`, `basePath`, and `defaultHeaders` mirror the
|
|
|
230
230
|
|
|
231
231
|
### Item
|
|
232
232
|
|
|
233
|
-
- `loadFromRemote()` - Load item from API
|
|
233
|
+
- `loadFromRemote()` - Load item from API (re-renders only when data changed; optional overlay via `showLoader`)
|
|
234
234
|
- `update(data)` - Update item
|
|
235
235
|
- `delete()` - Delete item
|
|
236
236
|
- `render()` - Render item
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,36 @@ function parseOptions(options) {
|
|
|
31
31
|
}
|
|
32
32
|
throw new Error("Invalid options", options);
|
|
33
33
|
}
|
|
34
|
+
function deepEqual(a, b) {
|
|
35
|
+
if (a === b) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
if (a === null || b === null || typeof a !== "object" || typeof b !== "object") {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
42
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
for (let i = 0; i < a.length; i++) {
|
|
46
|
+
if (!deepEqual(a[i], b[i])) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const keysA = Object.keys(a);
|
|
53
|
+
const keysB = Object.keys(b);
|
|
54
|
+
if (keysA.length !== keysB.length) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
for (const key of keysA) {
|
|
58
|
+
if (!Object.prototype.hasOwnProperty.call(b, key) || !deepEqual(a[key], b[key])) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
34
64
|
function deepmerge(target, source, optionsArgument) {
|
|
35
65
|
function defaultArrayMerge(target2, source2, optionsArgument2) {
|
|
36
66
|
let destination = target2.slice();
|
|
@@ -848,6 +878,29 @@ var JsonApiAdapter = class {
|
|
|
848
878
|
url.parameters[`page[${type}][limit]`] = pageSize;
|
|
849
879
|
}
|
|
850
880
|
}
|
|
881
|
+
/**
|
|
882
|
+
* Read pagination params already present in a collection URL.
|
|
883
|
+
*
|
|
884
|
+
* @param {import('../URL.js').URL} url - Collection URL
|
|
885
|
+
* @param {{ type?: string }} [context]
|
|
886
|
+
* @returns {{ offset?: number, pageSize?: number }}
|
|
887
|
+
*/
|
|
888
|
+
extractListQueryFromUrl(url, context = {}) {
|
|
889
|
+
const { type } = context;
|
|
890
|
+
const result = {};
|
|
891
|
+
if (!url || !url.parameters || !type) {
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
const limitKey = `page[${type}][limit]`;
|
|
895
|
+
const offsetKey = `page[${type}][offset]`;
|
|
896
|
+
if (url.parameters.hasOwnProperty(limitKey)) {
|
|
897
|
+
result.pageSize = url.parameters[limitKey];
|
|
898
|
+
}
|
|
899
|
+
if (url.parameters.hasOwnProperty(offsetKey)) {
|
|
900
|
+
result.offset = url.parameters[offsetKey];
|
|
901
|
+
}
|
|
902
|
+
return result;
|
|
903
|
+
}
|
|
851
904
|
/**
|
|
852
905
|
* Serialize plain item data for a create (POST) request.
|
|
853
906
|
*
|
|
@@ -1162,6 +1215,32 @@ var PlainRestAdapter = class {
|
|
|
1162
1215
|
}
|
|
1163
1216
|
url.parameters[this.limitParam] = pageSize;
|
|
1164
1217
|
}
|
|
1218
|
+
/**
|
|
1219
|
+
* @param {import('../URL.js').URL} url
|
|
1220
|
+
* @param {object} [context]
|
|
1221
|
+
* @returns {{ offset?: number, pageSize?: number }}
|
|
1222
|
+
*/
|
|
1223
|
+
extractListQueryFromUrl(url) {
|
|
1224
|
+
const result = {};
|
|
1225
|
+
if (!url || !url.parameters) {
|
|
1226
|
+
return result;
|
|
1227
|
+
}
|
|
1228
|
+
if (url.parameters.hasOwnProperty(this.limitParam)) {
|
|
1229
|
+
result.pageSize = url.parameters[this.limitParam];
|
|
1230
|
+
} else if (url.parameters.hasOwnProperty("pageSize")) {
|
|
1231
|
+
result.pageSize = url.parameters.pageSize;
|
|
1232
|
+
}
|
|
1233
|
+
if (this.paginationStyle === "page" && url.parameters.hasOwnProperty(this.pageParam)) {
|
|
1234
|
+
const page = url.parameters[this.pageParam] * 1;
|
|
1235
|
+
const pageSize = result.pageSize != null ? result.pageSize * 1 : null;
|
|
1236
|
+
if (pageSize) {
|
|
1237
|
+
result.offset = (page - 1) * pageSize;
|
|
1238
|
+
}
|
|
1239
|
+
} else if (url.parameters.hasOwnProperty(this.offsetParam)) {
|
|
1240
|
+
result.offset = url.parameters[this.offsetParam];
|
|
1241
|
+
}
|
|
1242
|
+
return result;
|
|
1243
|
+
}
|
|
1165
1244
|
/**
|
|
1166
1245
|
* @param {object|Array} itemData
|
|
1167
1246
|
* @param {object} [context]
|
|
@@ -1824,17 +1903,26 @@ var Item = class _Item {
|
|
|
1824
1903
|
*/
|
|
1825
1904
|
loadFromDataSource() {
|
|
1826
1905
|
let loaders = [];
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1906
|
+
const showLoader = this.showLoader !== false;
|
|
1907
|
+
if (showLoader) {
|
|
1908
|
+
const overlay = createOverlay(this);
|
|
1909
|
+
this.views.forEach((itemView) => {
|
|
1910
|
+
if (itemView.el) {
|
|
1911
|
+
let $el = $(itemView.el);
|
|
1912
|
+
let loader = overlay.clone();
|
|
1913
|
+
loader.insertBefore(itemView.el).width($el.width()).height($el.height());
|
|
1914
|
+
loaders.push(loader);
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
const removeLoaders = () => {
|
|
1919
|
+
loaders.forEach((loader) => {
|
|
1920
|
+
loader.remove();
|
|
1921
|
+
});
|
|
1922
|
+
};
|
|
1836
1923
|
return new Promise((resolve, reject) => {
|
|
1837
1924
|
if (!this.url) {
|
|
1925
|
+
removeLoaders();
|
|
1838
1926
|
reject(new Error("No valid URL provided"));
|
|
1839
1927
|
return;
|
|
1840
1928
|
}
|
|
@@ -1842,13 +1930,16 @@ var Item = class _Item {
|
|
|
1842
1930
|
let urlString = this.url.toString ? this.url.toString() : this.url;
|
|
1843
1931
|
this.storage.read(this, urlString, {}).then((resp) => {
|
|
1844
1932
|
let data = resp.data;
|
|
1845
|
-
this.
|
|
1933
|
+
const parsedData = this._parseRemoteDoc(data);
|
|
1934
|
+
if (!this._remoteDataEquals(parsedData)) {
|
|
1935
|
+
this._applyParsedRemoteData(parsedData);
|
|
1936
|
+
this.render();
|
|
1937
|
+
}
|
|
1846
1938
|
this._trigger("load", this);
|
|
1847
|
-
|
|
1848
|
-
loader.remove();
|
|
1849
|
-
});
|
|
1939
|
+
removeLoaders();
|
|
1850
1940
|
resolve(this);
|
|
1851
1941
|
}).catch((error2) => {
|
|
1942
|
+
removeLoaders();
|
|
1852
1943
|
dbg("fail to load item resource", this.url, error2);
|
|
1853
1944
|
if (error2 instanceof Error && error2.jqXHR) {
|
|
1854
1945
|
this.fail(error2.jqXHR, error2.textStatus || "error", error2.errorThrown || error2);
|
|
@@ -1925,13 +2016,12 @@ var Item = class _Item {
|
|
|
1925
2016
|
return returnView ? view : this;
|
|
1926
2017
|
}
|
|
1927
2018
|
/**
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
2019
|
+
* Parse a remote API document into canonical item data.
|
|
1930
2020
|
* @param {object} data - Raw HTTP response body
|
|
1931
|
-
* @returns {
|
|
2021
|
+
* @returns {object} Parsed resource data
|
|
2022
|
+
* @private
|
|
1932
2023
|
*/
|
|
1933
|
-
|
|
1934
|
-
dbg("Load from remote doc", data);
|
|
2024
|
+
_parseRemoteDoc(data) {
|
|
1935
2025
|
if (this.collection && !this.collection.type) {
|
|
1936
2026
|
const inferredType = this.adapter.inferItemType(data);
|
|
1937
2027
|
if (inferredType) {
|
|
@@ -1939,11 +2029,97 @@ var Item = class _Item {
|
|
|
1939
2029
|
}
|
|
1940
2030
|
}
|
|
1941
2031
|
this.adapter.validateItemRemoteDoc(data, { collection: this.collection });
|
|
1942
|
-
|
|
2032
|
+
return this.adapter.parseItemResponse(data, { collection: this.collection });
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Apply parsed remote data to this item.
|
|
2036
|
+
* @param {object} parsedData
|
|
2037
|
+
* @private
|
|
2038
|
+
*/
|
|
2039
|
+
_applyParsedRemoteData(parsedData) {
|
|
1943
2040
|
Object.assign(this, parsedData);
|
|
1944
2041
|
if (this.url) {
|
|
1945
2042
|
this.url = createURL(this.url);
|
|
1946
2043
|
}
|
|
2044
|
+
}
|
|
2045
|
+
/**
|
|
2046
|
+
* Compare current item state with parsed remote data.
|
|
2047
|
+
* @param {object} parsedData
|
|
2048
|
+
* @returns {boolean}
|
|
2049
|
+
* @private
|
|
2050
|
+
*/
|
|
2051
|
+
_remoteDataEquals(parsedData) {
|
|
2052
|
+
if (this.id == null && (!this.attributes || Object.keys(this.attributes).length === 0)) {
|
|
2053
|
+
return false;
|
|
2054
|
+
}
|
|
2055
|
+
if (String(this.id ?? "") !== String(parsedData.id ?? "")) {
|
|
2056
|
+
return false;
|
|
2057
|
+
}
|
|
2058
|
+
if ((this.type ?? null) !== (parsedData.type ?? null)) {
|
|
2059
|
+
return false;
|
|
2060
|
+
}
|
|
2061
|
+
if (!deepEqual(this.attributes ?? {}, parsedData.attributes ?? {})) {
|
|
2062
|
+
return false;
|
|
2063
|
+
}
|
|
2064
|
+
return deepEqual(
|
|
2065
|
+
this._normalizeRelationshipsForCompare(this.relationships),
|
|
2066
|
+
this._normalizeRelationshipsForCompare(parsedData.relationships)
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Normalize relationships to plain comparable objects.
|
|
2071
|
+
* @param {object} relationships
|
|
2072
|
+
* @returns {object}
|
|
2073
|
+
* @private
|
|
2074
|
+
*/
|
|
2075
|
+
_normalizeRelationshipsForCompare(relationships) {
|
|
2076
|
+
if (!relationships || typeof relationships !== "object") {
|
|
2077
|
+
return {};
|
|
2078
|
+
}
|
|
2079
|
+
const normalized = {};
|
|
2080
|
+
Object.keys(relationships).sort().forEach((name) => {
|
|
2081
|
+
normalized[name] = this._normalizeRelationshipValueForCompare(relationships[name]);
|
|
2082
|
+
});
|
|
2083
|
+
return normalized;
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* @param {*} rel
|
|
2087
|
+
* @returns {*}
|
|
2088
|
+
* @private
|
|
2089
|
+
*/
|
|
2090
|
+
_normalizeRelationshipValueForCompare(rel) {
|
|
2091
|
+
if (rel == null) {
|
|
2092
|
+
return null;
|
|
2093
|
+
}
|
|
2094
|
+
if (Array.isArray(rel)) {
|
|
2095
|
+
return rel.map((item) => this._normalizeRelationshipValueForCompare(item));
|
|
2096
|
+
}
|
|
2097
|
+
if (typeof rel !== "object") {
|
|
2098
|
+
return rel;
|
|
2099
|
+
}
|
|
2100
|
+
const normalized = {
|
|
2101
|
+
id: rel.id ?? null,
|
|
2102
|
+
type: rel.type ?? null,
|
|
2103
|
+
attributes: rel.attributes ?? {}
|
|
2104
|
+
};
|
|
2105
|
+
if (rel.relationships) {
|
|
2106
|
+
normalized.relationships = this._normalizeRelationshipsForCompare(rel.relationships);
|
|
2107
|
+
}
|
|
2108
|
+
return normalized;
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Load from a remote API document (format determined by adapter).
|
|
2112
|
+
*
|
|
2113
|
+
* @param {object} data - Raw HTTP response body
|
|
2114
|
+
* @returns {Item} This instance for chaining
|
|
2115
|
+
*/
|
|
2116
|
+
loadFromRemoteDoc(data) {
|
|
2117
|
+
dbg("Load from remote doc", data);
|
|
2118
|
+
const parsedData = this._parseRemoteDoc(data);
|
|
2119
|
+
if (this._remoteDataEquals(parsedData)) {
|
|
2120
|
+
return this;
|
|
2121
|
+
}
|
|
2122
|
+
this._applyParsedRemoteData(parsedData);
|
|
1947
2123
|
return this;
|
|
1948
2124
|
}
|
|
1949
2125
|
/**
|
|
@@ -2263,7 +2439,7 @@ var Item = class _Item {
|
|
|
2263
2439
|
}
|
|
2264
2440
|
resolve(this);
|
|
2265
2441
|
}).catch((error2) => {
|
|
2266
|
-
dbg("Update NOK", this.updateUrl,
|
|
2442
|
+
dbg("Update NOK", this.updateUrl, payload.body, error2);
|
|
2267
2443
|
if (error2 instanceof Error && error2.jqXHR) {
|
|
2268
2444
|
reject(error2);
|
|
2269
2445
|
} else if (error2.jqXHR) {
|
|
@@ -2496,8 +2672,9 @@ var CollectionView = class {
|
|
|
2496
2672
|
}
|
|
2497
2673
|
/**
|
|
2498
2674
|
* Render the collection view
|
|
2675
|
+
* @private
|
|
2499
2676
|
*/
|
|
2500
|
-
|
|
2677
|
+
_render() {
|
|
2501
2678
|
dbg("Render _collectionView", this.collection);
|
|
2502
2679
|
if (this.collection && this.collection.navtype === "page") {
|
|
2503
2680
|
this.reset();
|
|
@@ -2815,6 +2992,10 @@ var Collection = class {
|
|
|
2815
2992
|
configurable: true
|
|
2816
2993
|
});
|
|
2817
2994
|
let options = Object.assign({}, opts);
|
|
2995
|
+
const explicitListQuery = {
|
|
2996
|
+
pageSize: options.hasOwnProperty("pageSize"),
|
|
2997
|
+
offset: options.hasOwnProperty("offset")
|
|
2998
|
+
};
|
|
2818
2999
|
Object.assign(this, options);
|
|
2819
3000
|
if (options.hasOwnProperty("paging") && $(options.paging).length) {
|
|
2820
3001
|
this.paging = new Paging($(options.paging)[0], this);
|
|
@@ -2841,6 +3022,9 @@ var Collection = class {
|
|
|
2841
3022
|
throw new Error("Invalid navigations type. Should be page or scroll");
|
|
2842
3023
|
}
|
|
2843
3024
|
this.adapter = resolveAdapter(opts.adapter);
|
|
3025
|
+
if (this.url) {
|
|
3026
|
+
this._syncListQueryFromUrl(this.url, explicitListQuery);
|
|
3027
|
+
}
|
|
2844
3028
|
this.storage = opts.hasOwnProperty("storage") ? opts.storage : new Storage(
|
|
2845
3029
|
(() => {
|
|
2846
3030
|
const storageOpts = Object.assign({}, opts.ajaxOpts || {});
|
|
@@ -3021,10 +3205,31 @@ var Collection = class {
|
|
|
3021
3205
|
this.deleteUrl = typeof this.deleteUrl == "string" ? createURL(this.deleteUrl) : this.deleteUrl ?? createURL(this.url);
|
|
3022
3206
|
this.updateUrl = typeof this.updateUrl == "string" ? createURL(this.updateUrl) : this.updateUrl ?? createURL(this.url);
|
|
3023
3207
|
this.insertUrl = typeof this.insertUrl == "string" ? createURL(this.insertUrl) : this.insertUrl ?? createURL(this.url);
|
|
3208
|
+
if (this.adapter) {
|
|
3209
|
+
this._syncListQueryFromUrl(this.url);
|
|
3210
|
+
}
|
|
3024
3211
|
break;
|
|
3025
3212
|
}
|
|
3026
3213
|
return this;
|
|
3027
3214
|
}
|
|
3215
|
+
/**
|
|
3216
|
+
* Apply pagination params from URL query string to collection state.
|
|
3217
|
+
* @private
|
|
3218
|
+
* @param {import('./URL.js').URL} url
|
|
3219
|
+
* @param {{ pageSize?: boolean, offset?: boolean }} [explicit] - Options explicitly set at init
|
|
3220
|
+
*/
|
|
3221
|
+
_syncListQueryFromUrl(url, explicit = {}) {
|
|
3222
|
+
if (!url || !this.adapter || typeof this.adapter.extractListQueryFromUrl !== "function") {
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
const fromUrl = this.adapter.extractListQueryFromUrl(url, { type: this.type });
|
|
3226
|
+
if (fromUrl.pageSize != null && !explicit.pageSize) {
|
|
3227
|
+
this.setPageSize(fromUrl.pageSize);
|
|
3228
|
+
}
|
|
3229
|
+
if (fromUrl.offset != null && !explicit.offset) {
|
|
3230
|
+
this.offset = fromUrl.offset * 1;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3028
3233
|
/**
|
|
3029
3234
|
* Receive remote data
|
|
3030
3235
|
*
|
|
@@ -3114,7 +3319,7 @@ var Collection = class {
|
|
|
3114
3319
|
this.loadItem(item);
|
|
3115
3320
|
});
|
|
3116
3321
|
if (this.view) {
|
|
3117
|
-
this.view.
|
|
3322
|
+
this.view._render();
|
|
3118
3323
|
} else {
|
|
3119
3324
|
dbg("collection does not have a view ", this);
|
|
3120
3325
|
}
|
|
@@ -3146,7 +3351,7 @@ var Collection = class {
|
|
|
3146
3351
|
clear() {
|
|
3147
3352
|
this.items = [];
|
|
3148
3353
|
if (this.view) {
|
|
3149
|
-
this.view.
|
|
3354
|
+
this.view._render();
|
|
3150
3355
|
}
|
|
3151
3356
|
this._trigger("update", this);
|
|
3152
3357
|
return this;
|
|
@@ -3156,7 +3361,7 @@ var Collection = class {
|
|
|
3156
3361
|
*/
|
|
3157
3362
|
render() {
|
|
3158
3363
|
if (this.view) {
|
|
3159
|
-
this.view.
|
|
3364
|
+
this.view._render();
|
|
3160
3365
|
}
|
|
3161
3366
|
this._trigger("afterrender", this);
|
|
3162
3367
|
return this;
|
|
@@ -3177,15 +3382,21 @@ var Collection = class {
|
|
|
3177
3382
|
* @private
|
|
3178
3383
|
*/
|
|
3179
3384
|
loadFromDataSource() {
|
|
3180
|
-
const overlay = createOverlay(this);
|
|
3181
3385
|
let loader = null;
|
|
3182
|
-
|
|
3386
|
+
const showLoader = this.showLoader !== false;
|
|
3387
|
+
if (showLoader && this.view && this.view.el) {
|
|
3388
|
+
const overlay = createOverlay(this);
|
|
3183
3389
|
loader = $(overlay).clone().insertBefore(this.view.el).width($(this.view.el).width()).height($(this.view.el).height());
|
|
3184
3390
|
}
|
|
3391
|
+
const removeLoader = () => {
|
|
3392
|
+
if (loader) {
|
|
3393
|
+
$(loader).remove();
|
|
3394
|
+
}
|
|
3395
|
+
};
|
|
3185
3396
|
this._trigger("beforeload", this);
|
|
3186
3397
|
return new Promise((resolve, reject) => {
|
|
3187
3398
|
if (!this.url) {
|
|
3188
|
-
|
|
3399
|
+
removeLoader();
|
|
3189
3400
|
reject(new Error("No valid URL provided"));
|
|
3190
3401
|
return;
|
|
3191
3402
|
}
|
|
@@ -3201,9 +3412,7 @@ var Collection = class {
|
|
|
3201
3412
|
}
|
|
3202
3413
|
this.receiveRemoteData(res.data);
|
|
3203
3414
|
this._trigger("load", this);
|
|
3204
|
-
|
|
3205
|
-
$(loader).remove();
|
|
3206
|
-
}
|
|
3415
|
+
removeLoader();
|
|
3207
3416
|
if (this.paging) {
|
|
3208
3417
|
this.paging.render();
|
|
3209
3418
|
}
|
|
@@ -3211,15 +3420,15 @@ var Collection = class {
|
|
|
3211
3420
|
}).catch((error2) => {
|
|
3212
3421
|
if (error2 instanceof Error && error2.jqXHR) {
|
|
3213
3422
|
this.fail(error2.jqXHR, error2.textStatus || "error", error2.errorThrown || error2);
|
|
3214
|
-
|
|
3423
|
+
removeLoader();
|
|
3215
3424
|
reject(error2);
|
|
3216
3425
|
} else if (error2 && error2.jqXHR) {
|
|
3217
3426
|
this.fail(error2.jqXHR, error2.textStatus, error2.errorThrown);
|
|
3218
|
-
|
|
3427
|
+
removeLoader();
|
|
3219
3428
|
reject(error2);
|
|
3220
3429
|
} else {
|
|
3221
3430
|
this.fail(null, "error", error2);
|
|
3222
|
-
|
|
3431
|
+
removeLoader();
|
|
3223
3432
|
reject(error2);
|
|
3224
3433
|
}
|
|
3225
3434
|
});
|
|
@@ -4021,6 +4230,7 @@ export {
|
|
|
4021
4230
|
createOverlay,
|
|
4022
4231
|
createURL,
|
|
4023
4232
|
dbg,
|
|
4233
|
+
deepEqual,
|
|
4024
4234
|
deepmerge,
|
|
4025
4235
|
index_default as default,
|
|
4026
4236
|
error,
|