@social-mail/social-mail-client 1.2.252 → 1.2.254
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 +715 -79
- package/dist/admin/AdminAppIndex.pack.js.map +1 -1
- package/dist/admin/AdminAppIndex.pack.min.js +22 -16
- package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
- package/dist/code-editor/CodeEditorPage.d.ts +1 -3
- package/dist/code-editor/CodeEditorPage.d.ts.map +1 -1
- package/dist/code-editor/CodeEditorPage.js +5 -4
- package/dist/code-editor/CodeEditorPage.js.map +1 -1
- package/dist/common/controls/Loader.d.ts +2 -0
- package/dist/common/controls/Loader.d.ts.map +1 -0
- package/dist/common/controls/Loader.js +21 -0
- package/dist/common/controls/Loader.js.map +1 -0
- package/dist/common/controls/collection-editor/CollectionEditorEx.js +18 -8
- package/dist/common/controls/collection-editor/CollectionEditorEx.js.map +1 -1
- package/dist/common/controls/reference-editor/ReferenceEditor.d.ts.map +1 -1
- package/dist/common/controls/reference-editor/ReferenceEditor.js.map +1 -1
- package/dist/common/fileUrl.d.ts +14 -1
- package/dist/common/fileUrl.d.ts.map +1 -1
- package/dist/common/fileUrl.js +24 -5
- package/dist/common/fileUrl.js.map +1 -1
- package/dist/common/pages/stores/products/EditProductDetailPage.d.ts +4 -3
- package/dist/common/pages/stores/products/EditProductDetailPage.d.ts.map +1 -1
- package/dist/common/pages/stores/products/EditProductDetailPage.js +21 -5
- package/dist/common/pages/stores/products/EditProductDetailPage.js.map +1 -1
- package/dist/common/pages/stores/products/ProductEditor.d.ts +10 -1
- package/dist/common/pages/stores/products/ProductEditor.d.ts.map +1 -1
- package/dist/common/pages/stores/products/ProductEditor.js +176 -27
- package/dist/common/pages/stores/products/ProductEditor.js.map +1 -1
- package/dist/common/pages/stores/products/html/Offsers.d.ts +2 -0
- package/dist/common/pages/stores/products/html/Offsers.d.ts.map +1 -0
- package/dist/common/pages/stores/products/html/Offsers.js +20 -0
- package/dist/common/pages/stores/products/html/Offsers.js.map +1 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditor.d.ts +9 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditor.d.ts.map +1 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditor.js +64 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditor.js.map +1 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditorPage.d.ts +21 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditorPage.d.ts.map +1 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditorPage.js +138 -0
- package/dist/common/pages/stores/products/html/ProductHtmlEditorPage.js.map +1 -0
- package/dist/common/pages/stores/products/html/Specifications.d.ts +2 -0
- package/dist/common/pages/stores/products/html/Specifications.d.ts.map +1 -0
- package/dist/common/pages/stores/products/html/Specifications.js +22 -0
- package/dist/common/pages/stores/products/html/Specifications.js.map +1 -0
- package/dist/common/pages/websites/studio/WebSiteStudioPage.js +1 -1
- package/dist/common/pages/websites/studio/WebSiteStudioPage.js.map +1 -1
- package/dist/model/model.d.ts +21 -2
- package/dist/model/model.d.ts.map +1 -1
- package/dist/model/model.js +90 -11
- package/dist/model/model.js.map +1 -1
- package/dist/public/channel/ChannelView.pack.js +107 -16
- package/dist/public/channel/ChannelView.pack.js.map +1 -1
- package/dist/public/channel/ChannelView.pack.min.js +3 -3
- package/dist/public/channel/ChannelView.pack.min.js.map +1 -1
- package/dist/public/store/Store.pack.js +10729 -10631
- package/dist/public/store/Store.pack.js.map +1 -1
- package/dist/public/store/Store.pack.min.js +149 -288
- package/dist/public/store/Store.pack.min.js.map +1 -1
- package/dist/public/store/StoreApp.d.ts +1 -0
- package/dist/public/store/StoreApp.d.ts.map +1 -1
- package/dist/public/store/StoreApp.js +2 -2
- package/dist/public/store/StoreApp.js.map +1 -1
- package/dist/public/store/StoreApp.pack.js +33 -10
- package/dist/public/store/StoreApp.pack.js.map +1 -1
- package/dist/public/store/StoreApp.pack.min.js +8 -4
- package/dist/public/store/StoreApp.pack.min.js.map +1 -1
- package/dist/public/store/StoreItemDetailView.d.ts +13 -2
- package/dist/public/store/StoreItemDetailView.d.ts.map +1 -1
- package/dist/public/store/StoreItemDetailView.js +147 -7
- package/dist/public/store/StoreItemDetailView.js.map +1 -1
- package/dist/public/store/StoreItemListView.d.ts +2 -2
- package/dist/public/store/StoreItemListView.d.ts.map +1 -1
- package/dist/public/store/StoreItemListView.js +11 -9
- package/dist/public/store/StoreItemListView.js.map +1 -1
- package/dist/public/store/styles/common.d.ts +2 -0
- package/dist/public/store/styles/common.d.ts.map +1 -0
- package/dist/public/store/styles/common.js +18 -0
- package/dist/public/store/styles/common.js.map +1 -0
- package/dist/services/store/StoreItemService.d.ts +5 -0
- package/dist/services/store/StoreItemService.d.ts.map +1 -1
- package/dist/services/store/StoreItemService.js +66 -4
- package/dist/services/store/StoreItemService.js.map +1 -1
- package/dist/site-editor/editor/HtmlPageEditor.d.ts +1 -0
- package/dist/site-editor/editor/HtmlPageEditor.d.ts.map +1 -1
- package/dist/site-editor/editor/HtmlPageEditor.js +1 -0
- package/dist/site-editor/editor/HtmlPageEditor.js.map +1 -1
- package/dist/site-editor/editor/WebSitePageEditor.js +1 -1
- package/dist/site-editor/editor/WebSitePageEditor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/web/AppIndex.pack.js +715 -79
- package/dist/web/AppIndex.pack.js.map +1 -1
- package/dist/web/AppIndex.pack.min.js +22 -16
- package/dist/web/AppIndex.pack.min.js.map +1 -1
- package/dist/web/page/files/media/ChooseMediaPage.d.ts.map +1 -1
- package/dist/web/page/files/media/ChooseMediaPage.js +5 -1
- package/dist/web/page/files/media/ChooseMediaPage.js.map +1 -1
- package/dist/web/page/files/service/CloudFileService.d.ts +2 -1
- package/dist/web/page/files/service/CloudFileService.d.ts.map +1 -1
- package/dist/web/page/files/service/CloudFileService.js +5 -2
- package/dist/web/page/files/service/CloudFileService.js.map +1 -1
- package/node_modules/@web-atoms/core/dist/services/MockNavigationService.js.map +1 -1
- package/node_modules/@web-atoms/core/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@web-atoms/core/dist/web/controls/AtomControl.js +7 -3
- package/node_modules/@web-atoms/core/dist/web/controls/AtomControl.js.map +1 -1
- package/node_modules/@web-atoms/core/package.json +1 -1
- package/node_modules/@web-atoms/core/src/web/controls/AtomControl.ts +8 -2
- package/node_modules/@web-atoms/email-dom/dist/DomToString.js +10 -2
- package/node_modules/@web-atoms/email-dom/dist/DomToString.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/core/IXStyle.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Bold.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Button.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Cell.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Div.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/EllipsisText.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Email.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/EmailFooter.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/FloatingBox.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/HeaderBox.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Hr.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Image.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/InlineDiv.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Link.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Pre.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Row.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Span.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/StyleHelper.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/Table.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/dom/TextBox.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/style/IEmailElementStyle.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/style/mergeStyle.js.map +1 -1
- package/node_modules/@web-atoms/email-dom/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@web-atoms/email-dom/package.json +1 -1
- package/node_modules/@web-atoms/email-dom/src/DomToString.tsx +10 -4
- package/node_modules/@web-atoms/web-controls/dist/basic/PinchZoomView.d.ts.map +1 -1
- package/node_modules/@web-atoms/web-controls/dist/basic/PinchZoomView.js +1 -0
- package/node_modules/@web-atoms/web-controls/dist/basic/PinchZoomView.js.map +1 -1
- package/node_modules/@web-atoms/web-controls/dist/basic/styles/pinch-zoom-view-style.js +1 -0
- package/node_modules/@web-atoms/web-controls/dist/basic/styles/pinch-zoom-view-style.js.map +1 -1
- package/node_modules/@web-atoms/web-controls/dist/mobile-app/MobileApp.d.ts.map +1 -1
- package/node_modules/@web-atoms/web-controls/dist/mobile-app/MobileApp.js +2 -4
- package/node_modules/@web-atoms/web-controls/dist/mobile-app/MobileApp.js.map +1 -1
- package/node_modules/@web-atoms/web-controls/dist/tsconfig.tsbuildinfo +1 -1
- package/node_modules/@web-atoms/web-controls/package.json +1 -1
- package/node_modules/@web-atoms/web-controls/src/basic/PinchZoomView.tsx +1 -0
- package/node_modules/@web-atoms/web-controls/src/basic/styles/pinch-zoom-view-style.ts +1 -0
- package/node_modules/@web-atoms/web-controls/src/mobile-app/MobileApp.tsx +6 -2
- package/package.json +4 -4
- package/src/code-editor/CodeEditorPage.tsx +4 -6
- package/src/common/controls/Loader.tsx +9 -0
- package/src/common/controls/collection-editor/CollectionEditorEx.tsx +27 -13
- package/src/common/controls/reference-editor/ReferenceEditor.tsx +1 -0
- package/src/common/fileUrl.ts +17 -5
- package/src/common/pages/stores/products/EditProductDetailPage.tsx +11 -2
- package/src/common/pages/stores/products/ProductEditor.tsx +179 -33
- package/src/common/pages/stores/products/html/Offsers.tsx +9 -0
- package/src/common/pages/stores/products/html/ProductHtmlEditor.tsx +37 -0
- package/src/common/pages/stores/products/html/ProductHtmlEditorPage.tsx +131 -0
- package/src/common/pages/stores/products/html/Specifications.tsx +41 -0
- package/src/common/pages/websites/studio/WebSiteStudioPage.tsx +1 -1
- package/src/model/model.ts +35 -8
- package/src/public/store/StoreApp.tsx +1 -0
- package/src/public/store/StoreItemDetailView.tsx +160 -3
- package/src/public/store/StoreItemListView.tsx +6 -6
- package/src/public/store/styles/common.ts +7 -0
- package/src/services/store/StoreItemService.ts +68 -2
- package/src/site-editor/editor/HtmlPageEditor.tsx +2 -0
- package/src/site-editor/editor/WebSitePageEditor.tsx +1 -1
- package/src/web/page/files/media/ChooseMediaPage.tsx +5 -1
- package/src/web/page/files/service/CloudFileService.ts +7 -3
package/src/common/fileUrl.ts
CHANGED
|
@@ -9,9 +9,21 @@ export const imageUrl = (site: IAppFile, file: IAppFile, size?: number) => {
|
|
|
9
9
|
return apiPath(`/api/site/asset/webp(${size})/${site.appFileID}/${file.appFileID}/${file.fileContentID}/${name}.${size}.webp`);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
export const srcSetUrl = (site: IAppFile, file: IAppFile) => {
|
|
13
|
-
const small =
|
|
14
|
-
const medium =
|
|
15
|
-
const large =
|
|
12
|
+
export const srcSetUrl = (site: IAppFile, file: IAppFile, imgUrlFunc = imageUrl) => {
|
|
13
|
+
const small = imgUrlFunc(site, file, 480) + " 640w";
|
|
14
|
+
const medium = imgUrlFunc(site, file, 720) + " 1024w";
|
|
15
|
+
const large = imgUrlFunc(site, file) + " 1256w";
|
|
16
16
|
return `${small},${medium},${large}`;
|
|
17
|
-
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const signedImageUrl = ({ fileID = 0, appFileID = fileID, fileContentID = void 0, signed = void 0 }, size?: number) => {
|
|
20
|
+
return apiPath(`/api/signed/webp(${size})/${appFileID}/${fileContentID}/${signed}/file.${size}.webp`);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const signedUrl = ({ fileID = 0, appFileID = fileID, fileContentID = void 0, signed = void 0 }) => {
|
|
24
|
+
return apiPath(`/api/signed/download/${appFileID}/${fileContentID}/${signed}/file.dat`);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const storeFileUrl = (rootFolderID, file: IAppFile, type = "download", name = file.name ) => {
|
|
28
|
+
return apiPath(`/api/store/file/${type}/${rootFolderID}/${file.appFileID}/${file.fileContentID}/${name}`);
|
|
29
|
+
};
|
|
@@ -2,7 +2,7 @@ import XNode from "@web-atoms/core/dist/core/XNode";
|
|
|
2
2
|
import Form from "@web-atoms/web-controls/dist/basic/Form";
|
|
3
3
|
import { ContentPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
|
|
4
4
|
import CollectionEditor from "../../../controls/collection-editor/CollectionEditor";
|
|
5
|
-
import { IStoreItem, IStoreItemFolder, IStoreItemPrice, IStoreItemTag, StoreItem, StoreItemItemTypeArray } from "../../../../model/model";
|
|
5
|
+
import { IStoreItem, IStoreItemFolder, IStoreItemPrice, IStoreItemTag, IStoreMediaFile, StoreItem, StoreItemItemTypeArray } from "../../../../model/model";
|
|
6
6
|
import StoreItemService from "../../../../services/store/StoreItemService";
|
|
7
7
|
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
8
8
|
import FormField from "@web-atoms/web-controls/dist/basic/FormField";
|
|
@@ -21,8 +21,11 @@ import TagChips from "../../../controls/tags/TagChips";
|
|
|
21
21
|
import { DateFormats } from "../../../date/DateFormats";
|
|
22
22
|
import FolderViewControl from "../../../folder-view/FolderViewControl";
|
|
23
23
|
import ProductEditor from "./ProductEditor";
|
|
24
|
+
import MasterDetailPage from "@web-atoms/web-controls/dist/mobile-app/MasterDetailPage";
|
|
25
|
+
import ProductHtmlEditor from "./html/ProductHtmlEditorPage";
|
|
26
|
+
import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
|
|
24
27
|
|
|
25
|
-
export default class EditProductDetailPage extends
|
|
28
|
+
export default class EditProductDetailPage extends MasterDetailPage<Partial<IStoreItem>> {
|
|
26
29
|
|
|
27
30
|
model: IStoreItem = null;
|
|
28
31
|
|
|
@@ -83,4 +86,10 @@ export default class EditProductDetailPage extends ContentPage<Partial<IStoreIte
|
|
|
83
86
|
await this.init();
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
@Action({ onEvent: "editMediaFile"})
|
|
90
|
+
async editMediaFile(file: IStoreMediaFile) {
|
|
91
|
+
const item = this.model;
|
|
92
|
+
// this.openDetail(ProductHtmlEditor, { item, file });
|
|
93
|
+
await PageNavigator.pushPageForResult(ProductHtmlEditor, { item, file });
|
|
94
|
+
}
|
|
86
95
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
2
|
-
import { IStoreItem, IStoreItemFolder, IStoreItemPrice, StoreItem, StoreItemItemTypeArray } from "../../../../model/model";
|
|
2
|
+
import { IStoreItem, IStoreItemFolder, IStoreItemPrice, IStoreMediaFile, IStorePriceAddOn, StoreItem, StoreItemItemTypeArray, StoreMediaFile, StorePriceAddOn } from "../../../../model/model";
|
|
3
3
|
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
4
4
|
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
5
5
|
import Query from "@web-atoms/entity/dist/services/Query";
|
|
@@ -7,7 +7,7 @@ import Form from "@web-atoms/web-controls/dist/basic/Form";
|
|
|
7
7
|
import FormField from "@web-atoms/web-controls/dist/basic/FormField";
|
|
8
8
|
import Select from "@web-atoms/web-controls/dist/basic/Select";
|
|
9
9
|
import { Sql } from "../../../Sql";
|
|
10
|
-
import { SaveIconTextButton } from "../../../controls/buttons/IconButton";
|
|
10
|
+
import { SaveIconTextButton, UploadIconTextButton } from "../../../controls/buttons/IconButton";
|
|
11
11
|
import CollectionEditorEx from "../../../controls/collection-editor/CollectionEditorEx";
|
|
12
12
|
import ReferenceEditor from "../../../controls/reference-editor/ReferenceEditor";
|
|
13
13
|
import TagChips from "../../../controls/tags/TagChips";
|
|
@@ -16,19 +16,48 @@ import FolderViewControl from "../../../folder-view/FolderViewControl";
|
|
|
16
16
|
import EditItemFolderPage from "../folders/EditItemFolderPage";
|
|
17
17
|
import EditItemPricePage from "./prices/EditItemPricePage";
|
|
18
18
|
import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
|
|
19
|
+
import { FilesDragDrop } from "../../../controls/drag-drop/FilesDragDrop";
|
|
20
|
+
import UploadEvent from "@web-atoms/web-controls/dist/basic/UploadEvent";
|
|
21
|
+
import Action from "@web-atoms/core/dist/view-model/Action";
|
|
22
|
+
import { signedImageUrl } from "../../../fileUrl";
|
|
23
|
+
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
24
|
+
import EntityService from "../../../../services/EntityService";
|
|
25
|
+
import StoreItemService from "../../../../services/store/StoreItemService";
|
|
26
|
+
import { InlinePopupButton } from "@web-atoms/web-controls/dist/basic/InlinePopup";
|
|
27
|
+
import { MenuItem } from "@web-atoms/web-controls/dist/basic/PopupButton";
|
|
28
|
+
import MasterDetailPage from "@web-atoms/web-controls/dist/mobile-app/MasterDetailPage";
|
|
29
|
+
import ProductHtmlEditor from "./html/ProductHtmlEditorPage";
|
|
30
|
+
import { Offers } from "./html/Offsers";
|
|
31
|
+
import { Specifications } from "./html/Specifications";
|
|
19
32
|
|
|
20
33
|
export default class ProductEditor extends AtomControl {
|
|
21
34
|
|
|
35
|
+
@BindableProperty
|
|
36
|
+
productID: number = null;
|
|
37
|
+
|
|
22
38
|
@BindableProperty
|
|
23
39
|
model: IStoreItem = null;
|
|
24
40
|
|
|
41
|
+
@InjectProperty
|
|
42
|
+
storeItemService: StoreItemService;
|
|
43
|
+
|
|
25
44
|
onPropertyChanged(name: string): void {
|
|
26
45
|
super.onPropertyChanged(name);
|
|
27
46
|
switch(name) {
|
|
28
47
|
case "model":
|
|
29
48
|
this.app.runAsync(() => this.init());
|
|
30
49
|
break;
|
|
50
|
+
case "productID":
|
|
51
|
+
this.app.runAsync(() => this.loadProduct());
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async loadProduct() {
|
|
57
|
+
if (!this.productID) {
|
|
58
|
+
return;
|
|
31
59
|
}
|
|
60
|
+
this.model = await this.storeItemService.get(this.productID);
|
|
32
61
|
}
|
|
33
62
|
|
|
34
63
|
async init() {
|
|
@@ -70,41 +99,10 @@ export default class ProductEditor extends AtomControl {
|
|
|
70
99
|
value={Bind.twoWaysImmediate(() => this.model.description)}/>
|
|
71
100
|
</FormField>
|
|
72
101
|
</div>
|
|
73
|
-
<CollectionEditorEx
|
|
74
|
-
label="Prices"
|
|
75
|
-
model={this.model}
|
|
76
|
-
field={(x) => x.storeItemPrices}
|
|
77
|
-
addPage={EditItemPricePage}
|
|
78
|
-
itemRenderer={(item: IStoreItemPrice) => <div>
|
|
79
|
-
<div text={item.currency}/>
|
|
80
|
-
<div text={item.amount }/>
|
|
81
|
-
<div
|
|
82
|
-
title={DateFormats.withWeekDayAndTime(item.startDate)}
|
|
83
|
-
text={DateFormats.relative.short(item.startDate)}/>
|
|
84
|
-
{ item.endDate
|
|
85
|
-
? <div
|
|
86
|
-
title={DateFormats.withWeekDayAndTime(item.endDate)}
|
|
87
|
-
text={DateFormats.relative.short(item.endDate)}/>
|
|
88
|
-
: <div/>
|
|
89
|
-
}
|
|
90
|
-
{/* <Switch
|
|
91
|
-
checked={item.active}
|
|
92
|
-
/> */}
|
|
93
|
-
</div>}
|
|
94
|
-
/>
|
|
95
102
|
<TagChips
|
|
96
103
|
softDeleteProperty={Bind.oneWay(() => this.model.storeItemID > 0)}
|
|
97
104
|
items={Bind.twoWaysImmediate(() => this.model.storeItemTags)}
|
|
98
105
|
/>
|
|
99
|
-
<details
|
|
100
|
-
data-border="frame"
|
|
101
|
-
open={true}>
|
|
102
|
-
<summary text="Files"/>
|
|
103
|
-
<FolderViewControl
|
|
104
|
-
root={Bind.oneWay(() => this.model.fileFolder)}
|
|
105
|
-
/>
|
|
106
|
-
</details>
|
|
107
|
-
|
|
108
106
|
<CollectionEditorEx
|
|
109
107
|
style-display={Bind.oneWay(() => this.model.storeItemID > 0, false)}
|
|
110
108
|
label="Sizes"
|
|
@@ -142,7 +140,155 @@ export default class ProductEditor extends AtomControl {
|
|
|
142
140
|
}}
|
|
143
141
|
itemRenderer={(item: IStoreItem) => <div><a text={item.name}></a></div>}
|
|
144
142
|
/>
|
|
143
|
+
<CollectionEditorEx
|
|
144
|
+
label="Prices"
|
|
145
|
+
model={this.model}
|
|
146
|
+
field={(x) => x.storeItemPrices}
|
|
147
|
+
addPage={EditItemPricePage}
|
|
148
|
+
itemRenderer={(item: IStoreItemPrice) => <div>
|
|
149
|
+
<div text={item.currency}/>
|
|
150
|
+
<div text={item.amount }/>
|
|
151
|
+
<div
|
|
152
|
+
title={DateFormats.withWeekDayAndTime(item.startDate)}
|
|
153
|
+
text={DateFormats.relative.short(item.startDate)}/>
|
|
154
|
+
{ item.endDate
|
|
155
|
+
? <div
|
|
156
|
+
title={DateFormats.withWeekDayAndTime(item.endDate)}
|
|
157
|
+
text={DateFormats.relative.short(item.endDate)}/>
|
|
158
|
+
: <div/>
|
|
159
|
+
}
|
|
160
|
+
<CollectionEditorEx
|
|
161
|
+
label="Add Ons"
|
|
162
|
+
model={item}
|
|
163
|
+
field={(x) => x.addons}
|
|
164
|
+
itemFactory={() => StorePriceAddOn.create({
|
|
165
|
+
price: item,
|
|
166
|
+
priceID: item.priceID,
|
|
167
|
+
addOnItemID: null,
|
|
168
|
+
addOnItem: null,
|
|
169
|
+
inclusive: false,
|
|
170
|
+
print: true
|
|
171
|
+
})}
|
|
172
|
+
saveAfterAdd={false}
|
|
173
|
+
itemRenderer={(x: IStorePriceAddOn) => <div>
|
|
174
|
+
<ReferenceEditor
|
|
175
|
+
model={x}
|
|
176
|
+
field={(a) => a.addOnItem}
|
|
177
|
+
searchQuery={(q: Query<IStoreItem>, search) => (search
|
|
178
|
+
? q.where({ search: search + "%" }, (p) => (i) => Sql.text.iLike(i.name, p.search))
|
|
179
|
+
: q)}
|
|
180
|
+
suggestionRenderer={(i: IStoreItem) => <div><label text={i.name}/></div>}
|
|
181
|
+
itemRenderer={(a: IStoreItem) => <div>
|
|
182
|
+
<label text={a.name}/>
|
|
183
|
+
</div>}
|
|
184
|
+
/>
|
|
185
|
+
</div>}
|
|
186
|
+
/>
|
|
187
|
+
{/* <Switch
|
|
188
|
+
checked={item.active}
|
|
189
|
+
/> */}
|
|
190
|
+
</div>}
|
|
191
|
+
/>
|
|
192
|
+
<details
|
|
193
|
+
data-border="frame">
|
|
194
|
+
<summary text="Files"/>
|
|
195
|
+
<FolderViewControl
|
|
196
|
+
root={Bind.oneWay(() => this.model.fileFolder)}
|
|
197
|
+
/>
|
|
198
|
+
</details>
|
|
199
|
+
|
|
200
|
+
<CollectionEditorEx
|
|
201
|
+
style-display={Bind.oneWay(() => this.model.storeItemID > 0, false)}
|
|
202
|
+
label="Media"
|
|
203
|
+
layout="flex-wrap"
|
|
204
|
+
model={this.model}
|
|
205
|
+
field={(x) => x.mediaFiles}
|
|
206
|
+
footer={() => <div data-layout="row">
|
|
207
|
+
<UploadIconTextButton
|
|
208
|
+
{ ... UploadEvent.AttachUploadAction({
|
|
209
|
+
uploadEvent: "files-uploaded",
|
|
210
|
+
extra: Bind.oneWay(() => JSON.stringify({
|
|
211
|
+
parentID: this.model.folderID
|
|
212
|
+
}))
|
|
213
|
+
})}
|
|
214
|
+
/>
|
|
215
|
+
<InlinePopupButton
|
|
216
|
+
icon="fas fa-plus"
|
|
217
|
+
label="Add Html"
|
|
218
|
+
popup={() => <div>
|
|
219
|
+
<MenuItem
|
|
220
|
+
data-click-event="add-offer"
|
|
221
|
+
label="Add Offers"/>
|
|
222
|
+
<MenuItem
|
|
223
|
+
data-click-event="add-specifications"
|
|
224
|
+
label="Add Specifications"/>
|
|
225
|
+
</div>} ></InlinePopupButton>
|
|
226
|
+
</div>}
|
|
227
|
+
itemRenderer={(item: IStoreMediaFile) => <div>
|
|
228
|
+
{ item.isPreview
|
|
229
|
+
? <img
|
|
230
|
+
src={this.mediaFileUrl(item)}
|
|
231
|
+
/>
|
|
232
|
+
: <button
|
|
233
|
+
data-click-event="edit-media-file"
|
|
234
|
+
data-layout="link"
|
|
235
|
+
text={item.title}
|
|
236
|
+
/>
|
|
237
|
+
}
|
|
238
|
+
</div>}
|
|
239
|
+
{ ... FilesDragDrop({
|
|
240
|
+
uploadEvent: "files-uploaded",
|
|
241
|
+
extra: Bind.oneWay(() => JSON.stringify({
|
|
242
|
+
parentID: this.model.folderID
|
|
243
|
+
}))
|
|
244
|
+
})}
|
|
245
|
+
/>
|
|
145
246
|
|
|
146
247
|
</div>;
|
|
147
248
|
}
|
|
249
|
+
mediaFileUrl(item: IStoreMediaFile) {
|
|
250
|
+
if (item.appFile) {
|
|
251
|
+
return `/api/files/webp(200)/${item.appFileID}/${item.appFile.fileContentID}/${item.appFile.name}.webp`;
|
|
252
|
+
}
|
|
253
|
+
return signedImageUrl(item, 200);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@Action({ onEvent: "files-uploaded"})
|
|
257
|
+
async onFilesUploaded({ files }) {
|
|
258
|
+
this.model.mediaFiles ??= [];
|
|
259
|
+
for (const appFile of files) {
|
|
260
|
+
this.model.mediaFiles.add(StoreMediaFile.create({
|
|
261
|
+
appFile,
|
|
262
|
+
appFileID: appFile.appFileID
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@Action({ onEvent: ["add-offer", "add-specifications"]})
|
|
268
|
+
async onAddHtmlFile(data, e: Event) {
|
|
269
|
+
let title = "";
|
|
270
|
+
let template: () => string;
|
|
271
|
+
switch(e.type) {
|
|
272
|
+
case "addOffer":
|
|
273
|
+
title = "offer.html";
|
|
274
|
+
template = Offers;
|
|
275
|
+
break;
|
|
276
|
+
case "addSpecifications":
|
|
277
|
+
title = "specs.html";
|
|
278
|
+
template = Specifications;
|
|
279
|
+
break;
|
|
280
|
+
default:
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// create empty file...
|
|
285
|
+
const file = await this.storeItemService.getOrCreateMediaFile(this.model, title, template);
|
|
286
|
+
// this.openDetail(ProductHtmlEditor, { item: this.model, file });
|
|
287
|
+
this.element.dispatchEvent(new CustomEvent("editMediaFile", {
|
|
288
|
+
detail: file,
|
|
289
|
+
bubbles: true
|
|
290
|
+
}));
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
|
|
148
294
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
2
|
+
import DomToString from "@web-atoms/email-dom/dist/DomToString";
|
|
3
|
+
|
|
4
|
+
export const Offers = () => DomToString(<main>
|
|
5
|
+
<section styler-layout="column">
|
|
6
|
+
</section>
|
|
7
|
+
<section styler-layout="column">
|
|
8
|
+
</section>
|
|
9
|
+
</main>);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
|
|
2
|
+
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
3
|
+
import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
|
|
4
|
+
import { IAppFile } from "../../../../../model/model";
|
|
5
|
+
import HtmlPageEditor from "../../../../../site-editor/editor/HtmlPageEditor";
|
|
6
|
+
import ChooseMediaPage from "../../../../../web/page/files/media/ChooseMediaPage";
|
|
7
|
+
import CloudFileService from "../../../../../web/page/files/service/CloudFileService";
|
|
8
|
+
import { imageUrl, srcSetUrl, storeFileUrl } from "../../../../fileUrl";
|
|
9
|
+
|
|
10
|
+
export default class ProductHtmlEditor extends HtmlPageEditor {
|
|
11
|
+
|
|
12
|
+
@BindableProperty
|
|
13
|
+
public folder: IAppFile = null;
|
|
14
|
+
|
|
15
|
+
@InjectProperty
|
|
16
|
+
private cloudFileService: CloudFileService;
|
|
17
|
+
|
|
18
|
+
async changeImage() {
|
|
19
|
+
const files: { file: IAppFile, size: number}[] = await PageNavigator.pushPageForResult(ChooseMediaPage, {
|
|
20
|
+
folder: this.folder,
|
|
21
|
+
accept: "image/*",
|
|
22
|
+
multiple: true,
|
|
23
|
+
selected: this.selection.element
|
|
24
|
+
});
|
|
25
|
+
const images = files.map(({ file, size}) => {
|
|
26
|
+
const src = storeFileUrl(this.folder.appFileID, file, `webp(${size})`, `${file.name}.${size}.webp`);
|
|
27
|
+
const srcset = srcSetUrl(this.folder, file, (folder, f, s) => storeFileUrl(this.folder.appFileID, file, `webp(${s})`, `${file.name}.${s}.webp`));
|
|
28
|
+
return { src, "data-src-set": srcset };
|
|
29
|
+
});
|
|
30
|
+
await this.insertImage( ... images);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected async setStylerSheet() {
|
|
34
|
+
// do nothing
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ContentPage } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
|
|
2
|
+
import { IStoreItem, IStoreMediaFile } from "../../../../../model/model";
|
|
3
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
4
|
+
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
5
|
+
import Loader from "../../../../controls/Loader";
|
|
6
|
+
import { signedUrl } from "../../../../fileUrl";
|
|
7
|
+
import FetchBuilder from "@web-atoms/core/dist/services/FetchBuilder";
|
|
8
|
+
import HtmlPageEditor from "../../../../../site-editor/editor/HtmlPageEditor";
|
|
9
|
+
import ProductHtmlEditor from "./ProductHtmlEditor";
|
|
10
|
+
import { StylerSet } from "../../../../../site-editor/styler/StylerSet";
|
|
11
|
+
import PageNavigator from "@web-atoms/web-controls/dist/PageNavigator";
|
|
12
|
+
import CodeEditorPage from "../../../../../code-editor/CodeEditorPage";
|
|
13
|
+
import Action from "@web-atoms/core/dist/view-model/Action";
|
|
14
|
+
import { SaveIconTextButton } from "../../../../controls/buttons/IconButton";
|
|
15
|
+
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
16
|
+
import CloudFileService from "../../../../../web/page/files/service/CloudFileService";
|
|
17
|
+
import EntityService from "../../../../../services/EntityService";
|
|
18
|
+
|
|
19
|
+
const wrap = (styleText, body) => `
|
|
20
|
+
<!DOCTYPE html>
|
|
21
|
+
<html>
|
|
22
|
+
<style styler-style-sheet="styler-style-sheet">
|
|
23
|
+
${styleText}
|
|
24
|
+
</style>
|
|
25
|
+
<body>
|
|
26
|
+
${body}
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export default class ProductHtmlEditorPage extends ContentPage<{ item: IStoreItem, file: IStoreMediaFile }> {
|
|
32
|
+
|
|
33
|
+
storeItem: IStoreItem;
|
|
34
|
+
|
|
35
|
+
mediaFile: IStoreMediaFile;
|
|
36
|
+
html: string;
|
|
37
|
+
htmlEditor: HtmlPageEditor;
|
|
38
|
+
pageContent: string;
|
|
39
|
+
|
|
40
|
+
@InjectProperty
|
|
41
|
+
private cloudFileService: CloudFileService;
|
|
42
|
+
private originalHtml: string;
|
|
43
|
+
|
|
44
|
+
async init() {
|
|
45
|
+
|
|
46
|
+
this.renderer = <div>
|
|
47
|
+
<Loader/>
|
|
48
|
+
</div>;
|
|
49
|
+
|
|
50
|
+
this.storeItem = this.parameters.item;
|
|
51
|
+
this.mediaFile = this.parameters.file;
|
|
52
|
+
|
|
53
|
+
const htmlMain = this.mediaFile.fileContentID
|
|
54
|
+
? await FetchBuilder.get(signedUrl(this.mediaFile)).responseAsText()
|
|
55
|
+
: "<main>Content</main>";
|
|
56
|
+
|
|
57
|
+
this.originalHtml = htmlMain;
|
|
58
|
+
|
|
59
|
+
const css = StylerSet.instance.toString();
|
|
60
|
+
|
|
61
|
+
this.html = wrap(css, htmlMain);
|
|
62
|
+
|
|
63
|
+
this.renderer = <div>
|
|
64
|
+
<ProductHtmlEditor
|
|
65
|
+
data-position="absolute-fill"
|
|
66
|
+
folder={this.storeItem.store.folder}
|
|
67
|
+
presenter={Bind.presenter((c) => this.htmlEditor = c)}
|
|
68
|
+
event-html-page-changed={(ce: CustomEvent<string>) => this.pageContent = ce.detail}
|
|
69
|
+
htmlPage={this.html}
|
|
70
|
+
/>
|
|
71
|
+
</div>;
|
|
72
|
+
|
|
73
|
+
this.footerRenderer = () => <div
|
|
74
|
+
data-layout="header-row"
|
|
75
|
+
style-display={Bind.oneWay(() => this.pageContent !== this.html)}>
|
|
76
|
+
<SaveIconTextButton
|
|
77
|
+
event-click={() => this.savePage()}
|
|
78
|
+
text="Save"
|
|
79
|
+
/>
|
|
80
|
+
<SaveIconTextButton
|
|
81
|
+
event-click={() => this.savePage(true)}
|
|
82
|
+
text="Save and Close"
|
|
83
|
+
/>
|
|
84
|
+
</div>;
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Action({})
|
|
89
|
+
async savePage(close = false) {
|
|
90
|
+
if (!this.htmlEditor.lastCommittedBody) {
|
|
91
|
+
if (close) {
|
|
92
|
+
this.close(this.mediaFile);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const { fileContentID } = await this.cloudFileService.saveFile({
|
|
97
|
+
appFileID: this.mediaFile.appFileID,
|
|
98
|
+
content: new File([this.htmlEditor.lastCommittedBody], this.parameters.file.title, { type: "text/html" })
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.mediaFile.fileContentID = fileContentID;
|
|
102
|
+
const es = this.resolve(EntityService);
|
|
103
|
+
await es.save(this.mediaFile, (c) => c);
|
|
104
|
+
if (close) {
|
|
105
|
+
this.close(this.mediaFile);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Action({ onEvent: "edit-code"})
|
|
110
|
+
async editCode() {
|
|
111
|
+
const content = await PageNavigator.pushPageForResult(CodeEditorPage, {
|
|
112
|
+
fileName: this.parameters.file.title,
|
|
113
|
+
content: this.htmlEditor.lastCommittedHtml ?? this.htmlEditor.htmlPage
|
|
114
|
+
});
|
|
115
|
+
this.pageContent = content;
|
|
116
|
+
this.htmlEditor.htmlPage = content;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
protected hide(): void {
|
|
120
|
+
this.pageContent = this.htmlEditor?.lastCommittedHtml ?? this.htmlEditor?.htmlPage;
|
|
121
|
+
super.hide();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
protected show(): void {
|
|
125
|
+
super.show();
|
|
126
|
+
if (this.pageContent) {
|
|
127
|
+
setTimeout(() => this.htmlEditor.htmlPage = this.pageContent, 400);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
2
|
+
import DomToString from "@web-atoms/email-dom/dist/DomToString";
|
|
3
|
+
|
|
4
|
+
export const Specifications = () => DomToString(<main>
|
|
5
|
+
<section styler-layout="columns-2">
|
|
6
|
+
<table>
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<th colspan={2}>Spec 1</th>
|
|
10
|
+
</tr>
|
|
11
|
+
</thead>
|
|
12
|
+
<tbody>
|
|
13
|
+
<tr>
|
|
14
|
+
<td>Size</td>
|
|
15
|
+
<td>Medium</td>
|
|
16
|
+
</tr>
|
|
17
|
+
<tr>
|
|
18
|
+
<td>Color</td>
|
|
19
|
+
<td>Transparent</td>
|
|
20
|
+
</tr>
|
|
21
|
+
</tbody>
|
|
22
|
+
</table>
|
|
23
|
+
<table>
|
|
24
|
+
<thead>
|
|
25
|
+
<tr>
|
|
26
|
+
<th colspan={2}>Spec 1</th>
|
|
27
|
+
</tr>
|
|
28
|
+
</thead>
|
|
29
|
+
<tbody>
|
|
30
|
+
<tr>
|
|
31
|
+
<td>Size</td>
|
|
32
|
+
<td>Medium</td>
|
|
33
|
+
</tr>
|
|
34
|
+
<tr>
|
|
35
|
+
<td>Color</td>
|
|
36
|
+
<td>Transparent</td>
|
|
37
|
+
</tr>
|
|
38
|
+
</tbody>
|
|
39
|
+
</table>
|
|
40
|
+
</section>
|
|
41
|
+
</main>);
|
|
@@ -242,7 +242,7 @@ export default class WebSiteStudioPage extends ContentPage {
|
|
|
242
242
|
@Action({ onEvent: "edit-code"})
|
|
243
243
|
async editCode() {
|
|
244
244
|
const content = await PageNavigator.pushPageForResult(CodeEditorPage, {
|
|
245
|
-
|
|
245
|
+
fileName: this.selectedFile.name,
|
|
246
246
|
content: this.htmlEditor.lastCommittedHtml ?? this.htmlEditor.htmlPage
|
|
247
247
|
});
|
|
248
248
|
this.pageContent = content;
|