@mono-lit/helper 0.0.1 → 0.0.2
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/LICENSE.md +55 -55
- package/README.md +35 -35
- package/dist/data-source-controller-B_rgHCjw.js +241 -0
- package/dist/{data-source-controller-C50Qyfzh.js → data-source-controller-Dbb4fd8I.js} +69 -6
- package/dist/{data-source-options-BTpfrOZ_.js → data-source-options-CP-X62Pa.js} +2 -2
- package/dist/{data-source-options-CQSTZHPE.js → data-source-options-Jqj7LU3Z.js} +1 -1
- package/dist/{data-source-read-CUX-lgrQ.js → data-source-read-B4DGp6UQ.js} +1 -1
- package/dist/{export-BvlBx_GZ.js → export-BiGVyxt6.js} +2 -2
- package/dist/{field-icons-BoOG6KrL.js → field-icons-DELrSdqJ.js} +36 -1
- package/dist/index.js +7 -7
- package/dist/{index.node-DjvYOL-J.js → index.node-BIqEGehH.js} +5 -4
- package/dist/index.node.js +7 -7
- package/dist/{mono-button-CoVnBLav.js → mono-button-simcTQdW.js} +2 -2
- package/dist/{mono-button.shadow-FfP_hMH4.js → mono-button.shadow-B_rKOY9N.js} +2 -2
- package/dist/{mono-data-chart-ChU4Ii3p.js → mono-data-chart-CEv29_NS.js} +53 -12
- package/dist/{mono-data-dropdown-BAUl58kW.js → mono-data-dropdown-Wnoke6zO.js} +1 -1
- package/dist/{mono-data-grid-CLBK8clE.js → mono-data-grid-CjkEqxgE.js} +5 -232
- package/dist/{mono-data-grid-Db80FzdZ.js → mono-data-grid-YjR3n9Ar.js} +3 -230
- package/dist/{data-search-Bwo5bg8K.js → normalize-error-Gcgmgh5i.js} +299 -1
- package/dist/{reactive-BHsqVjRh.js → reactive-Di3mTMnV.js} +299 -1
- package/dist/src/components/card/card-core.d.ts +1 -0
- package/dist/src/components/chart/chart-types.d.ts +19 -0
- package/dist/src/components/select/select-types.d.ts +26 -0
- package/dist/src/components/tag-input/tag-input-types.d.ts +26 -0
- package/dist/src/composables/data-source-controller.d.ts +29 -0
- package/dist/src/composables/field-icons.d.ts +8 -0
- package/dist/src/utils/normalize-error.d.ts +30 -0
- package/dist/{tooltip-CysgRgBi.js → tooltip-DQqNpqk2.js} +62 -27
- package/dist/tooltip.js +1 -1
- package/dist/ui/alert.js +1 -1
- package/dist/ui/button-dropdown.js +1 -1
- package/dist/ui/button.js +1 -1
- package/dist/ui/card.js +15 -2
- package/dist/ui/chart.js +81 -4
- package/dist/ui/dropdown-table.js +2 -2
- package/dist/ui/index.css +181 -18
- package/dist/ui/modal.js +3 -2
- package/dist/ui/select.js +153 -19
- package/dist/ui/shadow/alert.js +1 -1
- package/dist/ui/shadow/button-dropdown.js +1 -1
- package/dist/ui/shadow/button.js +1 -1
- package/dist/ui/shadow/card.js +16 -2
- package/dist/ui/shadow/chart.js +133 -17
- package/dist/ui/shadow/dropdown-table.js +2 -2
- package/dist/ui/shadow/modal.js +3 -2
- package/dist/ui/shadow/select.js +153 -19
- package/dist/ui/shadow/table.js +4 -4
- package/dist/ui/shadow/tag-input.js +154 -26
- package/dist/ui/table.js +3 -3
- package/dist/ui/tag-input.js +153 -25
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as createNotifier } from "./notifier-CE4yxMUQ.js";
|
|
2
2
|
import { a as parseFieldPath, c as toODataClause, l as toODataSelector, n as isPath, o as projectFields, r as mergePatch, s as setFieldValue, t as getFieldValue } from "./field-path-C92eGLg3.js";
|
|
3
|
-
import {
|
|
4
|
-
import { a as buildGroups, c as isGroupNode, i as searchFilterOf, o as collectGroupPaths, r as readAllRows, s as flattenLeaves } from "./data-source-read-
|
|
5
|
-
import { a as resolveDataSourceOptions, c as composeSummaryApply, d as createApplyGate, f as isRolledUp, h as monoArraySource, i as normalizeSortList, l as summaryAliases, m as storeRows, n as extraLoadOptions, o as toList, p as loadApply, s as buildSummaryApply, t as dataSourceOptionsKey, u as summaryFilterOf } from "./data-source-options-
|
|
3
|
+
import { A as compileFilterPredicate, D as searchEntryFor, E as resolveSearchEntries, O as andFilters, S as hasWildcardSearch, T as plainSearchColumns, a as describeError, h as mergeSearchFields, j as joinFilters, k as andPredicates, l as isCanceled, n as unwrapReactive, p as DEFAULT_SEARCH_FIELDS, v as customPredicate, x as hasCustomSearch, y as customRemoteClause } from "./reactive-Di3mTMnV.js";
|
|
4
|
+
import { a as buildGroups, c as isGroupNode, i as searchFilterOf, o as collectGroupPaths, r as readAllRows, s as flattenLeaves } from "./data-source-read-B4DGp6UQ.js";
|
|
5
|
+
import { a as resolveDataSourceOptions, c as composeSummaryApply, d as createApplyGate, f as isRolledUp, h as monoArraySource, i as normalizeSortList, l as summaryAliases, m as storeRows, n as extraLoadOptions, o as toList, p as loadApply, s as buildSummaryApply, t as dataSourceOptionsKey, u as summaryFilterOf } from "./data-source-options-CP-X62Pa.js";
|
|
6
6
|
import { t as arrayToODataString } from "./filter-odata-C1vSGZaY.js";
|
|
7
7
|
import { t as monoFilterBuilder } from "./filter-builder-CE4zE0V5.js";
|
|
8
8
|
//#region src/components/table/date-filter-tree.ts
|
|
@@ -294,229 +294,6 @@ function inRange(d, r) {
|
|
|
294
294
|
return t >= r.from.getTime() && t < r.to.getTime();
|
|
295
295
|
}
|
|
296
296
|
//#endregion
|
|
297
|
-
//#region src/utils/normalize-error.ts
|
|
298
|
-
/** Fields worth reading off an object that is not an `Error`. */
|
|
299
|
-
var MESSAGE_KEYS = [
|
|
300
|
-
"message",
|
|
301
|
-
"statusText",
|
|
302
|
-
"errorMessage",
|
|
303
|
-
"error",
|
|
304
|
-
"detail"
|
|
305
|
-
];
|
|
306
|
-
var text = (value) => typeof value === "string" && value.trim() ? value.trim() : "";
|
|
307
|
-
var isObject = (value) => value !== null && typeof value === "object";
|
|
308
|
-
/**
|
|
309
|
-
* A readable message for `raw`, or `fallback` when nothing legible can be found.
|
|
310
|
-
*
|
|
311
|
-
* Never throws, and never returns an empty string — a caller rendering this into
|
|
312
|
-
* an error bar has to have something to render, and a blank bar is worse than a
|
|
313
|
-
* generic one.
|
|
314
|
-
*/
|
|
315
|
-
function normalizeError(raw, fallback = "Request failed") {
|
|
316
|
-
if (raw == null) return fallback;
|
|
317
|
-
if (raw instanceof Error) {
|
|
318
|
-
const own = text(raw.message);
|
|
319
|
-
if (own) return own;
|
|
320
|
-
} else {
|
|
321
|
-
if (typeof raw === "string") return text(raw) || fallback;
|
|
322
|
-
if (typeof raw === "number" || typeof raw === "boolean") return String(raw);
|
|
323
|
-
}
|
|
324
|
-
if (isObject(raw)) {
|
|
325
|
-
const obj = raw;
|
|
326
|
-
for (const key of MESSAGE_KEYS) {
|
|
327
|
-
const hit = text(obj[key]);
|
|
328
|
-
if (hit) return hit;
|
|
329
|
-
}
|
|
330
|
-
const response = obj.response;
|
|
331
|
-
if (isObject(response)) {
|
|
332
|
-
const nested = text(response.statusText) || text(response.message);
|
|
333
|
-
if (nested) return nested;
|
|
334
|
-
}
|
|
335
|
-
const status = errorStatus(obj);
|
|
336
|
-
if (status !== void 0 && status > 0) return `HTTP ${status}`;
|
|
337
|
-
if (raw instanceof Error) return text(raw.name) || fallback;
|
|
338
|
-
return fallback;
|
|
339
|
-
}
|
|
340
|
-
return text(String(raw)) || fallback;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* What the bar says for a status. English; an app puts its own language in
|
|
344
|
-
* ONCE with `setErrorMessages()` rather than on every table.
|
|
345
|
-
*/
|
|
346
|
-
var DEFAULT_ERROR_MESSAGES = Object.freeze({
|
|
347
|
-
network: "Could not reach the server. Check your connection and try again.",
|
|
348
|
-
400: "The server rejected the request.",
|
|
349
|
-
401: "Your session has expired. Please sign in again.",
|
|
350
|
-
403: "You do not have permission to view this data.",
|
|
351
|
-
404: "The requested data could not be found.",
|
|
352
|
-
408: "The server took too long to respond. Please try again.",
|
|
353
|
-
409: "The request conflicts with the current state of the data.",
|
|
354
|
-
422: "The server could not process the request.",
|
|
355
|
-
429: "Too many requests. Please wait a moment and try again.",
|
|
356
|
-
500: "Something went wrong on the server. Please try again later.",
|
|
357
|
-
502: "The server is temporarily unavailable. Please try again later.",
|
|
358
|
-
503: "The server is temporarily unavailable. Please try again later.",
|
|
359
|
-
504: "The server took too long to respond. Please try again later.",
|
|
360
|
-
default: "Request failed"
|
|
361
|
-
});
|
|
362
|
-
var globalMessages = null;
|
|
363
|
-
/**
|
|
364
|
-
* App-wide wording, merged over the defaults; `null` restores them. A grid's own
|
|
365
|
-
* `errorMessages` merges over this in turn, so a single table can still differ.
|
|
366
|
-
*/
|
|
367
|
-
function setErrorMessages(messages) {
|
|
368
|
-
globalMessages = messages ? { ...messages } : null;
|
|
369
|
-
}
|
|
370
|
-
/** Defaults ← app-wide ← `local`, same shape as the filter builder's `resolveTexts`. */
|
|
371
|
-
function resolveErrorMessages(local) {
|
|
372
|
-
const merged = { ...DEFAULT_ERROR_MESSAGES };
|
|
373
|
-
for (const layer of [globalMessages, local]) {
|
|
374
|
-
if (!layer) continue;
|
|
375
|
-
for (const key of Object.keys(layer)) {
|
|
376
|
-
const value = layer[key];
|
|
377
|
-
if (typeof value === "string" && value.trim()) merged[key] = value;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
return merged;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* The standard reason phrases. Not shown to anyone — they are what `describeError`
|
|
384
|
-
* uses to recognise that an error's text is ONLY the phrase for its status
|
|
385
|
-
* (`Error('Forbidden')` + `httpStatus: 403`), which adds nothing to the preset and
|
|
386
|
-
* so is not a detail worth appending.
|
|
387
|
-
*/
|
|
388
|
-
var REASON_PHRASES = {
|
|
389
|
-
400: "Bad Request",
|
|
390
|
-
401: "Unauthorized",
|
|
391
|
-
402: "Payment Required",
|
|
392
|
-
403: "Forbidden",
|
|
393
|
-
404: "Not Found",
|
|
394
|
-
405: "Method Not Allowed",
|
|
395
|
-
408: "Request Timeout",
|
|
396
|
-
409: "Conflict",
|
|
397
|
-
410: "Gone",
|
|
398
|
-
412: "Precondition Failed",
|
|
399
|
-
413: "Payload Too Large",
|
|
400
|
-
415: "Unsupported Media Type",
|
|
401
|
-
422: "Unprocessable Entity",
|
|
402
|
-
429: "Too Many Requests",
|
|
403
|
-
500: "Internal Server Error",
|
|
404
|
-
501: "Not Implemented",
|
|
405
|
-
502: "Bad Gateway",
|
|
406
|
-
503: "Service Unavailable",
|
|
407
|
-
504: "Gateway Timeout"
|
|
408
|
-
};
|
|
409
|
-
/** Texts a transport mints for "no answer at all" — a status of 0 in words. */
|
|
410
|
-
var NETWORK_TEXTS = [
|
|
411
|
-
"failed to fetch",
|
|
412
|
-
"networkerror when attempting to fetch resource",
|
|
413
|
-
"load failed",
|
|
414
|
-
"network error",
|
|
415
|
-
"unspecified network error",
|
|
416
|
-
"network connection timeout",
|
|
417
|
-
"network request failed"
|
|
418
|
-
];
|
|
419
|
-
var toStatus = (value) => {
|
|
420
|
-
if (value === null || value === void 0 || value === "") return void 0;
|
|
421
|
-
const n = Number(value);
|
|
422
|
-
return Number.isInteger(n) && n >= 0 && n < 1e3 ? n : void 0;
|
|
423
|
-
};
|
|
424
|
-
/**
|
|
425
|
-
* The HTTP status an error carries, `0` for a network failure, `undefined` when
|
|
426
|
-
* it has none.
|
|
427
|
-
*
|
|
428
|
-
* Reads the fields the common transports use — devextreme's `httpStatus`, a
|
|
429
|
-
* fetch `Response` / axios error's `status` and `response.status`, ofetch's
|
|
430
|
-
* `statusCode`, an OData error body's numeric `code` — on an `Error` instance as
|
|
431
|
-
* readily as on a plain object, since devextreme `extend()`s them onto an
|
|
432
|
-
* `Error`.
|
|
433
|
-
*/
|
|
434
|
-
function errorStatus(raw) {
|
|
435
|
-
if (!isObject(raw)) return void 0;
|
|
436
|
-
const response = isObject(raw.response) ? raw.response : void 0;
|
|
437
|
-
const direct = toStatus(raw.httpStatus) ?? toStatus(raw.status) ?? toStatus(raw.statusCode) ?? toStatus(response?.status) ?? toStatus(response?.statusCode);
|
|
438
|
-
if (direct !== void 0) return direct;
|
|
439
|
-
const code = toStatus((isObject(raw.errorDetails) ? raw.errorDetails : void 0)?.code);
|
|
440
|
-
if (code !== void 0 && code >= 400) return code;
|
|
441
|
-
const own = (raw instanceof Error ? text(raw.message) : text(raw.message)).toLowerCase();
|
|
442
|
-
if (own && NETWORK_TEXTS.some((t) => own.includes(t))) return 0;
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* The text a SERVER wrote about the failure, if the error carries one — an OData
|
|
446
|
-
* error body's message, a JSON body's `message` / `error`, an axios
|
|
447
|
-
* `response.data`. `''` when there is nothing beyond the transport's own words.
|
|
448
|
-
*/
|
|
449
|
-
function serverDetail(raw) {
|
|
450
|
-
if (!isObject(raw)) return "";
|
|
451
|
-
const details = raw.errorDetails;
|
|
452
|
-
if (isObject(details)) {
|
|
453
|
-
const m = details.message;
|
|
454
|
-
const hit = text(m) || (isObject(m) ? text(m.value) : "");
|
|
455
|
-
if (hit) return hit;
|
|
456
|
-
}
|
|
457
|
-
const response = isObject(raw.response) ? raw.response : void 0;
|
|
458
|
-
const data = response?.data ?? response?._data ?? raw.data;
|
|
459
|
-
if (isObject(data)) {
|
|
460
|
-
const err = data.error;
|
|
461
|
-
const hit = text(data.message) || text(data.detail) || text(data.title) || text(err) || (isObject(err) ? text(err.message) : "");
|
|
462
|
-
if (hit) return hit;
|
|
463
|
-
} else if (text(data)) return text(data);
|
|
464
|
-
if (!(raw instanceof Error)) {
|
|
465
|
-
const err = raw.error;
|
|
466
|
-
const hit = text(raw.errorMessage) || text(raw.detail) || (isObject(err) ? text(err.message) : "");
|
|
467
|
-
if (hit) return hit;
|
|
468
|
-
}
|
|
469
|
-
return "";
|
|
470
|
-
}
|
|
471
|
-
/** Is `value` nothing more than the reason phrase / a generic label for `status`? */
|
|
472
|
-
function isBoilerplate(value, status) {
|
|
473
|
-
const v = value.toLowerCase();
|
|
474
|
-
if (!v || v === "error" || v === "unknown error" || v === "request failed") return true;
|
|
475
|
-
if (/^http\s*\d{3}$/.test(v)) return true;
|
|
476
|
-
if (NETWORK_TEXTS.some((t) => v.includes(t))) return true;
|
|
477
|
-
if (status !== void 0) {
|
|
478
|
-
const phrase = REASON_PHRASES[status]?.toLowerCase();
|
|
479
|
-
if (phrase && (v === phrase || v === `${status} ${phrase}` || v === `${status}`)) return true;
|
|
480
|
-
if (v === String(status)) return true;
|
|
481
|
-
}
|
|
482
|
-
return Object.values(REASON_PHRASES).some((p) => p.toLowerCase() === v);
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* The line a person should read for `raw`.
|
|
486
|
-
*
|
|
487
|
-
* Order: a preset for the status (`'network'` for 0) → the error's own text →
|
|
488
|
-
* `messages.default`. When a preset is the headline, whatever the server said
|
|
489
|
-
* on top of the status becomes `detail`; without a preset, the raw text IS the
|
|
490
|
-
* headline and only a distinct server body is a detail. Never throws, never
|
|
491
|
-
* returns an empty `message`.
|
|
492
|
-
*/
|
|
493
|
-
function describeError(raw, messages) {
|
|
494
|
-
const texts = resolveErrorMessages(messages);
|
|
495
|
-
const status = errorStatus(raw);
|
|
496
|
-
const fallback = texts.default || DEFAULT_ERROR_MESSAGES.default;
|
|
497
|
-
const rawText = normalizeError(raw, fallback);
|
|
498
|
-
const preset = status === void 0 ? void 0 : status === 0 ? texts.network : texts[status];
|
|
499
|
-
if (preset) {
|
|
500
|
-
const candidate = serverDetail(raw) || (rawText === fallback ? "" : rawText);
|
|
501
|
-
const detail = candidate && !isBoilerplate(candidate, status) && candidate !== preset ? candidate : "";
|
|
502
|
-
return detail ? {
|
|
503
|
-
message: preset,
|
|
504
|
-
status,
|
|
505
|
-
detail
|
|
506
|
-
} : {
|
|
507
|
-
message: preset,
|
|
508
|
-
status
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
const message = rawText || fallback;
|
|
512
|
-
const fromServer = serverDetail(raw);
|
|
513
|
-
const detail = fromServer && fromServer !== message && !isBoilerplate(fromServer, status) ? fromServer : "";
|
|
514
|
-
const out = { message };
|
|
515
|
-
if (status !== void 0) out.status = status;
|
|
516
|
-
if (detail) out.detail = detail;
|
|
517
|
-
return out;
|
|
518
|
-
}
|
|
519
|
-
//#endregion
|
|
520
297
|
//#region src/components/table/store-group-source.ts
|
|
521
298
|
/**
|
|
522
299
|
* Build a {@link MonoServerGroupSource} that drives **server-side** group paging
|
|
@@ -595,10 +372,6 @@ function storeGroupSource(source, config) {
|
|
|
595
372
|
}
|
|
596
373
|
//#endregion
|
|
597
374
|
//#region src/components/table/mono-data-grid.ts
|
|
598
|
-
function isCanceled(err) {
|
|
599
|
-
if (!err) return false;
|
|
600
|
-
return err === "canceled" || err.name === "canceled" || err.message === "canceled" || err.__id === "canceled";
|
|
601
|
-
}
|
|
602
375
|
function monoDataGrid(ds = null, opts = {}) {
|
|
603
376
|
let bound = null;
|
|
604
377
|
let searchFieldsOverride;
|
|
@@ -4117,7 +3890,7 @@ function monoDataGrid(ds = null, opts = {}) {
|
|
|
4117
3890
|
});
|
|
4118
3891
|
}
|
|
4119
3892
|
async function exportReport(options) {
|
|
4120
|
-
const { exportTable } = await import("./export-
|
|
3893
|
+
const { exportTable } = await import("./export-BiGVyxt6.js");
|
|
4121
3894
|
return exportTable(options);
|
|
4122
3895
|
}
|
|
4123
3896
|
function subscribe(cb) {
|
|
@@ -4137,4 +3910,4 @@ function monoDataGrid(ds = null, opts = {}) {
|
|
|
4137
3910
|
return ctrl;
|
|
4138
3911
|
}
|
|
4139
3912
|
//#endregion
|
|
4140
|
-
export {
|
|
3913
|
+
export { seedFromRanges as a, minimize as i, buildDateTree as n, setAllChecked as o, checkState as r, setChecked as s, monoDataGrid as t };
|
|
@@ -1,235 +1,12 @@
|
|
|
1
1
|
import { a as parseFieldPath, c as toODataClause, l as toODataSelector, n as isPath, o as projectFields, r as mergePatch, s as setFieldValue, t as getFieldValue } from "./field-path-C92eGLg3.js";
|
|
2
2
|
import { a as buildGroups, c as isGroupNode, i as searchFilterOf, o as collectGroupPaths, r as readAllRows, s as flattenLeaves } from "./data-source-read-DL88aH8t.js";
|
|
3
3
|
import { i as joinFilters, n as andPredicates, r as compileFilterPredicate, t as andFilters } from "./filter-eval-DIfU2EAn.js";
|
|
4
|
-
import {
|
|
5
|
-
import { a as resolveDataSourceOptions, c as composeSummaryApply, d as createApplyGate, f as isRolledUp, h as monoArraySource, i as normalizeSortList, l as summaryAliases, m as storeRows, n as extraLoadOptions, o as toList, p as loadApply, s as buildSummaryApply, t as dataSourceOptionsKey, u as summaryFilterOf } from "./data-source-options-
|
|
4
|
+
import { A as resolveSearchEntries, C as customRemoteClause, E as hasWildcardSearch, S as customPredicate, T as hasCustomSearch, h as mergeSearchFields, j as searchEntryFor, k as plainSearchColumns, n as describeError, o as isCanceled, u as DEFAULT_SEARCH_FIELDS } from "./normalize-error-Gcgmgh5i.js";
|
|
5
|
+
import { a as resolveDataSourceOptions, c as composeSummaryApply, d as createApplyGate, f as isRolledUp, h as monoArraySource, i as normalizeSortList, l as summaryAliases, m as storeRows, n as extraLoadOptions, o as toList, p as loadApply, s as buildSummaryApply, t as dataSourceOptionsKey, u as summaryFilterOf } from "./data-source-options-Jqj7LU3Z.js";
|
|
6
6
|
import { n as unwrapReactive } from "./reactive-D3EERqgO.js";
|
|
7
7
|
import { t as arrayToODataString } from "./filter-odata-C1vSGZaY.js";
|
|
8
8
|
import { t as createNotifier } from "./notifier-CE4yxMUQ.js";
|
|
9
9
|
import { t as monoFilterBuilder } from "./filter-builder-Bke3qOgJ.js";
|
|
10
|
-
//#region src/utils/normalize-error.ts
|
|
11
|
-
/** Fields worth reading off an object that is not an `Error`. */
|
|
12
|
-
var MESSAGE_KEYS = [
|
|
13
|
-
"message",
|
|
14
|
-
"statusText",
|
|
15
|
-
"errorMessage",
|
|
16
|
-
"error",
|
|
17
|
-
"detail"
|
|
18
|
-
];
|
|
19
|
-
var text = (value) => typeof value === "string" && value.trim() ? value.trim() : "";
|
|
20
|
-
var isObject = (value) => value !== null && typeof value === "object";
|
|
21
|
-
/**
|
|
22
|
-
* A readable message for `raw`, or `fallback` when nothing legible can be found.
|
|
23
|
-
*
|
|
24
|
-
* Never throws, and never returns an empty string — a caller rendering this into
|
|
25
|
-
* an error bar has to have something to render, and a blank bar is worse than a
|
|
26
|
-
* generic one.
|
|
27
|
-
*/
|
|
28
|
-
function normalizeError(raw, fallback = "Request failed") {
|
|
29
|
-
if (raw == null) return fallback;
|
|
30
|
-
if (raw instanceof Error) {
|
|
31
|
-
const own = text(raw.message);
|
|
32
|
-
if (own) return own;
|
|
33
|
-
} else {
|
|
34
|
-
if (typeof raw === "string") return text(raw) || fallback;
|
|
35
|
-
if (typeof raw === "number" || typeof raw === "boolean") return String(raw);
|
|
36
|
-
}
|
|
37
|
-
if (isObject(raw)) {
|
|
38
|
-
const obj = raw;
|
|
39
|
-
for (const key of MESSAGE_KEYS) {
|
|
40
|
-
const hit = text(obj[key]);
|
|
41
|
-
if (hit) return hit;
|
|
42
|
-
}
|
|
43
|
-
const response = obj.response;
|
|
44
|
-
if (isObject(response)) {
|
|
45
|
-
const nested = text(response.statusText) || text(response.message);
|
|
46
|
-
if (nested) return nested;
|
|
47
|
-
}
|
|
48
|
-
const status = errorStatus(obj);
|
|
49
|
-
if (status !== void 0 && status > 0) return `HTTP ${status}`;
|
|
50
|
-
if (raw instanceof Error) return text(raw.name) || fallback;
|
|
51
|
-
return fallback;
|
|
52
|
-
}
|
|
53
|
-
return text(String(raw)) || fallback;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* What the bar says for a status. English; an app puts its own language in
|
|
57
|
-
* ONCE with `setErrorMessages()` rather than on every table.
|
|
58
|
-
*/
|
|
59
|
-
var DEFAULT_ERROR_MESSAGES = Object.freeze({
|
|
60
|
-
network: "Could not reach the server. Check your connection and try again.",
|
|
61
|
-
400: "The server rejected the request.",
|
|
62
|
-
401: "Your session has expired. Please sign in again.",
|
|
63
|
-
403: "You do not have permission to view this data.",
|
|
64
|
-
404: "The requested data could not be found.",
|
|
65
|
-
408: "The server took too long to respond. Please try again.",
|
|
66
|
-
409: "The request conflicts with the current state of the data.",
|
|
67
|
-
422: "The server could not process the request.",
|
|
68
|
-
429: "Too many requests. Please wait a moment and try again.",
|
|
69
|
-
500: "Something went wrong on the server. Please try again later.",
|
|
70
|
-
502: "The server is temporarily unavailable. Please try again later.",
|
|
71
|
-
503: "The server is temporarily unavailable. Please try again later.",
|
|
72
|
-
504: "The server took too long to respond. Please try again later.",
|
|
73
|
-
default: "Request failed"
|
|
74
|
-
});
|
|
75
|
-
var globalMessages = null;
|
|
76
|
-
/**
|
|
77
|
-
* App-wide wording, merged over the defaults; `null` restores them. A grid's own
|
|
78
|
-
* `errorMessages` merges over this in turn, so a single table can still differ.
|
|
79
|
-
*/
|
|
80
|
-
function setErrorMessages(messages) {
|
|
81
|
-
globalMessages = messages ? { ...messages } : null;
|
|
82
|
-
}
|
|
83
|
-
/** Defaults ← app-wide ← `local`, same shape as the filter builder's `resolveTexts`. */
|
|
84
|
-
function resolveErrorMessages(local) {
|
|
85
|
-
const merged = { ...DEFAULT_ERROR_MESSAGES };
|
|
86
|
-
for (const layer of [globalMessages, local]) {
|
|
87
|
-
if (!layer) continue;
|
|
88
|
-
for (const key of Object.keys(layer)) {
|
|
89
|
-
const value = layer[key];
|
|
90
|
-
if (typeof value === "string" && value.trim()) merged[key] = value;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return merged;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* The standard reason phrases. Not shown to anyone — they are what `describeError`
|
|
97
|
-
* uses to recognise that an error's text is ONLY the phrase for its status
|
|
98
|
-
* (`Error('Forbidden')` + `httpStatus: 403`), which adds nothing to the preset and
|
|
99
|
-
* so is not a detail worth appending.
|
|
100
|
-
*/
|
|
101
|
-
var REASON_PHRASES = {
|
|
102
|
-
400: "Bad Request",
|
|
103
|
-
401: "Unauthorized",
|
|
104
|
-
402: "Payment Required",
|
|
105
|
-
403: "Forbidden",
|
|
106
|
-
404: "Not Found",
|
|
107
|
-
405: "Method Not Allowed",
|
|
108
|
-
408: "Request Timeout",
|
|
109
|
-
409: "Conflict",
|
|
110
|
-
410: "Gone",
|
|
111
|
-
412: "Precondition Failed",
|
|
112
|
-
413: "Payload Too Large",
|
|
113
|
-
415: "Unsupported Media Type",
|
|
114
|
-
422: "Unprocessable Entity",
|
|
115
|
-
429: "Too Many Requests",
|
|
116
|
-
500: "Internal Server Error",
|
|
117
|
-
501: "Not Implemented",
|
|
118
|
-
502: "Bad Gateway",
|
|
119
|
-
503: "Service Unavailable",
|
|
120
|
-
504: "Gateway Timeout"
|
|
121
|
-
};
|
|
122
|
-
/** Texts a transport mints for "no answer at all" — a status of 0 in words. */
|
|
123
|
-
var NETWORK_TEXTS = [
|
|
124
|
-
"failed to fetch",
|
|
125
|
-
"networkerror when attempting to fetch resource",
|
|
126
|
-
"load failed",
|
|
127
|
-
"network error",
|
|
128
|
-
"unspecified network error",
|
|
129
|
-
"network connection timeout",
|
|
130
|
-
"network request failed"
|
|
131
|
-
];
|
|
132
|
-
var toStatus = (value) => {
|
|
133
|
-
if (value === null || value === void 0 || value === "") return void 0;
|
|
134
|
-
const n = Number(value);
|
|
135
|
-
return Number.isInteger(n) && n >= 0 && n < 1e3 ? n : void 0;
|
|
136
|
-
};
|
|
137
|
-
/**
|
|
138
|
-
* The HTTP status an error carries, `0` for a network failure, `undefined` when
|
|
139
|
-
* it has none.
|
|
140
|
-
*
|
|
141
|
-
* Reads the fields the common transports use — devextreme's `httpStatus`, a
|
|
142
|
-
* fetch `Response` / axios error's `status` and `response.status`, ofetch's
|
|
143
|
-
* `statusCode`, an OData error body's numeric `code` — on an `Error` instance as
|
|
144
|
-
* readily as on a plain object, since devextreme `extend()`s them onto an
|
|
145
|
-
* `Error`.
|
|
146
|
-
*/
|
|
147
|
-
function errorStatus(raw) {
|
|
148
|
-
if (!isObject(raw)) return void 0;
|
|
149
|
-
const response = isObject(raw.response) ? raw.response : void 0;
|
|
150
|
-
const direct = toStatus(raw.httpStatus) ?? toStatus(raw.status) ?? toStatus(raw.statusCode) ?? toStatus(response?.status) ?? toStatus(response?.statusCode);
|
|
151
|
-
if (direct !== void 0) return direct;
|
|
152
|
-
const code = toStatus((isObject(raw.errorDetails) ? raw.errorDetails : void 0)?.code);
|
|
153
|
-
if (code !== void 0 && code >= 400) return code;
|
|
154
|
-
const own = (raw instanceof Error ? text(raw.message) : text(raw.message)).toLowerCase();
|
|
155
|
-
if (own && NETWORK_TEXTS.some((t) => own.includes(t))) return 0;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* The text a SERVER wrote about the failure, if the error carries one — an OData
|
|
159
|
-
* error body's message, a JSON body's `message` / `error`, an axios
|
|
160
|
-
* `response.data`. `''` when there is nothing beyond the transport's own words.
|
|
161
|
-
*/
|
|
162
|
-
function serverDetail(raw) {
|
|
163
|
-
if (!isObject(raw)) return "";
|
|
164
|
-
const details = raw.errorDetails;
|
|
165
|
-
if (isObject(details)) {
|
|
166
|
-
const m = details.message;
|
|
167
|
-
const hit = text(m) || (isObject(m) ? text(m.value) : "");
|
|
168
|
-
if (hit) return hit;
|
|
169
|
-
}
|
|
170
|
-
const response = isObject(raw.response) ? raw.response : void 0;
|
|
171
|
-
const data = response?.data ?? response?._data ?? raw.data;
|
|
172
|
-
if (isObject(data)) {
|
|
173
|
-
const err = data.error;
|
|
174
|
-
const hit = text(data.message) || text(data.detail) || text(data.title) || text(err) || (isObject(err) ? text(err.message) : "");
|
|
175
|
-
if (hit) return hit;
|
|
176
|
-
} else if (text(data)) return text(data);
|
|
177
|
-
if (!(raw instanceof Error)) {
|
|
178
|
-
const err = raw.error;
|
|
179
|
-
const hit = text(raw.errorMessage) || text(raw.detail) || (isObject(err) ? text(err.message) : "");
|
|
180
|
-
if (hit) return hit;
|
|
181
|
-
}
|
|
182
|
-
return "";
|
|
183
|
-
}
|
|
184
|
-
/** Is `value` nothing more than the reason phrase / a generic label for `status`? */
|
|
185
|
-
function isBoilerplate(value, status) {
|
|
186
|
-
const v = value.toLowerCase();
|
|
187
|
-
if (!v || v === "error" || v === "unknown error" || v === "request failed") return true;
|
|
188
|
-
if (/^http\s*\d{3}$/.test(v)) return true;
|
|
189
|
-
if (NETWORK_TEXTS.some((t) => v.includes(t))) return true;
|
|
190
|
-
if (status !== void 0) {
|
|
191
|
-
const phrase = REASON_PHRASES[status]?.toLowerCase();
|
|
192
|
-
if (phrase && (v === phrase || v === `${status} ${phrase}` || v === `${status}`)) return true;
|
|
193
|
-
if (v === String(status)) return true;
|
|
194
|
-
}
|
|
195
|
-
return Object.values(REASON_PHRASES).some((p) => p.toLowerCase() === v);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* The line a person should read for `raw`.
|
|
199
|
-
*
|
|
200
|
-
* Order: a preset for the status (`'network'` for 0) → the error's own text →
|
|
201
|
-
* `messages.default`. When a preset is the headline, whatever the server said
|
|
202
|
-
* on top of the status becomes `detail`; without a preset, the raw text IS the
|
|
203
|
-
* headline and only a distinct server body is a detail. Never throws, never
|
|
204
|
-
* returns an empty `message`.
|
|
205
|
-
*/
|
|
206
|
-
function describeError(raw, messages) {
|
|
207
|
-
const texts = resolveErrorMessages(messages);
|
|
208
|
-
const status = errorStatus(raw);
|
|
209
|
-
const fallback = texts.default || DEFAULT_ERROR_MESSAGES.default;
|
|
210
|
-
const rawText = normalizeError(raw, fallback);
|
|
211
|
-
const preset = status === void 0 ? void 0 : status === 0 ? texts.network : texts[status];
|
|
212
|
-
if (preset) {
|
|
213
|
-
const candidate = serverDetail(raw) || (rawText === fallback ? "" : rawText);
|
|
214
|
-
const detail = candidate && !isBoilerplate(candidate, status) && candidate !== preset ? candidate : "";
|
|
215
|
-
return detail ? {
|
|
216
|
-
message: preset,
|
|
217
|
-
status,
|
|
218
|
-
detail
|
|
219
|
-
} : {
|
|
220
|
-
message: preset,
|
|
221
|
-
status
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
const message = rawText || fallback;
|
|
225
|
-
const fromServer = serverDetail(raw);
|
|
226
|
-
const detail = fromServer && fromServer !== message && !isBoilerplate(fromServer, status) ? fromServer : "";
|
|
227
|
-
const out = { message };
|
|
228
|
-
if (status !== void 0) out.status = status;
|
|
229
|
-
if (detail) out.detail = detail;
|
|
230
|
-
return out;
|
|
231
|
-
}
|
|
232
|
-
//#endregion
|
|
233
10
|
//#region src/components/table/store-group-source.ts
|
|
234
11
|
/**
|
|
235
12
|
* Build a {@link MonoServerGroupSource} that drives **server-side** group paging
|
|
@@ -597,10 +374,6 @@ function inRange(d, r) {
|
|
|
597
374
|
}
|
|
598
375
|
//#endregion
|
|
599
376
|
//#region src/components/table/mono-data-grid.ts
|
|
600
|
-
function isCanceled(err) {
|
|
601
|
-
if (!err) return false;
|
|
602
|
-
return err === "canceled" || err.name === "canceled" || err.message === "canceled" || err.__id === "canceled";
|
|
603
|
-
}
|
|
604
377
|
function monoDataGrid(ds = null, opts = {}) {
|
|
605
378
|
let bound = null;
|
|
606
379
|
let searchFieldsOverride;
|
|
@@ -4139,4 +3912,4 @@ function monoDataGrid(ds = null, opts = {}) {
|
|
|
4139
3912
|
return ctrl;
|
|
4140
3913
|
}
|
|
4141
3914
|
//#endregion
|
|
4142
|
-
export { seedFromRanges as a,
|
|
3915
|
+
export { seedFromRanges as a, minimize as i, buildDateTree as n, setAllChecked as o, checkState as r, setChecked as s, monoDataGrid as t };
|