@social-mail/social-mail-client 1.2.215 → 1.2.217

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 (98) hide show
  1. package/dist/admin/AdminAppIndex.pack.js +4815 -188
  2. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.min.js +34 -7
  4. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  5. package/dist/common/commands/CommonCommands.d.ts +1 -3
  6. package/dist/common/commands/CommonCommands.d.ts.map +1 -1
  7. package/dist/common/commands/CommonCommands.js +1 -1
  8. package/dist/common/commands/CommonCommands.js.map +1 -1
  9. package/dist/common/controls/collection-editor/CollectionEditor.d.ts +2 -1
  10. package/dist/common/controls/collection-editor/CollectionEditor.d.ts.map +1 -1
  11. package/dist/common/controls/collection-editor/CollectionEditor.js +26 -12
  12. package/dist/common/controls/collection-editor/CollectionEditor.js.map +1 -1
  13. package/dist/common/controls/collection-editor/CollectionEditorEx.js +173 -0
  14. package/dist/common/controls/collection-editor/CollectionEditorEx.js.map +1 -0
  15. package/dist/common/controls/reference-editor/ReferenceEditor.d.ts +38 -0
  16. package/dist/common/controls/reference-editor/ReferenceEditor.d.ts.map +1 -0
  17. package/dist/common/controls/reference-editor/ReferenceEditor.js +226 -0
  18. package/dist/common/controls/reference-editor/ReferenceEditor.js.map +1 -0
  19. package/dist/common/controls/search-items/SearchItemsPage.d.ts +7 -0
  20. package/dist/common/controls/search-items/SearchItemsPage.d.ts.map +1 -0
  21. package/dist/common/controls/search-items/SearchItemsPage.js +15 -0
  22. package/dist/common/controls/search-items/SearchItemsPage.js.map +1 -0
  23. package/dist/common/controls/tags/TagChips.d.ts +7 -0
  24. package/dist/common/controls/tags/TagChips.d.ts.map +1 -0
  25. package/dist/common/controls/tags/TagChips.js +89 -0
  26. package/dist/common/controls/tags/TagChips.js.map +1 -0
  27. package/dist/common/pages/contacts/ContactEditorPage.d.ts +12 -0
  28. package/dist/common/pages/contacts/ContactEditorPage.d.ts.map +1 -0
  29. package/dist/common/pages/contacts/ContactEditorPage.js +150 -0
  30. package/dist/common/pages/contacts/ContactEditorPage.js.map +1 -0
  31. package/dist/common/pages/stores/StoreDetailPage.d.ts.map +1 -1
  32. package/dist/common/pages/stores/StoreDetailPage.js +11 -3
  33. package/dist/common/pages/stores/StoreDetailPage.js.map +1 -1
  34. package/dist/common/pages/stores/folders/EditItemFolderPage.d.ts +10 -0
  35. package/dist/common/pages/stores/folders/EditItemFolderPage.d.ts.map +1 -0
  36. package/dist/common/pages/stores/folders/EditItemFolderPage.js +92 -0
  37. package/dist/common/pages/stores/folders/EditItemFolderPage.js.map +1 -0
  38. package/dist/common/pages/stores/orders/EditOrderPage.d.ts +5 -2
  39. package/dist/common/pages/stores/orders/EditOrderPage.d.ts.map +1 -1
  40. package/dist/common/pages/stores/orders/EditOrderPage.js +145 -4
  41. package/dist/common/pages/stores/orders/EditOrderPage.js.map +1 -1
  42. package/dist/common/pages/stores/products/EditProductDetailPage.d.ts +2 -3
  43. package/dist/common/pages/stores/products/EditProductDetailPage.d.ts.map +1 -1
  44. package/dist/common/pages/stores/products/EditProductDetailPage.js +110 -25
  45. package/dist/common/pages/stores/products/EditProductDetailPage.js.map +1 -1
  46. package/dist/common/pages/stores/products/EditProductListPage.d.ts.map +1 -1
  47. package/dist/common/pages/stores/products/EditProductListPage.js +24 -25
  48. package/dist/common/pages/stores/products/EditProductListPage.js.map +1 -1
  49. package/dist/model/model.d.ts +87 -2
  50. package/dist/model/model.d.ts.map +1 -1
  51. package/dist/model/model.js +3498 -18
  52. package/dist/model/model.js.map +1 -1
  53. package/dist/public/channel/ChannelView.pack.js +3500 -19
  54. package/dist/public/channel/ChannelView.pack.js.map +1 -1
  55. package/dist/public/channel/ChannelView.pack.min.js +2 -2
  56. package/dist/public/channel/ChannelView.pack.min.js.map +1 -1
  57. package/dist/services/contacts/ContactService.d.ts +8 -0
  58. package/dist/services/contacts/ContactService.d.ts.map +1 -0
  59. package/dist/services/contacts/ContactService.js +40 -0
  60. package/dist/services/contacts/ContactService.js.map +1 -0
  61. package/dist/services/store/StoreItemService.d.ts.map +1 -1
  62. package/dist/services/store/StoreItemService.js +3 -3
  63. package/dist/services/store/StoreItemService.js.map +1 -1
  64. package/dist/services/store/StoreOrderService.d.ts +3 -1
  65. package/dist/services/store/StoreOrderService.d.ts.map +1 -1
  66. package/dist/services/store/StoreOrderService.js +72 -3
  67. package/dist/services/store/StoreOrderService.js.map +1 -1
  68. package/dist/site-editor/editor/WebSitePageEditor.js +1 -1
  69. package/dist/tsconfig.tsbuildinfo +1 -1
  70. package/dist/web/AppIndex.pack.js +4816 -189
  71. package/dist/web/AppIndex.pack.js.map +1 -1
  72. package/dist/web/AppIndex.pack.min.js +34 -7
  73. package/dist/web/AppIndex.pack.min.js.map +1 -1
  74. package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.d.ts +26 -1
  75. package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.d.ts.map +1 -1
  76. package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.js +2 -1
  77. package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.js.map +1 -1
  78. package/node_modules/@web-atoms/entity/dist/tsconfig.tsbuildinfo +1 -1
  79. package/node_modules/@web-atoms/entity/package.json +1 -1
  80. package/node_modules/@web-atoms/entity/src/services/BaseEntityService.ts +27 -1
  81. package/package.json +2 -2
  82. package/src/common/commands/CommonCommands.ts +1 -1
  83. package/src/common/controls/collection-editor/CollectionEditor.tsx +28 -7
  84. package/src/common/controls/collection-editor/CollectionEditorEx.tsx +158 -0
  85. package/src/common/controls/reference-editor/ReferenceEditor.tsx +227 -0
  86. package/src/common/controls/search-items/SearchItemsPage.tsx +10 -0
  87. package/src/common/controls/tags/TagChips.tsx +51 -0
  88. package/src/common/pages/contacts/ContactEditorPage.tsx +132 -0
  89. package/src/common/pages/stores/StoreDetailPage.tsx +3 -1
  90. package/src/common/pages/stores/folders/EditItemFolderPage.tsx +69 -0
  91. package/src/common/pages/stores/orders/EditOrderPage.tsx +148 -5
  92. package/src/common/pages/stores/products/EditProductDetailPage.tsx +106 -29
  93. package/src/common/pages/stores/products/EditProductListPage.tsx +15 -12
  94. package/src/model/model.ts +538 -62
  95. package/src/services/contacts/ContactService.ts +29 -0
  96. package/src/services/store/StoreItemService.ts +7 -4
  97. package/src/services/store/StoreOrderService.ts +77 -2
  98. package/src/site-editor/editor/WebSitePageEditor.tsx +1 -1
