arrmatura 5.2.0 → 6.2.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.
Files changed (110) hide show
  1. package/index.ts +20 -0
  2. package/package.json +14 -44
  3. package/src/core/composition.ts +71 -0
  4. package/src/core/conditionals.ts +80 -0
  5. package/src/core/elementary.ts +40 -0
  6. package/src/core/fragment.ts +21 -0
  7. package/src/core/index.ts +19 -0
  8. package/src/core/iterations.ts +121 -0
  9. package/src/core/root.ts +46 -0
  10. package/src/core/routing.ts +37 -0
  11. package/src/core/selection.ts +57 -0
  12. package/src/core/slot.ts +36 -0
  13. package/src/ctx/Ctx.ts +424 -0
  14. package/src/ctx/CtxNode.ts +159 -0
  15. package/src/utils/compileExpression.ts +126 -0
  16. package/src/utils/stringify.ts +39 -0
  17. package/LICENSE +0 -21
  18. package/README.md +0 -54
  19. package/commons/auth/AuthService.ts +0 -111
  20. package/commons/auth/UserService.ts +0 -57
  21. package/commons/auth/index.ts +0 -5
  22. package/commons/auth/user.xml +0 -64
  23. package/commons/components/buttons.xml +0 -25
  24. package/commons/components/index.ts +0 -13
  25. package/commons/components/inputs.xml +0 -33
  26. package/commons/components/layouts.xml +0 -77
  27. package/commons/components/media.xml +0 -21
  28. package/commons/components/modal.xml +0 -37
  29. package/commons/components/navigation.xml +0 -73
  30. package/commons/components/popups.xml +0 -12
  31. package/commons/components/searchbar.xml +0 -54
  32. package/commons/components/table.xml +0 -140
  33. package/commons/components/toasts.xml +0 -18
  34. package/commons/components/viewport.xml +0 -48
  35. package/commons/forms/FieldItem.xml +0 -20
  36. package/commons/forms/FormController.ts +0 -87
  37. package/commons/forms/Item.ts +0 -132
  38. package/commons/forms/ItemCollectionController.ts +0 -113
  39. package/commons/forms/ItemController.ts +0 -91
  40. package/commons/forms/MultiEnumField.xml +0 -44
  41. package/commons/forms/MultivalueController.ts +0 -49
  42. package/commons/forms/NewItemController.ts +0 -46
  43. package/commons/forms/SmartareaField.xml +0 -51
  44. package/commons/forms/SuggestionController.ts +0 -80
  45. package/commons/forms/SuggestionField.xml +0 -28
  46. package/commons/forms/fields.xml +0 -151
  47. package/commons/forms/form.xml +0 -37
  48. package/commons/forms/index.ts +0 -29
  49. package/commons/index.ts +0 -6
  50. package/commons/services/ApiClientService.ts +0 -32
  51. package/commons/services/ErrorHandlingService.ts +0 -11
  52. package/commons/services/FirebaseService.ts +0 -185
  53. package/commons/services/GSheetsService.ts +0 -120
  54. package/commons/services/HeartbeatService.ts +0 -35
  55. package/commons/services/Invoke.ts +0 -29
  56. package/commons/services/JsonpService.ts +0 -18
  57. package/commons/services/Loader.ts +0 -17
  58. package/commons/services/MetadataService.ts +0 -50
  59. package/commons/services/NavigationService.ts +0 -74
  60. package/commons/services/Service.ts +0 -62
  61. package/commons/services/ServiceWorker.ts +0 -111
  62. package/commons/services/Storage.ts +0 -55
  63. package/commons/services/ToastService.ts +0 -61
  64. package/commons/services/index.ts +0 -13
  65. package/core/Arrmatura.ts +0 -79
  66. package/core/CNode.ts +0 -111
  67. package/core/Component.ts +0 -424
  68. package/core/cnodes/composition.ts +0 -100
  69. package/core/cnodes/conditionals.ts +0 -52
  70. package/core/cnodes/elementary.ts +0 -44
  71. package/core/cnodes/iterations.ts +0 -92
  72. package/core/cnodes/routing.ts +0 -25
  73. package/core/compileNode.ts +0 -39
  74. package/core/expression.ts +0 -73
  75. package/core/index.ts +0 -1
  76. package/core/register.ts +0 -43
  77. package/core/utils.ts +0 -23
  78. package/core-web/WebPlatform.ts +0 -25
  79. package/core-web/attributes.ts +0 -218
  80. package/core-web/elements.ts +0 -81
  81. package/core-web/index.ts +0 -28
  82. package/core-web/reflow.ts +0 -30
  83. package/core-web/support.ts +0 -27
  84. package/core-web/type.ts +0 -18
  85. package/docs/index.js +0 -485
  86. package/lib/array/arrayGroupBy.ts +0 -19
  87. package/lib/array/arraySortBy.ts +0 -49
  88. package/lib/array/arrayToObject.ts +0 -18
  89. package/lib/array/arrayish.ts +0 -7
  90. package/lib/array/index.ts +0 -4
  91. package/lib/crypto/index.ts +0 -25
  92. package/lib/date/index.ts +0 -127
  93. package/lib/func/curry.ts +0 -11
  94. package/lib/func/fx.ts +0 -56
  95. package/lib/func/identity.ts +0 -6
  96. package/lib/func/nextId.ts +0 -9
  97. package/lib/func/noop.ts +0 -6
  98. package/lib/geo/index.js +0 -22
  99. package/lib/index.ts +0 -17
  100. package/lib/object/index.ts +0 -69
  101. package/lib/parsing/codus.ts +0 -25
  102. package/lib/parsing/compiler.ts +0 -26
  103. package/lib/parsing/scalarParse.ts +0 -25
  104. package/lib/parsing/urls.ts +0 -91
  105. package/lib/parsing/xml.ts +0 -117
  106. package/lib/resources/l10n.ts +0 -40
  107. package/lib/resources/resources.ru.ts +0 -20
  108. package/lib/resources/resources.ts +0 -20
  109. package/lib/string/index.ts +0 -58
  110. package/lib/support/createListeners.ts +0 -12
