arrmatura 5.0.4 → 5.2.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/commons/auth/AuthService.ts +111 -0
- package/commons/auth/UserService.ts +28 -78
- package/commons/auth/index.ts +4 -3
- package/commons/auth/user.xml +18 -20
- package/commons/components/buttons.xml +6 -4
- package/commons/components/layouts.xml +8 -8
- package/commons/components/modal.xml +4 -4
- package/commons/components/navigation.xml +21 -7
- package/commons/components/searchbar.xml +36 -22
- package/commons/components/table.xml +25 -5
- package/commons/components/toasts.xml +10 -5
- package/commons/forms/FormController.ts +48 -34
- package/commons/forms/Item.ts +93 -29
- package/commons/forms/ItemCollectionController.ts +113 -0
- package/commons/forms/ItemController.ts +50 -21
- package/commons/forms/NewItemController.ts +46 -0
- package/commons/forms/SmartareaField.xml +3 -3
- package/commons/forms/SuggestionField.xml +3 -3
- package/commons/forms/fields.xml +28 -15
- package/commons/forms/form.xml +3 -3
- package/commons/forms/index.ts +4 -4
- package/commons/index.ts +2 -2
- package/commons/services/ApiClientService.ts +32 -0
- package/commons/services/GSheetsService.ts +92 -64
- package/commons/services/Invoke.ts +24 -8
- package/commons/services/JsonpService.ts +1 -1
- package/commons/services/MetadataService.ts +50 -0
- package/commons/services/NavigationService.ts +20 -1
- package/commons/services/Service.ts +22 -28
- package/commons/services/Storage.ts +55 -0
- package/commons/services/ToastService.ts +16 -4
- package/commons/services/index.ts +3 -4
- package/core/Arrmatura.ts +4 -9
- package/core/CNode.ts +1 -2
- package/core/Component.ts +29 -31
- package/core/cnodes/conditionals.ts +3 -2
- package/core/expression.ts +1 -1
- package/core/register.ts +1 -1
- package/core/utils.ts +1 -3
- package/core-web/attributes.ts +38 -10
- package/core-web/elements.ts +22 -4
- package/core-web/index.ts +14 -2
- package/core-web/reflow.ts +3 -1
- package/core-web/support.ts +27 -0
- package/docs/index.js +350 -66
- package/lib/{arrayGroupBy.ts → array/arrayGroupBy.ts} +1 -1
- package/lib/{arraySortBy.ts → array/arraySortBy.ts} +5 -5
- package/lib/{arrayToObject.ts → array/arrayToObject.ts} +0 -0
- package/lib/array/arrayish.ts +7 -0
- package/lib/array/index.ts +4 -0
- package/lib/crypto/index.ts +25 -0
- package/lib/{dateFormat.ts → date/index.ts} +61 -3
- package/lib/func/curry.ts +11 -0
- package/lib/{fx.ts → func/fx.ts} +32 -38
- package/lib/{noop.ts → func/identity.ts} +1 -3
- package/lib/{nextId.ts → func/nextId.ts} +0 -0
- package/lib/func/noop.ts +6 -0
- package/lib/geo/index.js +22 -0
- package/lib/index.ts +17 -19
- package/lib/{obj.ts → object/index.ts} +8 -3
- package/lib/{codus.ts → parsing/codus.ts} +1 -1
- package/lib/{predicat.ts → parsing/compiler.ts} +0 -0
- package/lib/{scalar.ts → parsing/scalarParse.ts} +0 -0
- package/lib/{urls.ts → parsing/urls.ts} +0 -0
- package/lib/{xml.ts → parsing/xml.ts} +3 -3
- package/lib/{l10n.ts → resources/l10n.ts} +2 -2
- package/lib/{resources.ru.ts → resources/resources.ru.ts} +0 -0
- package/lib/{resources.ts → resources/resources.ts} +0 -0
- package/lib/{str.ts → string/index.ts} +2 -20
- package/lib/{createListeners.ts → support/createListeners.ts} +0 -0
- package/package.json +7 -6
- package/commons/forms/ItemCollection.ts +0 -152
- package/commons/forms/MetadataService.ts +0 -45
- package/commons/pipes/index.ts +0 -21
- package/commons/pipes/showCounts.ts +0 -16
- package/commons/services/LocalStorage.ts +0 -46
- package/lib/consts.ts +0 -3
- package/lib/curry.ts +0 -8
- package/lib/dateOf.ts +0 -31
- package/lib/dateParseISO8601.ts +0 -27
- package/lib/guid.ts +0 -7
|
@@ -25,8 +25,8 @@ const sortByComparator = <T extends Comparable>(
|
|
|
25
25
|
key = fn.substr(1);
|
|
26
26
|
}
|
|
27
27
|
return (a: T, b: T): ComparatorResult => {
|
|
28
|
-
const aa = a[
|
|
29
|
-
const bb = b[
|
|
28
|
+
const aa = a[key];
|
|
29
|
+
const bb = b[key];
|
|
30
30
|
return aa < bb ? negOrder : aa > bb ? order : 0;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
@@ -40,10 +40,10 @@ const sortByComparator = <T extends Comparable>(
|
|
|
40
40
|
/**
|
|
41
41
|
* Sorts array by element property
|
|
42
42
|
*/
|
|
43
|
-
export const arraySortBy = function sortBy(
|
|
44
|
-
arr:
|
|
43
|
+
export const arraySortBy = function sortBy<T extends Comparable>(
|
|
44
|
+
arr: T[],
|
|
45
45
|
property = 'name',
|
|
46
46
|
order: ComparatorDirection = ComparatorDirection.ASC
|
|
47
47
|
) {
|
|
48
|
-
return
|
|
48
|
+
return !arr ? [] : [...arr].sort(sortByComparator<T>(property, order));
|
|
49
49
|
};
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// arrayish:
|
|
2
|
+
export const includes = (x: any, p: string) => x?.includes?.(p);
|
|
3
|
+
export const slice = <T>(x: T[], b = 0, e?: number): T[] => x?.slice?.(b, e) || [];
|
|
4
|
+
export const split = (x: string, key = ' ') => x?.split?.(key) || [];
|
|
5
|
+
export const find = <T extends Hash<any>>(x: T[], val: unknown, key = 'id') => x?.find?.((e: T) => e[key] == val);
|
|
6
|
+
export const filter = <T extends Hash<any>>(x: T[], key: string, val: unknown) =>
|
|
7
|
+
x?.filter?.((e: T) => !e[key] || e[key] == val);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Simple GUID generator. */
|
|
2
|
+
const s4 = (): string =>
|
|
3
|
+
Math.floor((1 + Math.random()) * 0x10000)
|
|
4
|
+
.toString(16)
|
|
5
|
+
.substring(1);
|
|
6
|
+
|
|
7
|
+
export const guid = (): string => `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
|
|
8
|
+
|
|
9
|
+
/* Simple hash function. */
|
|
10
|
+
export const hash = (s: string) => {
|
|
11
|
+
let a = 1,
|
|
12
|
+
c = 0,
|
|
13
|
+
h,
|
|
14
|
+
o;
|
|
15
|
+
if (s) {
|
|
16
|
+
a = 0;
|
|
17
|
+
for (h = s.length - 1; h >= 0; h--) {
|
|
18
|
+
o = s.charCodeAt(h);
|
|
19
|
+
a = ((a << 6) & 268435455) + o + (o << 14);
|
|
20
|
+
c = a & 266338304;
|
|
21
|
+
a = c !== 0 ? a ^ (c >> 21) : a;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return String(a);
|
|
25
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { padLeft } from 'str';
|
|
1
|
+
import { t } from '../resources/l10n';
|
|
2
|
+
import { padLeft } from 'string';
|
|
4
3
|
|
|
5
4
|
export const daysInMonth = (month: number, year: number) => new Date(year, month + 1, 0).getDate();
|
|
6
5
|
|
|
@@ -53,6 +52,33 @@ export function setDefaultDateFormat(f: string) {
|
|
|
53
52
|
DEFAULT_DATE_FORMAT = f;
|
|
54
53
|
}
|
|
55
54
|
|
|
55
|
+
export const dateParseISO8601 = function (x: string, TZ = new Date().getTimezoneOffset()) {
|
|
56
|
+
if (!x) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
if (x.length === 10) {
|
|
60
|
+
x += 'T12:00';
|
|
61
|
+
}
|
|
62
|
+
const timebits =
|
|
63
|
+
/^([0-9]{4})-([0-9]{2})-([0-9]{2})[ T]([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(Z?)(([+-])([0-9]{2})([0-9]{2}))?/;
|
|
64
|
+
const m = timebits.exec(x);
|
|
65
|
+
if (!m) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const tz = m[8] ? (!m[9] ? 0 : (m[10] === '+' ? -1 : +1) * (parseInt(m[11]) * 60 + parseInt(m[12]))) : TZ;
|
|
69
|
+
// utcdate is milliseconds since the epoch
|
|
70
|
+
const utcdate = Date.UTC(
|
|
71
|
+
parseInt(m[1]),
|
|
72
|
+
parseInt(m[2]) - 1, // months are zero-offset (!)
|
|
73
|
+
parseInt(m[3]),
|
|
74
|
+
parseInt(m[4]),
|
|
75
|
+
parseInt(m[5]), // hh:mm
|
|
76
|
+
(m[6] && parseInt(m[6])) || 0, // optional seconds
|
|
77
|
+
(m[7] && parseFloat(m[7])) || 0
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
return new Date(utcdate + tz * 60000);
|
|
81
|
+
};
|
|
56
82
|
export const dateFormat = (x: Dateable | null, format = DEFAULT_DATE_FORMAT) => {
|
|
57
83
|
if (!x) {
|
|
58
84
|
return '';
|
|
@@ -67,3 +93,35 @@ export const dateFormat = (x: Dateable | null, format = DEFAULT_DATE_FORMAT) =>
|
|
|
67
93
|
return key;
|
|
68
94
|
});
|
|
69
95
|
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Universal converter to Date.
|
|
99
|
+
*
|
|
100
|
+
* @returns Date instance or null
|
|
101
|
+
*/
|
|
102
|
+
export function dateOf(x: Dateable | null): Date | null {
|
|
103
|
+
if (x == null) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
if (typeof x === 'number') {
|
|
107
|
+
return new Date(x);
|
|
108
|
+
}
|
|
109
|
+
if (typeof x === 'object') {
|
|
110
|
+
// Date or has time
|
|
111
|
+
const dx = x as { getTime?: () => number };
|
|
112
|
+
if (dx.getTime) {
|
|
113
|
+
return new Date(dx.getTime());
|
|
114
|
+
}
|
|
115
|
+
// having a date representation
|
|
116
|
+
const ddx = x as { toDate?: () => Date };
|
|
117
|
+
if (ddx.toDate) {
|
|
118
|
+
return ddx.toDate();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (typeof x === 'string') {
|
|
122
|
+
return dateParseISO8601(x);
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const date = (x: any) => dateFormat(dateOf(x));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Fx<S> = (...args: unknown[]) => Fxx<S>;
|
|
2
|
+
type Fxx<S> = S | ((...args: unknown[]) => S | Fx<S>);
|
|
3
|
+
|
|
4
|
+
const _curry = <S>(fn: Fx<S>, args0: unknown[], lengthLimit: number): Fxx<S> => {
|
|
5
|
+
const fx = (args: unknown[]): Fxx<S> =>
|
|
6
|
+
args.length >= lengthLimit ? fn(...args) : _curry(fn, args, lengthLimit - args.length);
|
|
7
|
+
|
|
8
|
+
return (...args: unknown[]) => fx([...args0, ...args]);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const curry = <S>(fn: Fx<S>, ...args: unknown[]): Fxx<S> => _curry<S>(fn, args, fn.length);
|
package/lib/{fx.ts → func/fx.ts}
RENAMED
|
@@ -1,35 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Functions
|
|
2
|
+
* Useful low-level Functions.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export * from './obj';
|
|
6
|
-
|
|
7
|
-
export const assert = (b: unknown, error: string | Error, ErrorType = Error) => {
|
|
8
|
-
if (!b) {
|
|
9
|
-
throw typeof error === 'string' ? new ErrorType(error) : error;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const log = (x: any, pre: string) => {
|
|
14
|
-
console.log(pre || 'pipe', x);
|
|
15
|
-
return x;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const nextTick = (fn: any, lag: number) => {
|
|
19
|
-
return () => setTimeout(fn, lag);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const callFn = (fn: any, ...args: number[]) => {
|
|
23
|
-
return fn(...args);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// arrayish:
|
|
27
|
-
export const includes = (x: any, p: string) => x?.includes?.(p);
|
|
28
|
-
export const slice = <T>(x: T[], b = 0, e?: number): T[] => (x ? x.slice(b, e) : []);
|
|
29
|
-
|
|
30
5
|
// checks
|
|
31
6
|
export const isTrue = (x: any) => x === true;
|
|
32
7
|
export const isFalse = (x: any) => x === false;
|
|
8
|
+
export const isNotANumber = (x: any) => isNaN(x);
|
|
33
9
|
export const isUndefined = <T = unknown>(x: T): boolean => typeof x === 'undefined';
|
|
34
10
|
|
|
35
11
|
// logical
|
|
@@ -41,22 +17,40 @@ export const and = (x: any, s: any) => x && s;
|
|
|
41
17
|
|
|
42
18
|
// math
|
|
43
19
|
// eslint-disable-next-line eqeqeq
|
|
44
|
-
export const equals = (x: any, p: any) => x == p;
|
|
45
|
-
export const greater = (x: any, p: any) => x > p;
|
|
46
|
-
export const less = (x: any, p: any) => x < p;
|
|
20
|
+
export const equals = (x: any, p: any, thenn: any = true, elsee: any = false) => (x == p ? thenn : elsee);
|
|
21
|
+
export const greater = (x: any, p: any, thenn: any = true, elsee: any = false) => (x > p ? thenn : elsee);
|
|
22
|
+
export const less = (x: any, p: any, thenn: any = true, elsee: any = false) => (x < p ? thenn : elsee);
|
|
23
|
+
export const min = Math.min;
|
|
24
|
+
export const max = Math.max;
|
|
47
25
|
export const plus = (x: any, alt: any) => +x + +alt;
|
|
48
26
|
export const minus = (x: any, alt: any) => +x - +alt;
|
|
49
27
|
export const multiply = (x: any, alt: any) => +x * +alt;
|
|
50
|
-
export const swap = (f: BinaryOp) => (a: unknown, b: unknown) => f(b, a);
|
|
51
28
|
|
|
52
|
-
|
|
29
|
+
// functions
|
|
30
|
+
export const fnBindArgs = (fn: () => unknown, ...args: never[]) => fn?.bind(null, ...args);
|
|
31
|
+
|
|
32
|
+
export const fnCall = (fn: any, ...args: number[]) => {
|
|
33
|
+
return fn(...args);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const assert = (b: unknown, error: string | Error, ErrorType = Error) => {
|
|
37
|
+
if (!b) {
|
|
38
|
+
throw typeof error === 'string' ? new ErrorType(error) : error;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const log = (x: any, pre: string) => {
|
|
43
|
+
console.log(pre || 'pipe', x);
|
|
44
|
+
return x;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const fnTick = (fn: any, lag: number) => {
|
|
48
|
+
return () => setTimeout(fn, lag);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const fnSwapArgs = (f: BinaryOp) => (a: unknown, b: unknown) => f(b, a);
|
|
52
|
+
|
|
53
|
+
export const fnCompose =
|
|
53
54
|
(...ff: ((e: unknown) => unknown)[]) =>
|
|
54
55
|
(x0: unknown) =>
|
|
55
56
|
ff.reduceRight((x: unknown, fn) => fn(x), x0);
|
|
56
|
-
|
|
57
|
-
export const bindArgs = (fn: () => unknown, ...args: never[]) => fn?.bind(null, ...args);
|
|
58
|
-
|
|
59
|
-
export const assignFirstArgKeyValue =
|
|
60
|
-
(fn: () => unknown, key: string, val: unknown) =>
|
|
61
|
-
(x: object, ...args: unknown[]) =>
|
|
62
|
-
fn(Object.assign(x || {}, { [key]: val }), ...args.slice(1));
|
|
File without changes
|
package/lib/func/noop.ts
ADDED
package/lib/geo/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
/* eslint-disable max-statements */
|
|
3
|
+
export const calculateDistance = (_lat1, _long1, _lat2, _long2) => {
|
|
4
|
+
const R = 6372795;
|
|
5
|
+
const lat1 = (_lat1 * Math.PI) / 180;
|
|
6
|
+
const lat2 = (_lat2 * Math.PI) / 180;
|
|
7
|
+
const long1 = (_long1 * Math.PI) / 180;
|
|
8
|
+
const long2 = (_long2 * Math.PI) / 180;
|
|
9
|
+
const cl1 = Math.cos(lat1);
|
|
10
|
+
const cl2 = Math.cos(lat2);
|
|
11
|
+
const sl1 = Math.sin(lat1);
|
|
12
|
+
const sl2 = Math.sin(lat2);
|
|
13
|
+
const delta = long2 - long1;
|
|
14
|
+
const cdelta = Math.cos(delta);
|
|
15
|
+
const sdelta = Math.sin(delta);
|
|
16
|
+
const y = Math.sqrt(((cl2 * sdelta) ** 2) + (((cl1 * sl2) - (sl1 * cl2 * cdelta)) ** 2));
|
|
17
|
+
const x = (sl1 * sl2) + (cl1 * cl2 * cdelta);
|
|
18
|
+
const ad = Math.atan2(y, x);
|
|
19
|
+
const distance = (ad * R) / 1000;
|
|
20
|
+
/* eslint-disable no-restricted-globals */
|
|
21
|
+
return isNaN(distance) ? -1 : Number(distance.toFixed(2));
|
|
22
|
+
};
|
package/lib/index.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './
|
|
11
|
-
export * from './
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './
|
|
14
|
-
export * from './
|
|
15
|
-
export * from './
|
|
16
|
-
export * from './
|
|
17
|
-
export * from './
|
|
18
|
-
export * from './urls';
|
|
19
|
-
export * from './xml';
|
|
1
|
+
export * from './array';
|
|
2
|
+
export * from './date';
|
|
3
|
+
export * from './crypto';
|
|
4
|
+
export * from './resources/l10n';
|
|
5
|
+
export * from './func/nextId';
|
|
6
|
+
export * from './func/curry';
|
|
7
|
+
export * from './func/noop';
|
|
8
|
+
export * from './func/identity';
|
|
9
|
+
export * from './func/fx';
|
|
10
|
+
export * from './object';
|
|
11
|
+
export * from './string';
|
|
12
|
+
export * from './parsing/scalarParse';
|
|
13
|
+
export * from './parsing/codus';
|
|
14
|
+
export * from './parsing/compiler';
|
|
15
|
+
export * from './parsing/urls';
|
|
16
|
+
export * from './parsing/xml';
|
|
17
|
+
export * from './support/createListeners';
|
|
@@ -24,14 +24,19 @@ export const isEmpty = (x: unknown): boolean => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
// data structures
|
|
27
|
-
export const dot = (x: any, k: string) => (x ? x[k] : null);
|
|
28
|
-
export const keysOf = (x: any) => x ? Object.keys(x) : null;
|
|
29
|
-
export const valuesOf = (x: any) => x ? Object.keys(x
|
|
27
|
+
export const dot = (x: any, k: string = 'name') => (x ? x[k] : null);
|
|
28
|
+
export const keysOf = (x: any) => (x ? Object.keys(x) : null);
|
|
29
|
+
export const valuesOf = (x: any) => (x ? Object.keys(x) : null);
|
|
30
30
|
|
|
31
31
|
export const assignKeyValue = (o: Obj, key: string, value: unknown): object => {
|
|
32
32
|
return Object.assign(o || {}, { [key]: value });
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
export const assignFirstArgKeyValue =
|
|
36
|
+
(fn: (...args: unknown[]) => unknown, key: string, val: unknown) =>
|
|
37
|
+
(x: object, ...args: unknown[]) =>
|
|
38
|
+
fn.call(null, Object.assign(x || {}, { [key]: val }), ...args.slice(1));
|
|
39
|
+
|
|
35
40
|
export const pack = (x?: unknown, key = 'value'): object => {
|
|
36
41
|
return { [key]: x };
|
|
37
42
|
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { scalarParse } from './
|
|
1
|
+
import { scalarParse } from './scalarParse';
|
|
2
2
|
|
|
3
3
|
const RE_ATTRS = /([a-z][a-zA-Z0-9-:]+)(="[^"]*"|={[^}]*})?/g;
|
|
4
4
|
const RE_EMPTY = /^\s*$/;
|
|
@@ -6,7 +6,7 @@ const RE_XML_COMMENT = /<!--((?!-->)[\s\S])*-->/g;
|
|
|
6
6
|
const RE_XML_TAG = /(<)(\/?)([a-zа-я][a-zа-я0-9-:]*)((?:\s+[a-z][a-z0-9-:]+(?:="[^"]*"|={[^}]*})?)*)\s*(\/?)>/gi;
|
|
7
7
|
const SINGLE_TAGS = { img: 1, input: 1, br: 1, col: 1 };
|
|
8
8
|
|
|
9
|
-
const RE_XML_ENTITY = /&#?[0-9a-z]{
|
|
9
|
+
const RE_XML_ENTITY = /&#?[0-9a-z]{2,5};/g;
|
|
10
10
|
|
|
11
11
|
const SUBST_XML_ENTITY: Record<string, string> = {
|
|
12
12
|
amp: '&',
|
|
@@ -34,7 +34,7 @@ const FN_XML_ENTITY = function (s0: string) {
|
|
|
34
34
|
|
|
35
35
|
export const skipQoutes = (s: string) => (s[0] === '"' && s[s.length - 1] === '"' ? s.slice(1, -1) : s);
|
|
36
36
|
|
|
37
|
-
export const decodeXmlEntities = (s
|
|
37
|
+
export const decodeXmlEntities = (s?: string) => String(s || '').replace(RE_XML_ENTITY, FN_XML_ENTITY);
|
|
38
38
|
|
|
39
39
|
const addNode = (c: XmlNode, tag: string) => {
|
|
40
40
|
const node: XmlNode = { tag };
|
|
File without changes
|
|
File without changes
|
|
@@ -27,7 +27,7 @@ export const strEnhance = (x: string, template: string) => {
|
|
|
27
27
|
return !x ? '' : `${template || '*'}`.replace('*', x);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export const tail = (x: string, sep = '
|
|
30
|
+
export const tail = (x: string, sep = ' ') => {
|
|
31
31
|
if (!x) {
|
|
32
32
|
return '';
|
|
33
33
|
}
|
|
@@ -35,7 +35,7 @@ export const tail = (x: string, sep = '.') => {
|
|
|
35
35
|
return pos === -1 ? x : x.slice(pos + sep.length);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
export const head = (x: string, sep = '
|
|
38
|
+
export const head = (x: string, sep = ' ') => {
|
|
39
39
|
if (!x) {
|
|
40
40
|
return '';
|
|
41
41
|
}
|
|
@@ -49,24 +49,6 @@ export const mirror = (x: string) =>
|
|
|
49
49
|
.split('')
|
|
50
50
|
.reduce((r, c) => c + r, '');
|
|
51
51
|
|
|
52
|
-
/* Simple hash function. */
|
|
53
|
-
export const hash = (s: string) => {
|
|
54
|
-
let a = 1,
|
|
55
|
-
c = 0,
|
|
56
|
-
h,
|
|
57
|
-
o;
|
|
58
|
-
if (s) {
|
|
59
|
-
a = 0;
|
|
60
|
-
for (h = s.length - 1; h >= 0; h--) {
|
|
61
|
-
o = s.charCodeAt(h);
|
|
62
|
-
a = ((a << 6) & 268435455) + o + (o << 14);
|
|
63
|
-
c = a & 266338304;
|
|
64
|
-
a = c !== 0 ? a ^ (c >> 21) : a;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return String(a);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
52
|
export function padLeft(x: string | number, size = 2, fill = '0') {
|
|
71
53
|
let s = str(x);
|
|
72
54
|
while (s.length < size) {
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arrmatura",
|
|
3
|
-
"version": "5.0
|
|
4
|
-
"description": "framework",
|
|
3
|
+
"version": "5.2.0",
|
|
4
|
+
"description": "reactive web ui framework",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"start": "npx webpack-dev-server --hot --contentBase docs",
|
|
7
|
-
"build": "npx webpack-cli --mode production
|
|
8
|
-
"
|
|
9
|
-
"release": "npx webpack-cli && npm publish"
|
|
6
|
+
"start": "npx webpack-dev-server --hot --contentBase docs --config webpack.config.js",
|
|
7
|
+
"build": "npx webpack-cli --mode production",
|
|
8
|
+
"serve": "npx http-server ./docs",
|
|
9
|
+
"release": "npx webpack-cli && npm publish",
|
|
10
|
+
"pull": "./tools/pull.sh"
|
|
10
11
|
},
|
|
11
12
|
"repository": {
|
|
12
13
|
"type": "git",
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { Service } from '../services/Service';
|
|
2
|
-
import { analyzeDataByTags, getSuggestions, Item } from './Item';
|
|
3
|
-
import { arraySortBy } from 'arraySortBy';
|
|
4
|
-
|
|
5
|
-
export class ItemCollection extends Service {
|
|
6
|
-
selection: Hash = {};
|
|
7
|
-
shownLimit = 50;
|
|
8
|
-
sortBy = '-ts';
|
|
9
|
-
kluqPoshuku = '';
|
|
10
|
-
data?: Item[];
|
|
11
|
-
inputKluqPoshuku: any;
|
|
12
|
-
newEntry: any;
|
|
13
|
-
entry: any;
|
|
14
|
-
initials = '';
|
|
15
|
-
|
|
16
|
-
setData(data: Hash[]) {
|
|
17
|
-
this.data = !data ? [] : data.filter((e) => e.status !== 'deleted').map((e) => new Item(e));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
getInfo() {
|
|
21
|
-
if (!this.data) {
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
const searchedData = !this.kluqPoshuku
|
|
25
|
-
? this.data
|
|
26
|
-
: this.data.filter((e) => e.$searchData.includes(this.kluqPoshuku));
|
|
27
|
-
const { actualData, tags } = analyzeDataByTags(searchedData, this.selection, this.initials);
|
|
28
|
-
const sortedData = arraySortBy(actualData, this.sortBy);
|
|
29
|
-
return {
|
|
30
|
-
tags: tags.sort((a, b) => (a.selected === b.selected ? (a.id > b.id ? 1 : -1) : !a.selected ? 1 : -1)),
|
|
31
|
-
data: sortedData.slice(0, this.shownLimit),
|
|
32
|
-
openEntry: ({ id }) =>
|
|
33
|
-
this.emit(
|
|
34
|
-
'this.openEntry',
|
|
35
|
-
this.data?.find((e) => e.id === id)
|
|
36
|
-
),
|
|
37
|
-
counts: {
|
|
38
|
-
total: this.data.length,
|
|
39
|
-
actual: actualData.length,
|
|
40
|
-
hasMore: this.shownLimit < actualData.length,
|
|
41
|
-
},
|
|
42
|
-
search: {
|
|
43
|
-
kluq: this.kluqPoshuku,
|
|
44
|
-
value: this.inputKluqPoshuku,
|
|
45
|
-
suggestions:
|
|
46
|
-
this.kluqPoshuku === this.inputKluqPoshuku ? null : getSuggestions(this.data, this.inputKluqPoshuku),
|
|
47
|
-
input: (data) => this.emit('this.inputKluq', data),
|
|
48
|
-
enter: (data) => this.emit('this.znajdzPoKluqu', data),
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
onTag({ id }, { selection }: this) {
|
|
54
|
-
return {
|
|
55
|
-
selection: !id
|
|
56
|
-
? {}
|
|
57
|
-
: {
|
|
58
|
-
...selection,
|
|
59
|
-
[id]: !selection[id],
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
onZnajdzPoKluqu({ value }) {
|
|
65
|
-
return {
|
|
66
|
-
inputKluqPoshuku: value || '',
|
|
67
|
-
kluqPoshuku: value || '',
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
onInputKluq({ value }) {
|
|
71
|
-
return {
|
|
72
|
-
inputKluqPoshuku: value || '',
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
onSortBy({ value }) {
|
|
76
|
-
return {
|
|
77
|
-
sortBy: value || '-ts',
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
onShowMore({ size = 50 }, { shownLimit = 50 }) {
|
|
81
|
-
return {
|
|
82
|
-
shownLimit: shownLimit + size,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* New Entry
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
onOpenAddNew(data) {
|
|
90
|
-
return {
|
|
91
|
-
newEntry: {
|
|
92
|
-
...data,
|
|
93
|
-
...this.newEntry,
|
|
94
|
-
cancel: () => this.emit('this.cancelAddNew'),
|
|
95
|
-
submit: (data) => this.emit('this.saveNew', data),
|
|
96
|
-
open: true,
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
onCancelAddNew() {
|
|
102
|
-
return {
|
|
103
|
-
newEntry: { ...this.newEntry, open: false },
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async onSaveNew(data) {
|
|
108
|
-
delete data.id;
|
|
109
|
-
await this.upsert(data);
|
|
110
|
-
return {
|
|
111
|
-
newEntry: { ...this.newEntry, data, open: false },
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
upsert(data: any) {
|
|
115
|
-
throw new Error('Method not implemented.');
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Entry
|
|
119
|
-
*/
|
|
120
|
-
|
|
121
|
-
onOpenEntry(data) {
|
|
122
|
-
return {
|
|
123
|
-
entry: {
|
|
124
|
-
id: data.id,
|
|
125
|
-
data: Object.entries(data).reduce((r, [k, v]) => {
|
|
126
|
-
if (k[0] !== '$') {
|
|
127
|
-
r[k] = v;
|
|
128
|
-
}
|
|
129
|
-
return r;
|
|
130
|
-
}, {}),
|
|
131
|
-
...this.entry,
|
|
132
|
-
cancel: () => this.emit('this.cancelEntry'),
|
|
133
|
-
submit: (data) => this.emit('this.saveEntry', data),
|
|
134
|
-
delete: () => this.emit('this.deleteEntry', { id: data.id }),
|
|
135
|
-
open: true,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
onCancelEntry() {
|
|
141
|
-
return { entry: { open: false } };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async onSaveEntry(data) {
|
|
145
|
-
await this.upsert(data);
|
|
146
|
-
return { entry: { open: false } };
|
|
147
|
-
}
|
|
148
|
-
async onDeleteEntry(data) {
|
|
149
|
-
await this.upsert({ ...data, status: 'deleted' });
|
|
150
|
-
return { entry: { open: false } };
|
|
151
|
-
}
|
|
152
|
-
}
|