@social-mail/social-mail-client 1.9.55 → 1.9.56

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 (46) hide show
  1. package/dist/admin/AdminAppIndex.pack.global.css +1 -1
  2. package/dist/admin/AdminAppIndex.pack.global.css.map +1 -1
  3. package/dist/admin/AdminAppIndex.pack.js +92 -48
  4. package/dist/admin/AdminAppIndex.pack.js.map +1 -1
  5. package/dist/admin/AdminAppIndex.pack.min.js +1 -1
  6. package/dist/admin/AdminAppIndex.pack.min.js.map +1 -1
  7. package/dist/common/commands/CommonCommands.d.ts.map +1 -1
  8. package/dist/common/commands/CommonCommands.js.map +1 -1
  9. package/dist/common/controls/tree/TreeView.d.ts +1 -0
  10. package/dist/common/controls/tree/TreeView.d.ts.map +1 -1
  11. package/dist/common/controls/tree/TreeView.global.css +1 -1
  12. package/dist/common/controls/tree/TreeView.global.css.map +1 -1
  13. package/dist/common/controls/tree/TreeView.js +7 -1
  14. package/dist/common/controls/tree/TreeView.js.map +1 -1
  15. package/dist/common/pages/files/service/CloudFileService.d.ts +4 -0
  16. package/dist/common/pages/files/service/CloudFileService.d.ts.map +1 -1
  17. package/dist/common/pages/files/service/CloudFileService.js +41 -3
  18. package/dist/common/pages/files/service/CloudFileService.js.map +1 -1
  19. package/dist/site-editor-app/SiteEditorApp.pack.global.css +1 -1
  20. package/dist/site-editor-app/SiteEditorApp.pack.global.css.map +1 -1
  21. package/dist/site-editor-app/SiteEditorApp.pack.js +143 -64
  22. package/dist/site-editor-app/SiteEditorApp.pack.js.map +1 -1
  23. package/dist/site-editor-app/SiteEditorApp.pack.min.js +1 -1
  24. package/dist/site-editor-app/SiteEditorApp.pack.min.js.map +1 -1
  25. package/dist/site-editor-app/commands/SiteEditorCommands.d.ts +1 -0
  26. package/dist/site-editor-app/commands/SiteEditorCommands.d.ts.map +1 -1
  27. package/dist/site-editor-app/commands/SiteEditorCommands.js +2 -2
  28. package/dist/site-editor-app/commands/SiteEditorCommands.js.map +1 -1
  29. package/dist/site-editor-app/pages/websites/studio/WebSiteStudioPage.d.ts +2 -0
  30. package/dist/site-editor-app/pages/websites/studio/WebSiteStudioPage.d.ts.map +1 -1
  31. package/dist/site-editor-app/pages/websites/studio/WebSiteStudioPage.js +49 -14
  32. package/dist/site-editor-app/pages/websites/studio/WebSiteStudioPage.js.map +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/dist/web/AppIndex.pack.global.css +1 -1
  35. package/dist/web/AppIndex.pack.global.css.map +1 -1
  36. package/dist/web/AppIndex.pack.js +92 -48
  37. package/dist/web/AppIndex.pack.js.map +1 -1
  38. package/dist/web/AppIndex.pack.min.js +1 -1
  39. package/dist/web/AppIndex.pack.min.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/common/commands/CommonCommands.ts +0 -14
  42. package/src/common/controls/tree/TreeView.global.css +6 -1
  43. package/src/common/controls/tree/TreeView.tsx +10 -1
  44. package/src/common/pages/files/service/CloudFileService.ts +50 -1
  45. package/src/site-editor-app/commands/SiteEditorCommands.ts +2 -2
  46. package/src/site-editor-app/pages/websites/studio/WebSiteStudioPage.tsx +45 -32
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-client",
3
- "version": "1.9.55",
3
+ "version": "1.9.56",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -43,20 +43,6 @@ export default class CommonCommands extends Commands {
43
43
  openPage: () => import("../pages/websites/detail/WebSiteDetail")
44
44
  });
45
45
 