@@ -1,91 +0,0 @@
1
- import { Service } from '../services/Service';
2
- import { Item } from './Item';
3
- import { getPredicat } from '../../lib';
4
-
5
- const CHANGES: Hash<Hash> = {};
6
- export class ItemController extends Service {
7
- all?: Hash<Hash>;
8
- itemId: string = '';
9
- meta: any;
10
- context: any;
11
-
12
- get initialElement() {
13
- return Array.isArray(this.all) ? this.all.find((e) => e.id == this.itemId) : this.all?.[this.itemId];
14
- }
15
- get initialData() {
16
- const e = this.initialElement;
17
- return !e?.id ? null : e.$dataset;
18
- }
19
-
20
- get actualData() {
21
- const initial = this.initialData;
22
- if (!initial) {
23
- return null;
24
- }
25
- const data = { ...this.context, ...initial, ...CHANGES[this.itemId] };
26
- this.meta?.map((field: { [k: string]: string }) => {
27
- const { id, visible } = field;
28
- const isVisible = !visible || getPredicat(visible)(data);
29
- if (!isVisible && data[id]) {
30
- data[id] = '';
31
- }
32
- });
33
- return data;
34
- }
35
-
36
- get item() {
37
- return new Item(this.actualData || {});
38
- }
39
-
40
- get itemNavInfo() {
41
- return { prev: null, next: null, ...this.initialElement?.$navInfo };
42
- }
43
-
44
- get itemTitle() {
45
- return this.initialElement?.title;
46
- }
47
-
48
- get touched() {
49
- return !!CHANGES[this.itemId];
50
- }
51
-
52
- upsert(data?: Hash): Hash {
53
- throw new Error('upsert not defined.' + data);
54
- }
55
-
56
- async submitData(data: Delta) {
57
- if (!data) return null;
58
-
59
- const { error, lastUpdatedItemId, ...rest } = await this.upsert(data);
60
- console.log(error, rest);
61
- if (error) {
62
- const msg = (error as Error)?.message;
63
- this.toast({ id: msg, mode: 'error', message: 'Error: ' + msg });
64
- return null;
65
- }
66
- delete CHANGES[this.itemId];
67
- this.toast({ message: 'Saved successfully.', timeout: 5000, link: '#/task?itemId=' + lastUpdatedItemId });
68
- return {
69
- counter: NaN,
70
- };
71
- }
72
-
73
- // event handlers:
74
- onChange = (delta: Hash) => {
75
- CHANGES[this.itemId] = { ...CHANGES[this.itemId], ...delta };
76
- return {
77
- counter: NaN,
78
- };
79
- };
80
-
81
- onSave() {
82
- return this.submitData(this.actualData);
83
- }
84
-
85
- onDelete() {
86
- const { id } = this.initialElement?.id;
87
- if (!id) return null;
88
-
89
- return this.submitData({ id, status: 'deleted' });
90
- }
91
- }
@@ -1,44 +0,0 @@
1
- <component id="MultiEnumAppender">
2
- <div class="form-autocomplete" ui:if="options">
3
- <div class="has-icon-right" click="{toggle}">
4
- <div class="form-input text-gray">{placeholder}</div>
5
- <i class="form-icon icon icon-{opened|then:arrow-up:plus} c-hand"></i>
6
- </div>
7
- <Modal open="{opened}" mode="sm" close="{toggle}">
8
- <Modal:header>
9
- <h6>{caption}</h6>
10
- </Modal:header>
11
- <div style="overflow-y: auto;height:15rem;margin:0;">
12
- <ul class="menu2" style="min-width: 180px;list-style: none;">
13
- <li class="menu-item" ui:for="option of options" click="-> ctrl.insert|assignKeyValue:value:@option.id">
14
- <a>
15
- <div class="tile tile-centered">
16
- <div class="tile-content">🔸 {option.name|or:@option.id}</div>
17
- </div>
18
- </a>
19
- </li>
20
- </ul>
21
- </div>
22
- <!-- <Modal:footer>
23
- <Btn class="float-right" mode="primary" title="OK" action="{toggle}"/>
24
- </Modal:footer> -->
25
- </Modal>
26
- </div>
27
- </component>
28
-
29
- <component id="MultiEnumField">
30
- <FieldItem caption="{caption}" class={class} error="{error}" required="{required}" hint="{hint}">
31
-
32
- <MultivalueController ui:ref="ctrl" value="{value}" options="{options}" change="{onChange}"/>
33
-
34
- <div class="mb-1 has-icon-right" ui:for="item of <-ctrl.items">
35
- <div class="form-input" style="height: auto; min-height: 1.5rem;">
36
- <div class="">{item.name}</div>
37
- <i class="form-icon icon icon-cross p-2 c-hand" click="-> ctrl.delete|assignKeyValue:value:@item.id" ui:if="disabled|not"></i>
38
- </div>
39
- </div>
40
-
41
- <MultiEnumAppender caption="➕ {caption}" placeholder="{placeholder}" options="<-ctrl.availableOptions" opened="<-ctrl.opened" toggle="->ctrl.toggleOpened" ui:if="disabled|not"/>
42
-
43
- </FieldItem>
44
- </component>
@@ -1,49 +0,0 @@
1
- import { arrayToObject } from '../../lib';
2
- import { Service } from '../services/Service';
3
-
4
- export class MultivalueController extends Service {
5
- value: string = '';
6
- options: any;
7
- optionsHash?: Data;
8
-
9
- get items() {
10
- return this.bits.map((id) => ({ id, name: this.optionsHash?.[id]?.name || id }));
11
- }
12
-
13
- get bits() {
14
- return this.value ? this.value.split(',') : [];
15
- }
16
-
17
- setOptions(opts: Obj[]) {
18
- this.optionsHash = arrayToObject(opts);
19
- this.options = opts;
20
- }
21
-
22
- get availableOptions() {
23
- const result = this.options?.filter((e) => !this.value?.includes(e.id));
24
- return result?.length ? result : null;
25
- }
26
-
27
- change(data?: Hash) {
28
- throw new Error('change not defined.' + data);
29
- }
30
-
31
- onToggleOpened(_: never, { opened = false }) {
32
- return { opened: !opened };
33
- }
34
-
35
- onReset() {
36
- this.change({ value: '' });
37
- }
38
-
39
- onInsert({ value = '' }) {
40
- this.change({ value: [...this.bits, value].join(',') });
41
- return { opened: false };
42
- }
43
-
44
- onDelete({ value = '' }) {
45
- this.change({
46
- value: this.bits.filter((e) => e !== value).join(','),
47
- });
48
- }
49
- }
@@ -1,46 +0,0 @@
1
- import { Service } from '../services/Service';
2
-
3
- export class NewItemController extends Service {
4
- data: any;
5
- info: any;
6
-
7
- upsert(_data: any) {
8
- throw new Error('Method not implemented.');
9
- }
10
- async submitData(data: Delta) {
11
- if (!data) return null;
12
-
13
- const { error, lastUpdatedItemId, ...rest } = await this.upsert(data);
14
- console.log(error, rest);
15
- if (error) {
16
- const msg = (error as Error)?.message;
17
- this.toast({ id: msg, mode: 'error', message: 'Error: ' + msg });
18
- return null;
19
- }
20
-
21
- this.toast({ message: 'Added successfully. ', timeout: 5000, link: '#/task?itemId=' + lastUpdatedItemId });
22
- return {
23
- info: { open: false, data: {} },
24
- };
25
- }
26
- // event handlers:
27
-
28
- onOpenAddNew() {
29
- return {
30
- info: {
31
- data: this.data,
32
- open: true,
33
- },
34
- };
35
- }
36
-
37
- onCancel() {
38
- return {
39
- info: { open: false },
40
- };
41
- }
42
-
43
- onSubmit(data: Delta) {
44
- return this.submitData(data);
45
- }
46
- }
@@ -1,51 +0,0 @@
1
- <component id="Smartarea">
2
- <div class="form-autocomplete" ui:if="options">
3
-
4
- <ui:fragment ui:if="disabled">
5
- <ui:then>
6
- <div class="form-input" style="height: auto;min-height:1.5rem;">{value}</div>
7
- </ui:then>
8
- <ui:else>
9
- <div class="has-icon-right" click="{open|fnBindArgs:true}">
10
- <div class="form-input text-{value|then::gray}" style="height: auto;min-height:1.5rem;">{value|or:@placeholder}</div>
11
- <i class="form-icon icon icon-edit c-hand"></i>
12
- </div>
13
- </ui:else>
14
- </ui:fragment>
15
-
16
- <Modal open="{opened}" mode="sm" ui:if="{opened}" close="{open|fnBindArgs:false}">
17
- <Modal:header>
18
- <h6>{caption}</h6>
19
- </Modal:header>
20
-
21
- <div class="form-autocomplete">
22
- <div class="has-icon-right">
23
- <textarea class="form-input" style="padding-right: 3rem;height:6rem;" keypress="{change}" value="{value}" />
24
- <i class="form-icon icon icon-{value|then:cross:arrow-down} c-hand" click="{reset}" ui:if="value"></i>
25
- </div>
26
- <div style="overflow-y: auto;height:15rem;margin:0.5rem 0;">
27
- <ul class="menu2" style="min-width: 180px;list-style: none;">
28
- <li class="menu-item" ui:for="item of options" data-value="{item.id}" click="{append}">
29
- <a>
30
- <div class="tile tile-centered">
31
- <div class="tile-content">🏷️ {item.name|or:@item.id}</div>
32
- </div>
33
- </a>
34
- </li>
35
- </ul>
36
- </div>
37
- </div>
38
-
39
- <Modal:footer>
40
- <Btn class="float-right" mode="primary" title="OK" action="{open|fnBindArgs:false}"/>
41
- </Modal:footer>
42
- </Modal>
43
- </div>
44
- </component>
45
-
46
- <component id="SmartareaField">
47
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
48
- <SuggestionController ui:ref="ctrl" options="{options}" value="{value}" change="{onChange}"/>
49
- <Smartarea caption="{caption}" disabled="{disabled}" options="<-ctrl.smartOptions" value="{value}" disabled="{disabled}" opened="{opened}" open="->opened" placeholder="{placeholder}" change="->ctrl.change" append="->ctrl.append" reset="->ctrl.cutLast"/>
50
- </FieldItem>
51
- </component>
@@ -1,80 +0,0 @@
1
- import { Service } from '../services/Service';
2
-
3
- export class SuggestionController extends Service {
4
- value: string = '';
5
- options: any;
6
-
7
- get bits() {
8
- return this.value
9
- ? this.value
10
- .split(',')
11
- .map((s) => s.trim())
12
- .filter(Boolean)
13
- : [];
14
- }
15
-
16
- get lastBitIncluded() {
17
- let bits = this.bits;
18
- if (!bits.length) return false;
19
- const lastBit = bits[bits.length - 1] || '';
20
- return this.options.some((e) => e.id === lastBit);
21
- }
22
-
23
- get smartOptions() {
24
- let options = this.options;
25
- let bits = this.bits;
26
- if (!bits.length) return options;
27
- const lastBit = bits[bits.length - 1] || '';
28
- if (lastBit.length > 1 && !this.lastBitIncluded) {
29
- const keyword = lastBit.toLowerCase();
30
- options = options.filter((e) => (e.name || e.id).toLowerCase().includes(keyword));
31
- // if (options2.length) {
32
- // options = options2;
33
- // }
34
- }
35
-
36
- options = options.filter((e) => !bits.includes(e.id));
37
- // if (options2.length === 1 && value === options2[0].id) return null;
38
- return options.slice(0, 15);
39
- }
40
-
41
- get actualOptions() {
42
- const options = this.options;
43
- const value = String(this.value || '');
44
- const keyword = value?.toLowerCase() || '';
45
- if (keyword.length < 2) return options.slice(0, 15);
46
- const options2 = options.filter((e) => (e.name || e.id).toLowerCase().startsWith(keyword));
47
- if (options2.length === 1 && value === options2[0].id) return null;
48
- return options2.slice(0, 15);
49
- }
50
-
51
- change(data?: Hash) {
52
- throw new Error('change not defined.' + data);
53
- }
54
-
55
- onOpen(opened = false) {
56
- return { opened };
57
- }
58
-
59
- onReset() {
60
- this.change({ value: '' });
61
- }
62
-
63
- onAppend({ value = '' }) {
64
- const bits = this.bits;
65
- if (!this.lastBitIncluded) {
66
- bits.pop();
67
- }
68
- this.change({ value: [...bits, value].join(', ') });
69
- }
70
- onCutLast() {
71
- const bits = this.bits;
72
- bits.pop();
73
- this.change({ value: [...bits].join(', ') });
74
- }
75
-
76
- onChange({ value = '' }) {
77
- this.change({ value });
78
- return { opened: false };
79
- }
80
- }
@@ -1,28 +0,0 @@
1
- <component id="SuggestionInput">
2
- <div class="form-autocomplete">
3
- <div class="has-icon-right">
4
- <input class="form-input" type="text" disabled="{disabled}" placeholder="{placeholder}" focus="{open|fnBindArgs:true}" blur2="{open|fnBindArgs:false|fnTick:200}" keypress="{change}" value="{value}" />
5
- <i class="form-icon icon icon-{value|then:cross:arrow-down} c-hand" style="margin-right:{options.length|then:1.5:0.25}rem;" click="{reset}" ui:if="disabled|not|and:@value"></i>
6
- <ui:fragment ui:if="options|and:@options.length">
7
- <i class="form-icon icon icon-arrow-up c-hand" click="{open|fnBindArgs:false}" ui:if="opened"></i>
8
- <i class="form-icon icon icon-arrow-down c-hand" click="{open|fnBindArgs:true}" ui:if="opened|not"></i>
9
- </ui:fragment>
10
- </div>
11
- <ul class="menu" style="position2: relative; min-width: 180px;max-height:7rem;overflow-y:auto;" ui:if="{options|and:@options.length|and:@opened}">
12
- <li class="menu-item" ui:for="item of options" data-value="{item.id}" click="{change}">
13
- <a>
14
- <div class="tile tile-centered">
15
- <div class="tile-content">{item.name|or:@item.id}</div>
16
- </div>
17
- </a>
18
- </li>
19
- </ul>
20
- </div>
21
- </component>
22
-
23
- <component id="SuggestionField">
24
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
25
- <SuggestionController ui:ref="ctrl" options="{options}" value="{value}" change="{onChange}"/>
26
- <SuggestionInput options="<-ctrl.actualOptions" value="{value}" opened="<- ctrl.opened" open="-> ctrl.open" disabled="{disabled}" change="->ctrl.change" append="->ctrl.change" reset="->ctrl.reset"/>
27
- </FieldItem>
28
- </component>
@@ -1,151 +0,0 @@
1
- <component id="Field">
2
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
3
- <input class="form-input" type="text" disabled="{disabled}" placeholder="{placeholder}" value="{value}" change="{onChange}" />
4
- </FieldItem>
5
- </component>
6
-
7
- <component id="TextField">
8
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
9
- <input class="form-input" name="{id}" type="text" disabled="{disabled}" placeholder="{placeholder}" value="{value}" change="{onChange}" />
10
- </FieldItem>
11
- </component>
12
-
13
- <component id="PasswordField">
14
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
15
- <input class="form-input" name="{id}" type="password" disabled="{disabled}" placeholder="{placeholder|or:password}" value="{value}" change="{onChange}" />
16
- </FieldItem>
17
- </component>
18
-
19
- <component id="EmailField">
20
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
21
- <input class="form-input" type="email" disabled="{disabled}" placeholder="{placeholder|or:password}" value="{value}" change="{onChange}" />
22
- </FieldItem>
23
- </component>
24
-
25
- <component id="UrlField">
26
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
27
- <div class="input-group has-icon-right" style="height:2rem;">
28
- <ui:fragment ui:if="{editing}">
29
- <ui:then>
30
- <input class="form-input border-0" disabled="{disabled}" type="url" blur="-> editing|not" placeholder="{placeholder}" value="{value}" change="{onChange}" />
31
- <button class="btn btn-primary input-group-btn" click="-> editing|not">
32
- <i class="icon icon-check"/>
33
- </button>
34
- </ui:then>
35
- <ui:else>
36
- <a class="form-input text-ellipsis" href="{value}" target="{id}" ui:if="value">🔗 {value}</a>
37
- <a class="form-input text-ellipsis" ui:if="value|not">{placeholder|or:-}</a>
38
- <i class="form-icon icon icon-edit c-hand" click="->editing" ui:if="disabled|not"/>
39
- </ui:else>
40
- </ui:fragment>
41
- </div>
42
- </FieldItem>
43
- </component>
44
-
45
- <component id="EmailField">
46
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
47
- <input class="form-input" disabled="{disabled}" type="email" placeholder="{placeholder}" value="{value}" change="{onChange}" />
48
- </FieldItem>
49
- </component>
50
-
51
- <component id="DateField">
52
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
53
- <input class="form-input" disabled="{disabled}" type="date" placeholder="{placeholder}" value="{value}" change="{onChange}" />
54
- </FieldItem>
55
- </component>
56
-
57
- <component id="DateAndWorkingHoursField">
58
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
59
- <div class="d-flex">
60
- <input class="form-input" disabled="{disabled}" type="date" placeholder="{placeholder}" value="{value}" change="{onChange}" />
61
- <Select class="form-select ml-2" disabled="{disabled}" change="{onChange|assignFirstArgKeyValue:key:@typeSpec}" emptyCaption="-" value="{data|dot:@typeSpec}" options=":enums.workingHours" />
62
- </div>
63
- </FieldItem>
64
- </component>
65
-
66
-
67
- <component id="DateAndTimeField">
68
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
69
- <div class="d-flex">
70
- <input class="form-input flex-1" disabled="{disabled}" type="date" placeholder="{placeholder}" value="{value}" change="{onChange}" />
71
- <input class="form-input flex-1 ml-2" disabled="{value|not|or:@disabled}" type="text" value="{data|dot:@typeSpec}" change="{onChange|assignFirstArgKeyValue:key:@typeSpec}" />
72
- </div>
73
- </FieldItem>
74
- </component>
75
-
76
- <component id="DatePeriodField">
77
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
78
- <div class="d-flex">
79
- <input class="form-input flex-1" disabled="{disabled}" type="date" placeholder="{placeholder}" value="{value}" change="{onChange}" />
80
- <input class="form-input flex-1 ml-2" style="min-width: 6rem;" disabled="{value|not|or:@disabled}" type="date" value="{data|dot:@typeSpec}" change="{onChange|assignFirstArgKeyValue:key:@typeSpec}" />
81
- </div>
82
- </FieldItem>
83
- </component>
84
-
85
- <component id="DateTimeField">
86
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
87
- <input class="form-input" disabled="{disabled}" type="datetime-local" placeholder="{placeholder}" value="{value|dateFormat:yyyy-mm-ddTt}" change="{onChange}" />
88
- </FieldItem>
89
- </component>
90
-
91
- <component id="TimeField">
92
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
93
- <input class="form-input" disabled="{disabled}" type="text" placeholder="{placeholder}" value="{value|dateFormat:t}" change="{onChange}" />
94
- </FieldItem>
95
- </component>
96
-
97
- <component id="NumberField">
98
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
99
- <input class="form-input" disabled="{disabled}" type="number" placeholder="{placeholder}" value="{value}" change="{onChange}" />
100
- </FieldItem>
101
- </component>
102
-
103
- <component id="TextareaField">
104
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
105
- <textarea class="form-input" style="min-height: 15vw" disabled="{disabled}" placeholder="{placeholder}" rows="3" change="{onChange}" value="{value}"></textarea>
106
- </FieldItem>
107
- </component>
108
-
109
- <component id="BooleanField">
110
- <div class="form-group">
111
- <div class="col-sm-12 d-flex">
112
- <label class="form-switch">
113
- <span>{caption}</span>
114
- <input type="checkbox" toggle="{onChange}" checked="{value|truthy}" />
115
- <i class="form-icon"></i>
116
- </label>
117
- <div class="border-1 centroid text-secondary s-circle m-1 px-2" style="height:1.3rem; width:1.3rem;" data-value="{showHint|not}" click="->showHint|dot:value" ui:if="{hint}">
118
- <span>?</span>
119
- </div>
120
- </div>
121
- <div class="col-12" ui:if="{showHint}">
122
- <p class="form-input-hint mb-1">{hint}</p>
123
- </div>
124
- </div>
125
- </component>
126
-
127
- <component id="EnumField">
128
- <FieldItem caption="{caption}" class={class} error="{error}" required="{required}" hint="{hint}">
129
- <Select class="form-select" change="{onChange}" value="{value|or:@defaultValue}" options="{options}" emptyCaption="{emptyCaption}" disabled="{disabled}" />
130
- </FieldItem>
131
- </component>
132
-
133
- <component id="SelectField">
134
- <FieldItem caption="{caption}" class="{class}" error="{error}" required="{required}" hint="{hint}">
135
- <Select class="form-select" change="{onChange}" value="{value|or:@defaultValue}" options="{options}" emptyCaption="{emptyCaption}" disabled="{disabled}" />
136
- </FieldItem>
137
- </component>
138
-
139
- <component id="ChoiceField">
140
- <FieldItem caption="{caption}" class="{class}" error="{error}" required="{required}" hint="{hint}">
141
- <div class="btn-group btn-group-block">
142
- <Btn title="{option.name}" class="option-{value}{option.id|equals:@value|then::-other}" mode="{option.id|equals:@value|then:primary}" data="{option.id|pack:value}" action="{onChange}" ui:for="option of options"/>
143
- </div>
144
- </FieldItem>
145
- </component>
146
-
147
- <component id="RadioField">
148
- <FieldItem caption="{caption}" error="{error}" required="{required}" hint="{hint}">
149
- <RadioGroup change="{onChange}" value="{value}" data="{data}" options=":enums.{typeSpec}" disabled="{disabled}" />
150
- </FieldItem>
151
- </component>
@@ -1,37 +0,0 @@
1
- <component id="Forma">
2
- <div autocomplete="off" class="form-horizontal px-2">
3
- <FormController ui:ref="formController" data="{data}" meta="{meta}" change="{change}" />
4
- <ui:tag tag="{field.type|capitalize}Field" ui:props="{field}" ui:if="field.visible" ui:for="field of <-formController.fieldProps" />
5
- </div>
6
- </component>
7
-
8
- <component id="GroupForma">
9
- <div autocomplete="off" class="form-horizontal px-2">
10
- <FormController ui:ref="formController" data="{data}" meta="{meta}" change="{change}" groups="{groups}" />
11
- <FieldGroup ui:props="{group}" ui:for="group of <-formController.fieldsGroups" />
12
- </div>
13
- </component>
14
-
15
- <component id="TabbedForma">
16
- <div autocomplete="off" class="form-horizontal px-2">
17
- <FormController ui:ref="formController" data="{data}" meta="{meta}" change="{change}" tabs="{tabs}" groups="{groups}" />
18
- <TabbedFormaContent ui:props="<-formController.tabsInfo" />
19
- </div>
20
- </component>
21
-
22
- <component id="TabbedFormaContent">
23
- <Tabs items="{tabs}" change="->tabId|dot:id" value="{tabId|or:@initialTab}" ui:if="enabled" />
24
- <div ui:if="tabId|or:@initialTab|equals:@tab.id" ui:for="tab of tabs">
25
- <FieldGroup ui:props="{group}" ui:for="group of tab.items" />
26
- </div>
27
- </component>
28
-
29
- <component id="FieldGroup">
30
- <h6 class="mt-2 pt-2 px-2 text-gray">{name|or:id}</h6>
31
- <div class="panel">
32
- <div class="p-2">
33
- <ui:tag tag="{field.type|capitalize}Field" ui:props="{field}" ui:if="field.visible" ui:for="field of items" />
34
- </div>
35
- </div>
36
- </component>
37
-
@@ -1,29 +0,0 @@
1
- import { FormController } from './FormController';
2
- import { ItemCollectionController } from './ItemCollectionController';
3
- import { NewItemController } from './NewItemController';
4
- import { ItemController } from './ItemController';
5
- import { MultivalueController } from './MultivalueController';
6
- import { SuggestionController } from './SuggestionController';
7
-
8
- import form from './form.xml';
9
- import fields from './fields.xml';
10
-
11
- import SuggestionField from './SuggestionField.xml';
12
- import SmartareaField from './SmartareaField.xml';
13
- import FieldItem from './FieldItem.xml';
14
- import MultiEnumField from './MultiEnumField.xml';
15
-
16
- export default [
17
- form,
18
- fields,
19
- SuggestionField,
20
- SmartareaField,
21
- FieldItem,
22
- MultiEnumField,
23
- FormController,
24
- ItemCollectionController,
25
- NewItemController,
26
- ItemController,
27
- MultivalueController,
28
- SuggestionController,
29
- ];
package/commons/index.ts DELETED
@@ -1,6 +0,0 @@
1
- import components from './components';
2
- import * as services from './services';
3
- import forms from './forms';
4
- import * as auth from './auth';
5
-
6
- export default [...components, ...forms, ...Object.values(auth), ...Object.values(services)];
@@ -1,32 +0,0 @@
1
- import { urlAppendParams } from '../../lib';
2
- import { Service } from './Service';
3
-
4
- export class ApiClientService extends Service {
5
- baseUrl: string = '';
6
- token: string = '';
7
- onTokenExpired?: Procedure;
8
-
9
- post(path: string = '', data: any, options: object) {
10
- return fetch(urlAppendParams(this.baseUrl + path), {
11
- method: 'POST',
12
- mode: 'cors',
13
- redirect: 'follow',
14
- ...options,
15
- body: JSON.stringify({ token: this.token, data }),
16
- })
17
- .then((res) => res.json())
18
- .then(({ error, ...rest }) => {
19
- if (error) {
20
- if (error.code === '401') {
21
- this.onTokenExpired?.();
22
- }
23
- throw error;
24
- }
25
- return rest;
26
- });
27
- }
28
-
29
- onPost({ path, body, options }: { path: string; body: any; options: object }) {
30
- return this.post(path, body, options);
31
- }
32
- }
@@ -1,11 +0,0 @@
1
- import { Service } from './Service';
2
-
3
- export class ErrorHandlingService extends Service {
4
- handleError({ message = '', code, source = {} }) {
5
- this.show({ message: source + ': ' + message, code, mode: 'error' });
6
- }
7
-
8
- show({ message = '', code = '', source }) {
9
- console.error(source + ': ERROR: ', code, message);
10
- }
11
- }