@@ -0,0 +1,227 @@
1
+ import XNode from "@web-atoms/core/dist/core/XNode";
2
+ import AtomRepeater from "@web-atoms/web-controls/dist/basic/AtomRepeater";
3
+ import Expander from "@web-atoms/web-controls/dist/basic/Expander";
4
+ import { AddIconTextButton, DeleteIconButton } from "../buttons/IconButton";
5
+ import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
6
+ import Bind from "@web-atoms/core/dist/core/Bind";
7
+ import PopupService from "@web-atoms/core/dist/web/services/PopupService";
8
+ import EntityService from "../../../services/EntityService";
9
+ import styled from "@web-atoms/core/dist/style/styled";
10
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
11
+ import ExpressionParser from "@web-atoms/core/dist/core/ExpressionParser";
12
+ import { modelEntitySchemas } from "../../../model/model";
13
+ import { IModel, IModelSchema, IRelation } from "@web-atoms/entity/dist/services/BaseEntityService";
14
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
15
+ import { CancelToken } from "@web-atoms/core/dist/core/types";
16
+ import Query from "@web-atoms/entity/dist/services/Query";
17
+ import InfiniteRepeater from "../repeater/InfiniteRepeater";
18
+ import Action from "@web-atoms/core/dist/view-model/Action";
19
+
20
+ styled.css `
21
+
22
+ position: relative;
23
+ overflow: visible !important;
24
+
25
+ & .model {
26
+
27
+ position: relative;
28
+ overflow: visible !important;
29
+
30
+ }
31
+
32
+ & .suggestions {
33
+ position: absolute;
34
+ background-color: canvas;
35
+ padding: 10px;
36
+ border: solid 1px lightgray;
37
+ top: 2rem;
38
+ border-radius: 10px;
39
+ z-index: 40000;
40
+ }
41
+
42
+ `.installGlobal("[data-reference-editor=reference-editor]");
43
+
44
+ export default class ReferenceEditor<T = any, TR = any> extends AtomControl {
45
+
46
+ public label: string = "";
47
+
48
+ public model: T = null;
49
+
50
+ public field: (x: T) => TR = null;
51
+
52
+ public searchQuery: (q: Query<TR>, searchText: string) => Query<TR> = null;
53
+
54
+ public cacheVersion = "c1";
55
+
56
+ public cacheSeconds = 15;
57
+
58
+
59
+ public editModelPage: any = null;
60
+
61
+ public addNewDefaults: Partial<TR> = {};
62
+
63
+ public ["event-reference-updated"]: (ce: CustomEvent<TR>) => any;
64
+
65
+ private reference: any = null;
66
+ private fieldName: string = null;
67
+ private search = "";
68
+ private suggestions: TR[] = null;
69
+ private relation: IRelation = null;
70
+
71
+ @InjectProperty
72
+ private entityService: EntityService;
73
+ private schema: IModel<any> = null;
74
+ private showSearch = false;
75
+ private hasFocus = false;
76
+
77
+ constructor(app, e) {
78
+ super(app, e);
79
+ this.runAfterInit(() => this.app.runAsync(() => this.init()));
80
+ }
81
+
82
+ public itemRenderer: (x: TR) => XNode = () => <div title="Setup Item Renderer to customize view" text="Model"/>;
83
+ public suggestionRenderer: (x: TR) => XNode = (x) => this.itemRenderer(x);
84
+ public onAddNew: (search: string) => Promise<TR> = (search) => PageNavigator.pushPageForResult(this.editModelPage, { search, ... this.addNewDefaults });
85
+
86
+ async init() {
87
+
88
+ const fieldName = ExpressionParser.parsePath(this.field)[0][0];
89
+ this.fieldName = fieldName;
90
+
91
+ const renderModel = (renderer, model: any) => <div
92
+ class="model"
93
+ data-border="frame"
94
+ data-padding="auto"
95
+ data-layout="vertical-flex-stretch-items">
96
+ <div data-layout="row">
97
+ <label text={Bind.oneWay(() => this.label)}/>
98
+ {model && renderer(model)}
99
+ {model && <i
100
+ event-click={() => this.clearModel()}
101
+ title="Clear"
102
+ data-cursor="pointer"
103
+ data-color="red"
104
+ class="fas fa-times-circle"/>}
105
+ {!model && <input
106
+ type="search"
107
+ placeholder={`Search ${this.label}`}
108
+ event-focus={() => this.hasFocus = true}
109
+ event-blur={() => setTimeout(() => this.hasFocus = false, 250)}
110
+ value={Bind.twoWaysImmediate(() => this.search)}
111
+ />}
112
+ </div>
113
+ {!model && <div
114
+ class="suggestions"
115
+ style-display={Bind.oneWay(() => this.showSearch)}
116
+ >
117
+ <div>
118
+ <div
119
+ style-max-height="200px"
120
+ data-overflow-y="auto">
121
+ <AtomRepeater
122
+ data-layout="data-grid"
123
+ data-list-selection="default"
124
+ data-click-event="select-suggestion"
125
+ items={this.suggestions}
126
+ { ... InfiniteRepeater.pagedItems((start) => (c, e, cancelToken) => this.queryItems(start, this.search, cancelToken, this.showSearch))}
127
+ itemRenderer={this.suggestionRenderer}
128
+ />
129
+ </div>
130
+ <div
131
+ data-layout="row"
132
+ data-cursor="pointer"
133
+ event-click={() => this.addNew()}
134
+ >
135
+ <i class="fas fa-plus"/>
136
+ Add New
137
+ </div>
138
+ </div>
139
+ </div>}
140
+ </div>;
141
+
142
+ const fx = () => this.model[this.fieldName];
143
+ fx.toString = () => `() => this.model.${fieldName}`;
144
+
145
+ this.renderer = <div
146
+ data-reference-editor="reference-editor"
147
+ reference={Bind.oneWay(fx)}
148
+ schema={Bind.oneWay(() => modelEntitySchemas[(this.model as any).$type])}
149
+ relation={Bind.oneWay(() => this.schema.schema.relations.find((x) => x.name === this.fieldName))}
150
+ renderer={Bind.oneWay(() => renderModel(this.itemRenderer, this.reference) ) }
151
+ showSearch={Bind.oneWay(() => (this.hasFocus || this.search) ? true : false)}
152
+ ></div>;
153
+ }
154
+
155
+ queryItems(start, search: string, cancelToken: CancelToken, showSearch) {
156
+ if (!showSearch) {
157
+ return {
158
+ items: [],
159
+ total: 0
160
+ };
161
+ }
162
+ let q: Query<TR> = this.entityService.query(this.relation.relatedModel) as any;
163
+ q = this.searchQuery(q, search);
164
+ const { cacheVersion, cacheSeconds } = this;
165
+ return q.toPagedList({
166
+ start,
167
+ size: 10,
168
+ cacheSeconds,
169
+ cacheVersion,
170
+ cancelToken
171
+ });
172
+ }
173
+
174
+ async addNew() {
175
+ this.showSearch = false;
176
+ const model = await this.onAddNew(this.search);
177
+ }
178
+
179
+ async clearModel(): Promise<any> {
180
+ this.model[this.fieldName] = null;
181
+
182
+ const relation = this.relation;
183
+ if (!relation.isInverse) {
184
+ this.model[relation.fkMap[0].fk] = null;
185
+ }
186
+
187
+ // save...
188
+
189
+ // if we have all keys...
190
+ if (!this.hasAllKeys()) {
191
+ this.element.dispatchEvent(new CustomEvent("referenceUpdated",{
192
+ detail: null
193
+ }));
194
+ return;
195
+ }
196
+
197
+ await this.entityService.save(this.model as any, (c) => c);
198
+ this.element.dispatchEvent(new CustomEvent("referenceUpdated",{
199
+ detail: null
200
+ }));
201
+ }
202
+
203
+ hasAllKeys() {
204
+ const { schema, model } = this;
205
+ if (!model) {
206
+ return;
207
+ }
208
+ for (const key of schema.schema.keys) {
209
+ if(!model[key.name]) {
210
+ return false;
211
+ }
212
+ }
213
+ return schema.schema.keys.length > 0;
214
+ }
215
+
216
+ @Action({ onEvent: "select-suggestion"})
217
+ selectSuggestion(item) {
218
+ const { relation, model } = this;
219
+ model[this.fieldName] = item;
220
+ model[relation.fkMap[0].fk] = item[relation.fkMap[0].relatedKey];
221
+
222
+ this.element.dispatchEvent(new CustomEvent("referenceUpdated",{
223
+ detail: item
224
+ }));
225
+ }
226
+
227
+ }
@@ -0,0 +1,10 @@
1
+ import { IModel } from "@web-atoms/entity/dist/services/BaseEntityService";
2
+ import { PopupWindowPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
3
+
4
+ export default class SearchItemsPage<T> extends PopupWindowPage {
5
+
6
+ public entityModel: IModel<T>;
7
+
8
+ public query: any;
9
+
10
+ }
@@ -0,0 +1,51 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind";
2
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+ import AtomChips, { Chip, Suggestion } from "@web-atoms/web-controls/dist/basic/AtomChips";
5
+ import EntityService from "../../../services/EntityService";
6
+ import { CancelToken } from "@web-atoms/core/dist/core/types";
7
+ import { IStoreItemTag, ITag, Tag } from "../../../model/model";
8
+ import { Sql } from "../../Sql";
9
+
10
+ export default class TagChips extends AtomChips {
11
+
12
+ @InjectProperty
13
+ private entityService: EntityService;
14
+
15
+ protected preCreate(): void {
16
+ super.preCreate();
17
+
18
+ this.labelPath = (x: IStoreItemTag) => x.tag?.name;
19
+ this.prompt = "Tags";
20
+ this.itemRenderer = (x: IStoreItemTag) => <Chip
21
+ deleted={x.$deleted}
22
+ label={x.tag?.name}
23
+ />;
24
+ this.suggestionRenderer = (x: ITag) =>
25
+ <Suggestion text={x.name}/>;
26
+ this.enterKeyHint = "enter";
27
+ this.itemToChip = (item, name) => ({ $deleted: false, tag: Tag.create({ name }) });
28
+
29
+ this.render(<div suggestions={Bind.oneWayAsync((c, e, cancelToken) =>
30
+ this.searchItems(cancelToken, this.search), { watchDelayInMS: 750 })}></div>);
31
+
32
+ this.valuePath = (x: IStoreItemTag) => x.tag?.tagID ?? x.tagID;
33
+ }
34
+
35
+ private async searchItems(cancelToken: CancelToken, search: string) {
36
+ if (!search) {
37
+ return null;
38
+ }
39
+ let q = this.entityService.query(Tag);
40
+ search = search.toLocaleLowerCase();
41
+ q = q.where({ search: search + "%" }, (p) => (x) => Sql.text.like(x.name, p.search));
42
+ const items = await q.orderBy((x) => x.name)
43
+ .toPagedList({
44
+ cancelToken,
45
+ hideActivityIndicator: true,
46
+ size: 10
47
+ });
48
+ return items.items.map((tag) => ({ tag }));
49
+ }
50
+
51
+ }
@@ -0,0 +1,132 @@
1
+ import { PopupWindowPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
2
+ import { Contact, ContactEmail, ContactPhone, HostedDomain, IContact, IContactEmail, IContactPhone, IHostedDomain } from "../../../model/model";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+ import Form from "@web-atoms/web-controls/dist/basic/Form";
5
+ import FormField from "@web-atoms/web-controls/dist/basic/FormField";
6
+ import Bind from "@web-atoms/core/dist/core/Bind";
7
+ import ToggleButtonBar from "@web-atoms/web-controls/dist/basic/ToggleButtonBar";
8
+ import Select from "@web-atoms/web-controls/dist/basic/Select";
9
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
10
+ import EntityService from "../../../services/EntityService";
11
+ import CollectionEditor from "../../controls/collection-editor/CollectionEditor";
12
+ import CollectionEditorEx from "../../controls/collection-editor/CollectionEditorEx";
13
+ import { SaveIconTextButton } from "../../controls/buttons/IconButton";
14
+ import Action from "@web-atoms/core/dist/view-model/Action";
15
+ import ContactService from "../../../services/contacts/ContactService";
16
+
17
+ const contactTypes = [
18
+ { label: "Company", value: "company"},
19
+ { label: "Person", value: "person"}
20
+ ];
21
+
22
+ export default class ContactEditorPage extends PopupWindowPage<IContact> {
23
+
24
+ public model: IContact = null;
25
+
26
+ @InjectProperty
27
+ entityService: EntityService;
28
+
29
+ @InjectProperty
30
+ contactService: ContactService;
31
+
32
+ async init() {
33
+
34
+ this.model = this.parameters?.contactID
35
+ ? await this.contactService.get(this.parameters.contactID)
36
+ : Contact.create({
37
+ type: "person",
38
+ name: "",
39
+ emails: [
40
+ ContactEmail.create({
41
+ emailAddressText: "",
42
+ emailAddressID: null
43
+ })
44
+ ],
45
+ phones: [
46
+ ContactPhone.create({
47
+ phoneNumberE64: ""
48
+ })
49
+ ]});
50
+
51
+ this.title = this.model.contactID ? "Edit " + this.model.name : "Add New Contact";
52
+
53
+ this.renderer = <div>
54
+ <Form>
55
+ <FormField
56
+ label="Name"
57
+ required={true}
58
+ error={Bind.oneWay(() => this.model.name ? "" : "Name is required")}>
59
+ <input
60
+ value={Bind.twoWaysImmediate(() => this.model.name)}
61
+ autofocus={true}
62
+ />
63
+ </FormField>
64
+ <FormField label="Type">
65
+ <ToggleButtonBar
66
+ items={contactTypes}
67
+ labelPath={(x) => x.label}
68
+ valuePath={(x) => x.value}
69
+ value={Bind.twoWaysImmediate(() => this.model.type)}
70
+ />
71
+ </FormField>
72
+ <FormField label="Domain">
73
+ <Select
74
+ items={Bind.oneWay(() => this.entityService.query(HostedDomain)
75
+ .include((x) => x.domain)
76
+ .toArray())}
77
+ labelPath={(x: IHostedDomain) => x.domain.name}
78
+ valuePath={(x: IHostedDomain) => x.domainID}
79
+ value={Bind.twoWaysImmediate(() => this.model.domainID)}
80
+ />
81
+ </FormField>
82
+ <div data-layout="flex-wrap-padding">
83
+ <CollectionEditorEx
84
+ label="Phone"
85
+ model={this.model}
86
+ field={(x) => x.phones}
87
+ itemRenderer={(item: IContactPhone) => <div>
88
+ <input
89
+ value={Bind.sourceTwoWays(item, (x) => x.source.phoneNumberE64)}/>
90
+ </div>}/>
91
+ <CollectionEditorEx
92
+ label="Email"
93
+ model={this.model}
94
+ field={(x) => x.emails}
95
+ itemRenderer={(item: IContactEmail) => <div>
96
+ {item.emailAddress
97
+ ? <div text={item.emailAddress.emailAddress}/>
98
+ : <input
99
+ value={Bind.sourceTwoWays(item, (x) => x.source.emailAddress)}/>
100
+ }
101
+ </div>}/>
102
+ </div>
103
+ <details open={true} data-border="frame">
104
+ <summary>Tax Numbers</summary>
105
+ <div data-layout="vertical-flex-stretch-items">
106
+ <FormField label="GST ID (GSTIN)">
107
+ <input value={Bind.twoWaysImmediate(() => this.model.gstTaxID)}/>
108
+ </FormField>
109
+ <FormField label="Income TAX (PAN/TAX ID)">
110
+ <input value={Bind.twoWaysImmediate(() => this.model.incomeTaxID)}/>
111
+ </FormField>
112
+ <FormField label="Sales TAX ID">
113
+ <input value={Bind.twoWaysImmediate(() => this.model.salesTaxID)}/>
114
+ </FormField>
115
+ </div>
116
+ </details>
117
+ <div data-layout="sticky-command-row">
118
+ <SaveIconTextButton
119
+ data-submit-event="save-contact"
120
+ />
121
+ </div>
122
+ </Form>
123
+ </div>;
124
+ }
125
+
126
+ @Action({ onEvent: "save-contact", close: true })
127
+ async saveContact() {
128
+ await this.contactService.save(this.model);
129
+ return this.model;
130
+ }
131
+
132
+ }
@@ -12,6 +12,8 @@ import InfiniteRepeater from "../../controls/repeater/InfiniteRepeater";
12
12
  import StoreOrderService from "../../../services/store/StoreOrderService";
13
13
  import { AddIconTextButton } from "../../controls/buttons/IconButton";
14
14
  import Action from "@web-atoms/core/dist/view-model/Action";
15
+ import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
16
+ import EditOrderPage from "./orders/EditOrderPage";
15
17
 
16
18
  export default class StoreDetailPage extends ContentPage<{ id: any }> {
17
19
 
@@ -78,7 +80,7 @@ export default class StoreDetailPage extends ContentPage<{ id: any }> {
78
80
 
79
81
  @Action({ onEvent: "create-order"})
80
82
  async createOrder() {
81
-
83
+ await PageNavigator.pushPageForResult(EditOrderPage, { storeID: this.parameters.id });
82
84
  }
83
85
 
84
86
  }
@@ -0,0 +1,69 @@
1
+ import { PopupWindowPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
2
+ import { IStoreItemFolder, StoreItemFolder } from "../../../../model/model";
3
+ import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
4
+ import EntityService from "../../../../services/EntityService";
5
+ import XNode from "@web-atoms/core/dist/core/XNode";
6
+ import Form from "@web-atoms/web-controls/dist/basic/Form";
7
+ import FormField from "@web-atoms/web-controls/dist/basic/FormField";
8
+ import Bind from "@web-atoms/core/dist/core/Bind";
9
+ import ReferenceEditor from "../../../controls/reference-editor/ReferenceEditor";
10
+ import Query from "@web-atoms/entity/dist/services/Query";
11
+ import { Sql } from "../../../Sql";
12
+ import { SaveIconTextButton } from "../../../controls/buttons/IconButton";
13
+ import Action from "@web-atoms/core/dist/view-model/Action";
14
+
15
+ export default class EditItemFolderPage extends PopupWindowPage<IStoreItemFolder> {
16
+
17
+ model: IStoreItemFolder = null;
18
+
19
+ @InjectProperty
20
+ entityService: EntityService;
21
+
22
+ async init() {
23
+ this.model = this.parameters?.itemFolderID
24
+ ? await this.entityService.query(StoreItemFolder).where(this.parameters, (p) => (x) => x.itemFolderID === p.itemFolderID).firstOrDefault()
25
+ : StoreItemFolder.create({
26
+ parent: null,
27
+ storeID: this.parameters?.storeID
28
+ });
29
+
30
+ if (!this.parameters.storeID) {
31
+ alert("Store is not set");
32
+ this.cancel();
33
+ return;
34
+ }
35
+
36
+ this.renderer = <div>
37
+ <Form>
38
+ <FormField label="Name">
39
+ <input
40
+ placeholder="Name"
41
+ value={Bind.twoWaysImmediate(() => this.model.name)}
42
+ autofocus={true}/>
43
+ </FormField>
44
+ <ReferenceEditor
45
+ label="Folder"
46
+ model={this.model}
47
+ field={(x) => x.parent}
48
+ searchQuery={(q: Query<IStoreItemFolder>, search) =>
49
+ (search ? q.where({ search }, (p) => (x) => Sql.text.startsWith(x.name, p.search)) : q)
50
+ .orderBy((x) => x.path)
51
+ }
52
+ itemRenderer={(x) => <div><label text={x.name}/></div>}
53
+ />
54
+ <div data-layout="command-row">
55
+ <SaveIconTextButton
56
+ data-submit-event="save-folder"
57
+ />
58
+ </div>
59
+ </Form>
60
+ </div>;
61
+ }
62
+
63
+ @Action({ onEvent: "save-folder", close: true })
64
+ async saveFolder() {
65
+ await this.entityService.save(this.model, (c) => c);
66
+ return this.model;
67
+ }
68
+
69
+ }