46
-
47
- // static manageWebSite = Command.create({
48
- // route: "/studio/manage/{id}",
49
- // routeOrder: 100,
50
- // openPage: () => import("../pages/websites/manage/ManageWebSitePage")
51
- // });
52
-
53
-
54
- // static editWebSite = Command.create({
55
- // route: "/studio/edit/{id}",
56
- // routeOrder: 100,
57
- // openPage: () => import("../pages/websites/studio/WebSiteStudioPage")
58
- // });
59
-
60
46
  static changePassword = Command.create({
61
47
  route: "/user/change-password",
62
48
  pushPage: () => import("../pages/user/change-password/ChangePasswordPage")
@@ -10,6 +10,11 @@
10
10
  align-items: center;
11
11
  color: green;
12
12
 
13
+ & > [data-layout=container] {
14
+ grid-row: 2;
15
+ grid-column: 1 / span 3;
16
+ }
17
+
13
18
  & > [data-element=action] {
14
19
  grid-row: 1;
15
20
  grid-column: 3;
@@ -21,7 +26,7 @@
21
26
  }
22
27
  }
23
28
 
24
- &:hover {
29
+ &:hover:not(:has([data-layout=tree-view-item]:hover)){
25
30
  background-color: var(--hover-color);
26
31
  color: var(--hover-text-color);
27
32
  & > [data-element=action] {
@@ -11,6 +11,7 @@ import "./TreeView.global.css";
11
11
 
12
12
  interface ITreeViewElement<T> extends HTMLDivElement, IDisposable {
13
13
  parentItem: T;
14
+ childrenContainer: HTMLElement;
14
15
  dataItem: T;
15
16
  }
16
17
 
@@ -231,6 +232,7 @@ export default class TreeView<T extends object = any> extends AtomControl {
231
232
  }
232
233
 
233
234
  protected createElement(item: T, parentItem?: T, insertIndex = -1) {
235
+
234
236
  const element = document.createElement("div") as ITreeViewElement<T>;
235
237
  element.setAttribute("data-layout", "tree-view-item");
236
238
 
@@ -243,6 +245,10 @@ export default class TreeView<T extends object = any> extends AtomControl {
243
245
  throw new Error("Children array must not be empty");
244
246
  }
245
247
 
248
+ const childContainer = document.createElement("div");
249
+ childContainer.setAttribute("data-layout", "container");
250
+ element.childrenContainer = childContainer;
251
+
246
252
  const watcher = children.watch((target, event, index, child) => {
247
253
  if (event === "add") {
248
254
  // set parent in the
@@ -312,6 +318,7 @@ export default class TreeView<T extends object = any> extends AtomControl {
312
318
  const header = document.createElement("div");
313
319
  header.setAttribute("data-element", "header");
314
320
  element.appendChild(header);
321
+ element.appendChild(childContainer);
315
322
 
316
323
  const parentElement = this.map.get(parentItem);
317
324
  let last = parentElement;
@@ -323,8 +330,10 @@ export default class TreeView<T extends object = any> extends AtomControl {
323
330
  }
324
331
  if (insertIndex >= 1) {
325
332
  last = this.map.get(siblings[insertIndex - 1]);
333
+ last.insertAdjacentElement("afterend", element);
334
+ } else {
335
+ parentElement.childrenContainer.insertAdjacentElement("beforeend", element);
326
336
  }
327
- last.insertAdjacentElement("afterend", element);
328
337
  const pad = Number(parentElement.getAttribute("data-pad") ?? "0") + 10;
329
338
  element.setAttribute("data-pad", `${pad}`);
330
339
  element.style.paddingLeft = `${pad}px`;
@@ -8,6 +8,8 @@ import { Sql } from "../../../../common/Sql";
8
8
  import SocialMailApp from "../../../../common/SocialMailApp";
9
9
  import LocalFileService from "../../../../services/files/LocalFileService";
10
10
  import Query from "@web-atoms/entity/dist/services/Query";
11
+ import { CacheTTL } from "../../../cache/CacheTTL";
12
+ import CacheVersions from "../../../cache/CacheVersions";
11
13
 
12
14
  const hideActivityIndicator = true;
13
15
 
@@ -132,6 +134,49 @@ export default class CloudFileService {
132
134
  return folder;
133
135
  }
134
136
 
137
+ async webRoot({ id, cancelToken = null}) {
138
+
139
+ const root = await this.entityService.query(AppFile)
140
+ .where({ id }, (p) => (x) => x.appFileID === p.id)
141
+ .firstOrDefault( {
142
+ cacheSeconds: CacheTTL.seconds.oneHour,
143
+ cacheVersion: CacheVersions.site,
144
+ cancelToken
145
+ });
146
+
147
+ const path = root.path + "%";
148
+
149
+ const files = await this.entityService.query(AppFile)
150
+ .where({ path }, (p) => (x) => Sql.text.like(x.path, p.path)
151
+ && x.isDeleted === false
152
+ && (x.contentType === "text/html" || x.isFolder === true)
153
+ )
154
+ .include((x) => x.creator)
155
+ .include((x) => x.children)
156
+ .toArray({ cancelToken });
157
+
158
+ root.children = [];
159
+ for (const file of files) {
160
+ if (file.parentID === id) {
161
+ root.children.push(file);
162
+ file.parent = root;
163
+ }
164
+ }
165
+
166
+ root.children?.sort((a, b) =>
167
+ a.isFolder && b.isFolder
168
+ ? a.name.localeCompare(b.name)
169
+ : (a.isFolder
170
+ ? Number.MIN_SAFE_INTEGER
171
+ : (b.isFolder
172
+ ? Number.MAX_SAFE_INTEGER
173
+ : a.name.localeCompare(b.name)
174
+ )
175
+ )
176
+ );
177
+ return root;
178
+ }
179
+
135
180
  async root({ id, templates = false, cancelToken = null}) {
136
181
 
137
182
  let root: IAppFile;
@@ -387,7 +432,11 @@ export default class CloudFileService {
387
432
  }
388
433
 
389
434
  getFilePath(root: IAppFile, selectedFile: IAppFile) {
390
- const [ ignore, ... segments] = selectedFile.path.split("/") as any[];
435
+ const all = selectedFile.path.split("/") as any[];
436
+ while(all[0] !== root.appFileID) {
437
+ all.splice(0, 1);
438
+ }
439
+ const segments = all.slice(1);
391
440
  let path = "";
392
441
  for (const iterator of segments) {
393
442
  if (selectedFile.appFileID === iterator) {
@@ -14,8 +14,8 @@ export default class SiteEditorCommands extends CommonCommands {
14
14
  });
15
15
 
16
16
  static editWebSite = Command.create({
17
- route: "/social-mail/studio/edit/{id}",
18
- routeOrder: 100,
17
+ route: "/social-mail/studio/edit/{id}/{*page}",
18
+ routeOrder: 1000,
19
19
  openPage: () => import("../pages/websites/studio/WebSiteStudioPage")
20
20
  });
21
21
 
@@ -37,10 +37,12 @@ import StudioToolBar from "./tool-bar/StudioToolBar";
37
37
  import BasicShapes from "../../../../site-editor/tools/basic/BasicShapes";
38
38
  import StudioLayers from "./layers/StudioLayers";
39
39
  import Designs from "../../../../site-editor/tools/designs/Designs";
40
+ import SiteEditorCommands from "../../../commands/SiteEditorCommands";
41
+ import Loader from "../../../../common/controls/Loader";
40
42
 
41
43
  export default class WebSiteStudioPage extends ContentPage {
42
44
 
43
- public parameters: { id: number; templates?: boolean; };
45
+ public parameters: { id: number; templates?: boolean; page?: string; };
44
46
 
45
47
  public selectedFile: IAppFile;
46
48
 
@@ -72,8 +74,13 @@ export default class WebSiteStudioPage extends ContentPage {
72
74
  private htmlEditor: HtmlPageEditor;
73
75
 
74
76
  async init() {
77
+
78
+ this.renderer = <div>
79
+ <Loader/>
80
+ </div>;
81
+
75
82
  this.search = "";
76
- this.root = await this.cloudFileService.root(this.parameters);
83
+ this.root = await this.cloudFileService.webRoot(this.parameters);
77
84
 
78
85
  // find parent...
79
86
  this.element.dispatchEvent(new CustomEvent("iconClick", { bubbles: true}));
@@ -97,8 +104,29 @@ export default class WebSiteStudioPage extends ContentPage {
97
104
  return;
98
105
  }
99
106
 
100
- const indexHtml = this.root.children.find((x) => x.name === "index.html");
101
- this.selectedFile = indexHtml;
107
+
108
+ if (this.parameters?.page) {
109
+ // find page...
110
+
111
+ let { page } = this.parameters;
112
+ while(page.startsWith("/")) {
113
+ page = page.substring(1);
114
+ }
115
+ let segments = page.split("/");
116
+ const finalPage = segments.pop();
117
+ let root = this.root;
118
+ while(segments.length) {
119
+ const [first, ... all] = segments;
120
+ segments = all;
121
+ root = root.children.find((x) => x.name === first);
122
+ }
123
+ const finalFile = root.children.find((x) => x.name === finalPage);
124
+ this.selectedFile = finalFile;
125
+
126
+ } else {
127
+ const indexHtml = this.root.children.find((x) => x.name === "index.html");
128
+ this.selectedFile = indexHtml;
129
+ }
102
130
 
103
131
  const domain = this.webSite.channelDomains?.[0]?.domain?.domain;
104
132
  const infoEmail = domain ? `info@${domain.name}` : void 0;
@@ -106,6 +134,8 @@ export default class WebSiteStudioPage extends ContentPage {
106
134
 
107
135
  // const baseUrl = apiPath(`/api/site/draft/${this.root.appFileID}/`);
108
136
 
137
+ const htmlFile = await this.downloadHtml(this.selectedFile, this.cancelToken);
138
+
109
139
  this.titleRenderer = () => <div data-layout="row">
110
140
 
111
141
  <div text={this.root.name}/>
@@ -183,8 +213,9 @@ export default class WebSiteStudioPage extends ContentPage {
183
213
  root={this.root}
184
214
  class="folder-tree"
185
215
  accept="text/html"
216
+ event-select-item={(c) => this.changeFile()}
186
217
  presenter={Bind.presenter((c) => this.folderTree = c)}
187
- selectedItem={Bind.twoWaysImmediate(() => this.selectedFile)}
218
+ selectedItem={this.selectedFile}
188
219
  menuActions={(x: IAppFile) => !x.isFolder
189
220
  ? ( /\.(htm|html)$/i.test(x.name)
190
221
  ? [
@@ -235,14 +266,12 @@ export default class WebSiteStudioPage extends ContentPage {
235
266
  />
236
267
  <WebSitePageEditor
237
268
  class="file-list"
238
- selectedFile={Bind.oneWay(() => this.selectedFile)}
239
- baseUrl={Bind.oneWay(() => apiPath(`${this.root.url}${this.cloudFileService.getFilePath(this.root, this.selectedFile)}`))}
269
+ selectedFile={this.selectedFile}
270
+ baseUrl={apiPath(`${this.root.url}${this.cloudFileService.getFilePath(this.root, this.selectedFile)}`)}
240
271
  folder={this.root}
241
272
  presenter={Bind.presenter((c) => this.htmlEditor = c)}
242
273
  event-html-page-changed={(ce: CustomEvent<string>) => this.modified = true}
243
- htmlPage={Bind.oneWayAsync((s, e, cancelToken) => this.selectedFile
244
- ? this.downloadHtml(this.selectedFile, cancelToken)
245
- : void 0)}
274
+ htmlPage={htmlFile}
246
275
  />
247
276
  </div>;
248
277
 
@@ -253,6 +282,12 @@ export default class WebSiteStudioPage extends ContentPage {
253
282
  </div>;
254
283
  }
255
284
 
285
+ changeFile() {
286
+ const file = this.folderTree.selectedItem as IAppFile;
287
+ const folder = this.cloudFileService.getFilePath(this.root, file) ?? "";
288
+ SiteEditorCommands.editWebSite.dispatch({ id: this.parameters.id, page: folder + file.name });
289
+ }
290
+
256
291
  @Action({ onEvent: "keydown"})
257
292
  onKeyDown(d, e: KeyboardEvent) {
258
293
  if(e.ctrlKey || e.metaKey) {
@@ -271,28 +306,6 @@ export default class WebSiteStudioPage extends ContentPage {
271
306
  .asText(true);
272
307
  this.pageContent = text;
273
308
  return text;
274
- // const parser = new DOMParser();
275
- // const doc = parser.parseFromString(text, "text/html");
276
- // const injects = Array.from(doc.documentElement.querySelectorAll("inject")) as HTMLElement[];
277
- // for (const e of injects) {
278
- // let src = e.getAttribute("src");
279
- // if(src.startsWith("/")) {
280
- // src = src.substring(1);
281
- // } else {
282
- // // will do it later
283
- // }
284
- // const injectedFile = await this.cloudFileService.children(this.root.appFileID, src)
285
- // .firstOrDefault();
286
- // text = await FetchBuilder.get(injectedFile.downloadUrl).asText();
287
- // const dom = parser.parseFromString(text, "text/html");
288
- // const children = Array.from(dom.body.children);
289
- // e.innerHTML = "";
290
- // for (const iterator of children) {
291
- // iterator.setAttribute("contentEditable", "false");
292
- // e.appendChild(iterator);
293
- // }
294
- // }
295
- // return doc.documentElement.outerHTML;
296
309
  }
297
310
 
298
311
  async createIndexHtml() {