@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.
- package/dist/admin/AdminAppIndex.pack.js +4815 -188
- package/dist/admin/AdminAppIndex.pack.js.map +1 -1
- package/dist/admin/AdminAppIndex.pack.min.js +34 -7
- package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
- package/dist/common/commands/CommonCommands.d.ts +1 -3
- package/dist/common/commands/CommonCommands.d.ts.map +1 -1
- package/dist/common/commands/CommonCommands.js +1 -1
- package/dist/common/commands/CommonCommands.js.map +1 -1
- package/dist/common/controls/collection-editor/CollectionEditor.d.ts +2 -1
- package/dist/common/controls/collection-editor/CollectionEditor.d.ts.map +1 -1
- package/dist/common/controls/collection-editor/CollectionEditor.js +26 -12
- package/dist/common/controls/collection-editor/CollectionEditor.js.map +1 -1
- package/dist/common/controls/collection-editor/CollectionEditorEx.js +173 -0
- package/dist/common/controls/collection-editor/CollectionEditorEx.js.map +1 -0
- package/dist/common/controls/reference-editor/ReferenceEditor.d.ts +38 -0
- package/dist/common/controls/reference-editor/ReferenceEditor.d.ts.map +1 -0
- package/dist/common/controls/reference-editor/ReferenceEditor.js +226 -0
- package/dist/common/controls/reference-editor/ReferenceEditor.js.map +1 -0
- package/dist/common/controls/search-items/SearchItemsPage.d.ts +7 -0
- package/dist/common/controls/search-items/SearchItemsPage.d.ts.map +1 -0
- package/dist/common/controls/search-items/SearchItemsPage.js +15 -0
- package/dist/common/controls/search-items/SearchItemsPage.js.map +1 -0
- package/dist/common/controls/tags/TagChips.d.ts +7 -0
- package/dist/common/controls/tags/TagChips.d.ts.map +1 -0
- package/dist/common/controls/tags/TagChips.js +89 -0
- package/dist/common/controls/tags/TagChips.js.map +1 -0
- package/dist/common/pages/contacts/ContactEditorPage.d.ts +12 -0
- package/dist/common/pages/contacts/ContactEditorPage.d.ts.map +1 -0
- package/dist/common/pages/contacts/ContactEditorPage.js +150 -0
- package/dist/common/pages/contacts/ContactEditorPage.js.map +1 -0
- package/dist/common/pages/stores/StoreDetailPage.d.ts.map +1 -1
- package/dist/common/pages/stores/StoreDetailPage.js +11 -3
- package/dist/common/pages/stores/StoreDetailPage.js.map +1 -1
- package/dist/common/pages/stores/folders/EditItemFolderPage.d.ts +10 -0
- package/dist/common/pages/stores/folders/EditItemFolderPage.d.ts.map +1 -0
- package/dist/common/pages/stores/folders/EditItemFolderPage.js +92 -0
- package/dist/common/pages/stores/folders/EditItemFolderPage.js.map +1 -0
- package/dist/common/pages/stores/orders/EditOrderPage.d.ts +5 -2
- package/dist/common/pages/stores/orders/EditOrderPage.d.ts.map +1 -1
- package/dist/common/pages/stores/orders/EditOrderPage.js +145 -4
- package/dist/common/pages/stores/orders/EditOrderPage.js.map +1 -1
- package/dist/common/pages/stores/products/EditProductDetailPage.d.ts +2 -3
- package/dist/common/pages/stores/products/EditProductDetailPage.d.ts.map +1 -1
- package/dist/common/pages/stores/products/EditProductDetailPage.js +110 -25
- package/dist/common/pages/stores/products/EditProductDetailPage.js.map +1 -1
- package/dist/common/pages/stores/products/EditProductListPage.d.ts.map +1 -1
- package/dist/common/pages/stores/products/EditProductListPage.js +24 -25
- package/dist/common/pages/stores/products/EditProductListPage.js.map +1 -1
- package/dist/model/model.d.ts +87 -2
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +3498 -18
- package/dist/model/model.js.map +1 -1
- package/dist/public/channel/ChannelView.pack.js +3500 -19
- package/dist/public/channel/ChannelView.pack.js.map +1 -1
- package/dist/public/channel/ChannelView.pack.min.js +2 -2
- package/dist/public/channel/ChannelView.pack.min.js.map +1 -1
- package/dist/services/contacts/ContactService.d.ts +8 -0
- package/dist/services/contacts/ContactService.d.ts.map +1 -0
- package/dist/services/contacts/ContactService.js +40 -0
- package/dist/services/contacts/ContactService.js.map +1 -0
- package/dist/services/store/StoreItemService.d.ts.map +1 -1
- package/dist/services/store/StoreItemService.js +3 -3
- package/dist/services/store/StoreItemService.js.map +1 -1
- package/dist/services/store/StoreOrderService.d.ts +3 -1
- package/dist/services/store/StoreOrderService.d.ts.map +1 -1
- package/dist/services/store/StoreOrderService.js +72 -3
- package/dist/services/store/StoreOrderService.js.map +1 -1
- package/dist/site-editor/editor/WebSitePageEditor.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/web/AppIndex.pack.js +4816 -189
- package/dist/web/AppIndex.pack.js.map +1 -1
- package/dist/web/AppIndex.pack.min.js +34 -7
- package/dist/web/AppIndex.pack.min.js.map +1 -1
- package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.d.ts +26 -1
- package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.d.ts.map +1 -1
- package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.js +2 -1
- package/node_modules/@web-atoms/entity/dist/services/BaseEntityService.js.map +1 -1
- package/node_modules/@web-atoms/entity/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@web-atoms/entity/package.json +1 -1
- package/node_modules/@web-atoms/entity/src/services/BaseEntityService.ts +27 -1
- package/package.json +2 -2
- package/src/common/commands/CommonCommands.ts +1 -1
- package/src/common/controls/collection-editor/CollectionEditor.tsx +28 -7
- package/src/common/controls/collection-editor/CollectionEditorEx.tsx +158 -0
- package/src/common/controls/reference-editor/ReferenceEditor.tsx +227 -0
- package/src/common/controls/search-items/SearchItemsPage.tsx +10 -0
- package/src/common/controls/tags/TagChips.tsx +51 -0
- package/src/common/pages/contacts/ContactEditorPage.tsx +132 -0
- package/src/common/pages/stores/StoreDetailPage.tsx +3 -1
- package/src/common/pages/stores/folders/EditItemFolderPage.tsx +69 -0
- package/src/common/pages/stores/orders/EditOrderPage.tsx +148 -5
- package/src/common/pages/stores/products/EditProductDetailPage.tsx +106 -29
- package/src/common/pages/stores/products/EditProductListPage.tsx +15 -12
- package/src/model/model.ts +538 -62
- package/src/services/contacts/ContactService.ts +29 -0
- package/src/services/store/StoreItemService.ts +7 -4
- package/src/services/store/StoreOrderService.ts +77 -2
- 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
|
+
}
|