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.
Files changed (81) hide show
  1. package/commons/auth/AuthService.ts +111 -0
  2. package/commons/auth/UserService.ts +28 -78
  3. package/commons/auth/index.ts +4 -3
  4. package/commons/auth/user.xml +18 -20
  5. package/commons/components/buttons.xml +6 -4
  6. package/commons/components/layouts.xml +8 -8
  7. package/commons/components/modal.xml +4 -4
  8. package/commons/components/navigation.xml +21 -7
  9. package/commons/components/searchbar.xml +36 -22
  10. package/commons/components/table.xml +25 -5
  11. package/commons/components/toasts.xml +10 -5
  12. package/commons/forms/FormController.ts +48 -34
  13. package/commons/forms/Item.ts +93 -29
  14. package/commons/forms/ItemCollectionController.ts +113 -0
  15. package/commons/forms/ItemController.ts +50 -21
  16. package/commons/forms/NewItemController.ts +46 -0
  17. package/commons/forms/SmartareaField.xml +3 -3
  18. package/commons/forms/SuggestionField.xml +3 -3
  19. package/commons/forms/fields.xml +28 -15
  20. package/commons/forms/form.xml +3 -3
  21. package/commons/forms/index.ts +4 -4
  22. package/commons/index.ts +2 -2
  23. package/commons/services/ApiClientService.ts +32 -0
  24. package/commons/services/GSheetsService.ts +92 -64
  25. package/commons/services/Invoke.ts +24 -8
  26. package/commons/services/JsonpService.ts +1 -1
  27. package/commons/services/MetadataService.ts +50 -0
  28. package/commons/services/NavigationService.ts +20 -1
  29. package/commons/services/Service.ts +22 -28
  30. package/commons/services/Storage.ts +55 -0
  31. package/commons/services/ToastService.ts +16 -4
  32. package/commons/services/index.ts +3 -4
  33. package/core/Arrmatura.ts +4 -9
  34. package/core/CNode.ts +1 -2
  35. package/core/Component.ts +29 -31
  36. package/core/cnodes/conditionals.ts +3 -2
  37. package/core/expression.ts +1 -1
  38. package/core/register.ts +1 -1
  39. package/core/utils.ts +1 -3
  40. package/core-web/attributes.ts +38 -10
  41. package/core-web/elements.ts +22 -4
  42. package/core-web/index.ts +14 -2
  43. package/core-web/reflow.ts +3 -1
  44. package/core-web/support.ts +27 -0
  45. package/docs/index.js +350 -66
  46. package/lib/{arrayGroupBy.ts → array/arrayGroupBy.ts} +1 -1
  47. package/lib/{arraySortBy.ts → array/arraySortBy.ts} +5 -5
  48. package/lib/{arrayToObject.ts → array/arrayToObject.ts} +0 -0
  49. package/lib/array/arrayish.ts +7 -0
  50. package/lib/array/index.ts +4 -0
  51. package/lib/crypto/index.ts +25 -0
  52. package/lib/{dateFormat.ts → date/index.ts} +61 -3
  53. package/lib/func/curry.ts +11 -0
  54. package/lib/{fx.ts → func/fx.ts} +32 -38
  55. package/lib/{noop.ts → func/identity.ts} +1 -3
  56. package/lib/{nextId.ts → func/nextId.ts} +0 -0
  57. package/lib/func/noop.ts +6 -0
  58. package/lib/geo/index.js +22 -0
  59. package/lib/index.ts +17 -19
  60. package/lib/{obj.ts → object/index.ts} +8 -3
  61. package/lib/{codus.ts → parsing/codus.ts} +1 -1
  62. package/lib/{predicat.ts → parsing/compiler.ts} +0 -0
  63. package/lib/{scalar.ts → parsing/scalarParse.ts} +0 -0
  64. package/lib/{urls.ts → parsing/urls.ts} +0 -0
  65. package/lib/{xml.ts → parsing/xml.ts} +3 -3
  66. package/lib/{l10n.ts → resources/l10n.ts} +2 -2
  67. package/lib/{resources.ru.ts → resources/resources.ru.ts} +0 -0
  68. package/lib/{resources.ts → resources/resources.ts} +0 -0
  69. package/lib/{str.ts → string/index.ts} +2 -20
  70. package/lib/{createListeners.ts → support/createListeners.ts} +0 -0
  71. package/package.json +7 -6
  72. package/commons/forms/ItemCollection.ts +0 -152
  73. package/commons/forms/MetadataService.ts +0 -45
  74. package/commons/pipes/index.ts +0 -21
  75. package/commons/pipes/showCounts.ts +0 -16
  76. package/commons/services/LocalStorage.ts +0 -46
  77. package/lib/consts.ts +0 -3
  78. package/lib/curry.ts +0 -8
  79. package/lib/dateOf.ts +0 -31
  80. package/lib/dateParseISO8601.ts +0 -27
  81. package/lib/guid.ts +0 -7
@@ -1,4 +1,4 @@
1
- import { gettus } from 'obj';
1
+ import { gettus } from '../object';
2
2
 
3
3
  type GroupOf<T> = { id: string; count: number; items: T[] };
4
4
 
@@ -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[fn];
29
- const bb = b[fn];
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: Comparable[],
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 (arr || []).slice(0).sort(sortByComparator(property, order));
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,4 @@
1
+ export * from './arrayGroupBy';
2
+ export { arraySortBy } from './arraySortBy';
3
+ export * from './arrayToObject';
4
+ export * from './arrayish';
@@ -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 { dateOf } from 'dateOf';
2
- import { t } from 'l10n';
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);
@@ -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
- export const compose =
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));
@@ -1,8 +1,6 @@
1
1
  /**
2
- * The `identity` function.
2
+ * The `identity/Totus` function.
3
3
  *
4
4
  * @returns input parameter `as is`
5
5
  */
6
- export const noop = () => undefined;
7
-
8
6
  export const identity = <T = unknown>(e: T): T => e;
File without changes
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The `noop/Dzirka` function.
3
+ *
4
+ * @returns undefined
5
+ */
6
+ export const noop = () => undefined;
@@ -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 './arrayGroupBy';
2
- export { arraySortBy } from './arraySortBy';
3
- export * from './arrayToObject';
4
- export * from './createListeners';
5
- export * from './curry';
6
- export * from './dateFormat';
7
- export * from './dateOf';
8
- export * from './dateParseISO8601';
9
- export * from './codus';
10
- export * from './fx';
11
- export * from './guid';
12
- export * from './l10n';
13
- export * from './nextId';
14
- export * from './noop';
15
- export * from './obj';
16
- export * from './scalar';
17
- export * from './str';
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 ): null;
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
  };
@@ -1,4 +1,4 @@
1
- import { scalarParse } from 'scalar';
1
+ import { scalarParse } from './scalarParse';
2
2
 
3
3
  export const decodus = (val: string): unknown => {
4
4
  if (!val) return undefined;
File without changes
File without changes
File without changes
@@ -1,4 +1,4 @@
1
- import { scalarParse } from './scalar';
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]{3,5};/g;
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 = '') => s.replace(RE_XML_ENTITY, FN_XML_ENTITY);
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 };
@@ -1,5 +1,5 @@
1
- import en from 'resources';
2
- import ru from 'resources.ru';
1
+ import en from './resources';
2
+ import ru from './resources.ru';
3
3
 
4
4
  const R = { en, ru };
5
5
 
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) {
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "arrmatura",
3
- "version": "5.0.4",
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 && cp -fv docs/quiz.js public",
8
- "deploy:host": "firebase use ${NODE_ENV:-default} && firebase deploy --only hosting",
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
- }