underpost 2.8.881 → 2.8.883
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/.github/workflows/release.cd.yml +1 -2
- package/README.md +50 -36
- package/bin/db.js +1 -4
- package/cli.md +86 -86
- package/conf.js +1 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +6 -6
- package/manifests/maas/device-scan.sh +1 -1
- package/package.json +1 -1
- package/src/api/document/document.service.js +9 -1
- package/src/cli/repository.js +2 -0
- package/src/client/components/core/Auth.js +258 -89
- package/src/client/components/core/BtnIcon.js +10 -1
- package/src/client/components/core/CssCore.js +36 -27
- package/src/client/components/core/Docs.js +188 -85
- package/src/client/components/core/LoadingAnimation.js +5 -10
- package/src/client/components/core/Modal.js +262 -120
- package/src/client/components/core/ObjectLayerEngine.js +154 -158
- package/src/client/components/core/Panel.js +2 -0
- package/src/client/components/core/PanelForm.js +94 -60
- package/src/client/components/core/Router.js +15 -15
- package/src/client/components/core/ToolTip.js +83 -19
- package/src/client/components/core/Translate.js +1 -1
- package/src/client/components/core/VanillaJs.js +4 -3
- package/src/client/components/core/windowGetDimensions.js +202 -0
- package/src/client/components/default/MenuDefault.js +11 -0
- package/src/client/ssr/Render.js +1 -1
- package/src/index.js +1 -1
- package/src/runtime/lampp/Lampp.js +253 -128
- package/src/server/auth.js +68 -17
- package/src/server/crypto.js +195 -76
- package/src/server/peer.js +47 -5
- package/src/server/process.js +85 -1
- package/src/server/runtime.js +13 -32
- package/test/crypto.test.js +117 -0
- package/src/runtime/xampp/Xampp.js +0 -83
|
@@ -1,113 +1,112 @@
|
|
|
1
1
|
import { darkTheme, renderChessPattern } from './Css.js';
|
|
2
|
-
|
|
3
|
-
const templateHTML = html`
|
|
4
|
-
<style>
|
|
5
|
-
:host {
|
|
6
|
-
--border: 1px solid #bbb;
|
|
7
|
-
--gap: 8px;
|
|
8
|
-
display: inline-block;
|
|
9
|
-
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
|
|
10
|
-
}
|
|
11
|
-
.wrap {
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
gap: var(--gap);
|
|
15
|
-
align-items: flex-start;
|
|
16
|
-
}
|
|
17
|
-
.canvas-frame {
|
|
18
|
-
border: var(--border);
|
|
19
|
-
display: inline-block;
|
|
20
|
-
line-height: 0;
|
|
21
|
-
position: relative;
|
|
22
|
-
background: transparent;
|
|
23
|
-
}
|
|
24
|
-
canvas.canvas-layer {
|
|
25
|
-
display: block;
|
|
26
|
-
image-rendering: pixelated;
|
|
27
|
-
touch-action: none;
|
|
28
|
-
cursor: crosshair;
|
|
29
|
-
}
|
|
30
|
-
canvas.grid-layer {
|
|
31
|
-
position: absolute;
|
|
32
|
-
left: 0;
|
|
33
|
-
top: 0;
|
|
34
|
-
pointer-events: none;
|
|
35
|
-
}
|
|
36
|
-
.toolbar {
|
|
37
|
-
display: flex;
|
|
38
|
-
gap: 8px;
|
|
39
|
-
flex-wrap: wrap;
|
|
40
|
-
align-items: center;
|
|
41
|
-
}
|
|
42
|
-
.toolbar label {
|
|
43
|
-
display: inline-flex;
|
|
44
|
-
gap: 6px;
|
|
45
|
-
align-items: center;
|
|
46
|
-
}
|
|
47
|
-
.group {
|
|
48
|
-
display: inline-flex;
|
|
49
|
-
gap: 6px;
|
|
50
|
-
align-items: center;
|
|
51
|
-
}
|
|
52
|
-
</style>
|
|
53
|
-
|
|
54
|
-
<div class="wrap">
|
|
55
|
-
<div class="toolbar">
|
|
56
|
-
<input type="color" part="color" title="Brush color" value="#000000" />
|
|
57
|
-
<select part="tool">
|
|
58
|
-
<option value="pencil">pencil</option>
|
|
59
|
-
<option value="eraser">eraser</option>
|
|
60
|
-
<option value="fill">fill</option>
|
|
61
|
-
<option value="eyedropper">eyedropper</option>
|
|
62
|
-
</select>
|
|
63
|
-
|
|
64
|
-
<label>brush <input type="number" part="brush-size" min="1" value="1" /></label>
|
|
65
|
-
<label>pixel-size <input type="number" part="pixel-size" min="1" value="16" /></label>
|
|
66
|
-
|
|
67
|
-
<!-- New: cell dimensions (width x height) -->
|
|
68
|
-
<label
|
|
69
|
-
>cells <input type="number" part="cell-width" min="1" value="16" style="width:6ch" /> x
|
|
70
|
-
<input type="number" part="cell-height" min="1" value="16" style="width:6ch"
|
|
71
|
-
/></label>
|
|
72
|
-
|
|
73
|
-
<label class="switch"> <input type="checkbox" part="toggle-grid" /> grid </label>
|
|
74
|
-
|
|
75
|
-
<!-- New: transform tools -->
|
|
76
|
-
<div class="group">
|
|
77
|
-
<button part="flip-h" title="Flip horizontally">Flip H</button>
|
|
78
|
-
<button part="flip-v" title="Flip vertically">Flip V</button>
|
|
79
|
-
<button part="rot-ccw" title="Rotate -90°">⟲</button>
|
|
80
|
-
<button part="rot-cw" title="Rotate +90°">⟳</button>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
<label
|
|
84
|
-
>opacity <input type="range" part="opacity" min="0" max="255" value="255" style="width:10rem" /><input
|
|
85
|
-
type="number"
|
|
86
|
-
part="opacity-num"
|
|
87
|
-
min="0"
|
|
88
|
-
max="255"
|
|
89
|
-
value="255"
|
|
90
|
-
style="width:5ch;margin-left:4px"
|
|
91
|
-
/></label>
|
|
92
|
-
|
|
93
|
-
<button part="clear" title="Clear (make fully transparent)">Clear</button>
|
|
94
|
-
|
|
95
|
-
<button part="export">Export PNG</button>
|
|
96
|
-
<button part="export-json">Export JSON</button>
|
|
97
|
-
<button part="import-json">Import JSON</button>
|
|
98
|
-
</div>
|
|
99
|
-
<div class="canvas-frame" style="${renderChessPattern()}">
|
|
100
|
-
<canvas part="canvas" class="canvas-layer"></canvas>
|
|
101
|
-
<canvas part="grid" class="grid-layer"></canvas>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
`;
|
|
2
|
+
import { append, htmls } from './VanillaJs.js';
|
|
105
3
|
|
|
106
4
|
class ObjectLayerEngineElement extends HTMLElement {
|
|
107
5
|
constructor() {
|
|
108
6
|
super();
|
|
109
7
|
this.attachShadow({ mode: 'open' });
|
|
110
|
-
this.shadowRoot.innerHTML =
|
|
8
|
+
this.shadowRoot.innerHTML = html`
|
|
9
|
+
<style>
|
|
10
|
+
:host {
|
|
11
|
+
--border: 1px solid #bbb;
|
|
12
|
+
--gap: 8px;
|
|
13
|
+
display: inline-block;
|
|
14
|
+
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;
|
|
15
|
+
}
|
|
16
|
+
.wrap {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: var(--gap);
|
|
20
|
+
align-items: flex-start;
|
|
21
|
+
}
|
|
22
|
+
.canvas-frame {
|
|
23
|
+
border: var(--border);
|
|
24
|
+
display: inline-block;
|
|
25
|
+
line-height: 0;
|
|
26
|
+
position: relative;
|
|
27
|
+
background: transparent;
|
|
28
|
+
}
|
|
29
|
+
canvas.canvas-layer {
|
|
30
|
+
display: block;
|
|
31
|
+
image-rendering: pixelated;
|
|
32
|
+
touch-action: none;
|
|
33
|
+
cursor: crosshair;
|
|
34
|
+
}
|
|
35
|
+
canvas.grid-layer {
|
|
36
|
+
position: absolute;
|
|
37
|
+
left: 0;
|
|
38
|
+
top: 0;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
}
|
|
41
|
+
.toolbar {
|
|
42
|
+
display: flex;
|
|
43
|
+
gap: 8px;
|
|
44
|
+
flex-wrap: wrap;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
47
|
+
.toolbar label {
|
|
48
|
+
display: inline-flex;
|
|
49
|
+
gap: 6px;
|
|
50
|
+
align-items: center;
|
|
51
|
+
}
|
|
52
|
+
.group {
|
|
53
|
+
display: inline-flex;
|
|
54
|
+
gap: 6px;
|
|
55
|
+
align-items: center;
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
58
|
+
|
|
59
|
+
<div class="wrap">
|
|
60
|
+
<div class="toolbar">
|
|
61
|
+
<input type="color" part="color" title="Brush color" value="#000000" />
|
|
62
|
+
<select part="tool">
|
|
63
|
+
<option value="pencil">pencil</option>
|
|
64
|
+
<option value="eraser">eraser</option>
|
|
65
|
+
<option value="fill">fill</option>
|
|
66
|
+
<option value="eyedropper">eyedropper</option>
|
|
67
|
+
</select>
|
|
68
|
+
|
|
69
|
+
<label>brush <input type="number" part="brush-size" min="1" value="1" /></label>
|
|
70
|
+
<label>pixel-size <input type="number" part="pixel-size" min="1" value="16" /></label>
|
|
71
|
+
|
|
72
|
+
<!-- New: cell dimensions (width x height) -->
|
|
73
|
+
<label
|
|
74
|
+
>cells <input type="number" part="cell-width" min="1" value="16" style="width:6ch" /> x
|
|
75
|
+
<input type="number" part="cell-height" min="1" value="16" style="width:6ch"
|
|
76
|
+
/></label>
|
|
77
|
+
|
|
78
|
+
<label class="switch"> <input type="checkbox" part="toggle-grid" /> grid </label>
|
|
79
|
+
|
|
80
|
+
<!-- New: transform tools -->
|
|
81
|
+
<div class="group">
|
|
82
|
+
<button part="flip-h" title="Flip horizontally">Flip H</button>
|
|
83
|
+
<button part="flip-v" title="Flip vertically">Flip V</button>
|
|
84
|
+
<button part="rot-ccw" title="Rotate -90°">⟲</button>
|
|
85
|
+
<button part="rot-cw" title="Rotate +90°">⟳</button>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<label
|
|
89
|
+
>opacity <input type="range" part="opacity" min="0" max="255" value="255" style="width:10rem" /><input
|
|
90
|
+
type="number"
|
|
91
|
+
part="opacity-num"
|
|
92
|
+
min="0"
|
|
93
|
+
max="255"
|
|
94
|
+
value="255"
|
|
95
|
+
style="width:5ch;margin-left:4px"
|
|
96
|
+
/></label>
|
|
97
|
+
|
|
98
|
+
<button part="clear" title="Clear (make fully transparent)">Clear</button>
|
|
99
|
+
|
|
100
|
+
<button part="export">Export PNG</button>
|
|
101
|
+
<button part="export-json">Export JSON</button>
|
|
102
|
+
<button part="import-json">Import JSON</button>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="canvas-frame" style="${renderChessPattern()}">
|
|
105
|
+
<canvas part="canvas" class="canvas-layer"></canvas>
|
|
106
|
+
<canvas part="grid" class="grid-layer"></canvas>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
`;
|
|
111
110
|
|
|
112
111
|
// DOM
|
|
113
112
|
this._pixelCanvas = this.shadowRoot.querySelector('canvas[part="canvas"]');
|
|
@@ -862,64 +861,61 @@ Example usage:
|
|
|
862
861
|
<object-layer-engine id="ole" width="20" height="12" pixel-size="20"></object-layer-engine>
|
|
863
862
|
*/
|
|
864
863
|
|
|
865
|
-
const template = document.createElement('template');
|
|
866
|
-
template.innerHTML = html`
|
|
867
|
-
<style>
|
|
868
|
-
:host {
|
|
869
|
-
display: block;
|
|
870
|
-
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial;
|
|
871
|
-
}
|
|
872
|
-
.wrap {
|
|
873
|
-
display: flex;
|
|
874
|
-
flex-direction: column;
|
|
875
|
-
gap: 8px;
|
|
876
|
-
}
|
|
877
|
-
.controls {
|
|
878
|
-
display: flex;
|
|
879
|
-
gap: 8px;
|
|
880
|
-
align-items: center;
|
|
881
|
-
flex-wrap: wrap;
|
|
882
|
-
}
|
|
883
|
-
.drop-area {
|
|
884
|
-
border: 2px dashed #999;
|
|
885
|
-
padding: 12px;
|
|
886
|
-
border-radius: 8px;
|
|
887
|
-
text-align: center;
|
|
888
|
-
color: #555;
|
|
889
|
-
user-select: none;
|
|
890
|
-
}
|
|
891
|
-
.drop-area.dragover {
|
|
892
|
-
border-color: #4a90e2;
|
|
893
|
-
color: #1a73e8;
|
|
894
|
-
background: rgba(74, 144, 226, 0.04);
|
|
895
|
-
}
|
|
896
|
-
input[type='file'] {
|
|
897
|
-
display: inline-block;
|
|
898
|
-
}
|
|
899
|
-
.hint {
|
|
900
|
-
font-size: 0.9rem;
|
|
901
|
-
color: #666;
|
|
902
|
-
}
|
|
903
|
-
</style>
|
|
904
|
-
|
|
905
|
-
<div class="wrap">
|
|
906
|
-
<div class="controls">
|
|
907
|
-
<label title="Load PNG file">
|
|
908
|
-
<input type="file" accept="image/png" part="file-input" />
|
|
909
|
-
<span class="btn">Choose PNG</span>
|
|
910
|
-
</label>
|
|
911
|
-
<div class="hint">Only PNG images accepted. Drop PNG onto the box below.</div>
|
|
912
|
-
</div>
|
|
913
|
-
|
|
914
|
-
<div class="drop-area" part="drop-area">Drop PNG here or click "Choose PNG"</div>
|
|
915
|
-
</div>
|
|
916
|
-
`;
|
|
917
|
-
|
|
918
864
|
class ObjectLayerPngLoader extends HTMLElement {
|
|
919
865
|
constructor() {
|
|
920
866
|
super();
|
|
921
867
|
this.attachShadow({ mode: 'open' });
|
|
922
|
-
this.shadowRoot.
|
|
868
|
+
this.shadowRoot.innerHTML = html`
|
|
869
|
+
<style>
|
|
870
|
+
:host {
|
|
871
|
+
display: block;
|
|
872
|
+
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial;
|
|
873
|
+
}
|
|
874
|
+
.wrap {
|
|
875
|
+
display: flex;
|
|
876
|
+
flex-direction: column;
|
|
877
|
+
gap: 8px;
|
|
878
|
+
}
|
|
879
|
+
.controls {
|
|
880
|
+
display: flex;
|
|
881
|
+
gap: 8px;
|
|
882
|
+
align-items: center;
|
|
883
|
+
flex-wrap: wrap;
|
|
884
|
+
}
|
|
885
|
+
.drop-area {
|
|
886
|
+
border: 2px dashed #999;
|
|
887
|
+
padding: 12px;
|
|
888
|
+
border-radius: 8px;
|
|
889
|
+
text-align: center;
|
|
890
|
+
color: #555;
|
|
891
|
+
user-select: none;
|
|
892
|
+
}
|
|
893
|
+
.drop-area.dragover {
|
|
894
|
+
border-color: #4a90e2;
|
|
895
|
+
color: #1a73e8;
|
|
896
|
+
background: rgba(74, 144, 226, 0.04);
|
|
897
|
+
}
|
|
898
|
+
input[type='file'] {
|
|
899
|
+
display: inline-block;
|
|
900
|
+
}
|
|
901
|
+
.hint {
|
|
902
|
+
font-size: 0.9rem;
|
|
903
|
+
color: #666;
|
|
904
|
+
}
|
|
905
|
+
</style>
|
|
906
|
+
|
|
907
|
+
<div class="wrap">
|
|
908
|
+
<div class="controls">
|
|
909
|
+
<label title="Load PNG file">
|
|
910
|
+
<input type="file" accept="image/png" part="file-input" />
|
|
911
|
+
<span class="btn">Choose PNG</span>
|
|
912
|
+
</label>
|
|
913
|
+
<div class="hint">Only PNG images accepted. Drop PNG onto the box below.</div>
|
|
914
|
+
</div>
|
|
915
|
+
|
|
916
|
+
<div class="drop-area" part="drop-area">Drop PNG here or click "Choose PNG"</div>
|
|
917
|
+
</div>
|
|
918
|
+
`;
|
|
923
919
|
|
|
924
920
|
this._fileInput = this.shadowRoot.querySelector('input[type="file"]');
|
|
925
921
|
this._dropArea = this.shadowRoot.querySelector('.drop-area');
|
|
@@ -131,6 +131,7 @@ const Panel = {
|
|
|
131
131
|
${await BtnIcon.Render({
|
|
132
132
|
class: `in flr main-btn-menu action-bar-box ${idPanel}-btn-tool ${idPanel}-btn-edit-${id}`,
|
|
133
133
|
label: html`<div class="abs center"><i class="fas fa-edit"></i></div>`,
|
|
134
|
+
useVisibilityHover: true,
|
|
134
135
|
tooltipHtml: await Badge.Render({
|
|
135
136
|
id: `tooltip-${idPanel}-${id}`,
|
|
136
137
|
text: `${Translate.Render(`edit`)}`,
|
|
@@ -141,6 +142,7 @@ const Panel = {
|
|
|
141
142
|
${await BtnIcon.Render({
|
|
142
143
|
class: `in flr main-btn-menu action-bar-box ${idPanel}-btn-tool ${idPanel}-btn-delete-${id}`,
|
|
143
144
|
label: html`<div class="abs center"><i class="fas fa-trash"></i></div>`,
|
|
145
|
+
useVisibilityHover: true,
|
|
144
146
|
tooltipHtml: await Badge.Render({
|
|
145
147
|
id: `tooltip-${idPanel}-${id}`,
|
|
146
148
|
text: `${Translate.Render(`delete`)}`,
|
|
@@ -42,6 +42,7 @@ const PanelForm = {
|
|
|
42
42
|
limit: 3, // Load 5 items per page
|
|
43
43
|
hasMore: true,
|
|
44
44
|
loading: false,
|
|
45
|
+
lasIdAvailable: null,
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
const formData = [
|
|
@@ -359,9 +360,10 @@ const PanelForm = {
|
|
|
359
360
|
panelData.data = [];
|
|
360
361
|
}
|
|
361
362
|
|
|
362
|
-
panelData.originData.push(...newInstance(result.data));
|
|
363
|
+
panelData.originData.push(...newInstance(result.data.data));
|
|
364
|
+
panelData.lasIdAvailable = result.data.lastId;
|
|
363
365
|
|
|
364
|
-
for (const documentObject of result.data) {
|
|
366
|
+
for (const documentObject of result.data.data) {
|
|
365
367
|
let mdFileId, fileId;
|
|
366
368
|
let mdBlob, fileBlob;
|
|
367
369
|
let mdPlain, filePlain;
|
|
@@ -407,9 +409,9 @@ const PanelForm = {
|
|
|
407
409
|
});
|
|
408
410
|
}
|
|
409
411
|
|
|
410
|
-
panelData.skip += result.data.length;
|
|
411
|
-
panelData.hasMore = result.data.length === panelData.limit;
|
|
412
|
-
if (result.data.length
|
|
412
|
+
panelData.skip += result.data.data.length;
|
|
413
|
+
panelData.hasMore = result.data.data.length === panelData.limit;
|
|
414
|
+
if (result.data.data.length === 0 || result.data.data.pop()._id === panelData.lasIdAvailable) {
|
|
413
415
|
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
414
416
|
panelData.hasMore = false;
|
|
415
417
|
}
|
|
@@ -474,75 +476,107 @@ const PanelForm = {
|
|
|
474
476
|
let firsUpdateEvent = false;
|
|
475
477
|
let lastCid;
|
|
476
478
|
let lastUserId;
|
|
479
|
+
let loadingGetData = false;
|
|
477
480
|
closeModalRouteChangeEvents[idPanel] = () => {
|
|
478
481
|
setTimeout(() => {
|
|
479
482
|
this.Data[idPanel].updatePanel();
|
|
480
483
|
});
|
|
481
484
|
};
|
|
482
|
-
this.Data[idPanel].updatePanel = async () => {
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
485
|
+
this.Data[idPanel].updatePanel = async (...args) => {
|
|
486
|
+
const _updatePanel = async (...args) => {
|
|
487
|
+
try {
|
|
488
|
+
const cid = getQueryParams().cid ? getQueryParams().cid : '';
|
|
489
|
+
const forceUpdate =
|
|
490
|
+
Elements.Data.user.main.model &&
|
|
491
|
+
Elements.Data.user.main.model.user &&
|
|
492
|
+
Elements.Data.user.main.model.user._id &&
|
|
493
|
+
lastUserId !== Elements.Data.user.main.model.user._id;
|
|
494
|
+
|
|
495
|
+
logger.warn(
|
|
496
|
+
{
|
|
497
|
+
idPanel,
|
|
498
|
+
cid,
|
|
499
|
+
forceUpdate,
|
|
500
|
+
},
|
|
501
|
+
JSON.stringify(Elements.Data.user.main.model.user, null, 4),
|
|
502
|
+
);
|
|
501
503
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
+
if (loadingGetData || (lastCid === cid && !forceUpdate)) return;
|
|
505
|
+
loadingGetData = true;
|
|
506
|
+
lastUserId = newInstance(Elements.Data.user.main.model.user._id);
|
|
507
|
+
lastCid = cid;
|
|
504
508
|
|
|
505
|
-
|
|
509
|
+
logger.warn('Init render panel data');
|
|
506
510
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
511
|
+
this.Data[idPanel] = {
|
|
512
|
+
...this.Data[idPanel],
|
|
513
|
+
originData: [],
|
|
514
|
+
data: [],
|
|
515
|
+
filesData: [],
|
|
516
|
+
limit: 3, // Load 5 items per page
|
|
517
|
+
hasMore: true,
|
|
518
|
+
loading: false,
|
|
519
|
+
};
|
|
514
520
|
|
|
515
|
-
|
|
521
|
+
if (cid) this.Data[idPanel].skip = 0;
|
|
516
522
|
|
|
517
|
-
|
|
523
|
+
const containerSelector = `.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`;
|
|
524
|
+
htmls(containerSelector, await renderSrrPanelData());
|
|
518
525
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
526
|
+
await getPanelData();
|
|
527
|
+
|
|
528
|
+
htmls(
|
|
529
|
+
containerSelector,
|
|
530
|
+
html`
|
|
531
|
+
<div class="in">${await panelRender({ data: this.Data[idPanel].data })}</div>
|
|
532
|
+
<div class="in panel-placeholder-bottom panel-placeholder-bottom-${idPanel}"></div>
|
|
533
|
+
`,
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
if (
|
|
537
|
+
!this.Data[idPanel].lasIdAvailable ||
|
|
538
|
+
this.Data[idPanel].lasIdAvailable !==
|
|
539
|
+
this.Data[idPanel].originData[this.Data[idPanel].originData.length - 1]._id
|
|
540
|
+
)
|
|
541
|
+
LoadingAnimation.spinner.play(`.panel-placeholder-bottom-${idPanel}`, 'dual-ring-mini');
|
|
542
|
+
|
|
543
|
+
const scrollContainerSelector = `.modal-${options.route}`;
|
|
544
|
+
|
|
545
|
+
if (cid) {
|
|
546
|
+
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (this.Data[idPanel].removeScrollEvent) {
|
|
550
|
+
this.Data[idPanel].removeScrollEvent();
|
|
537
551
|
}
|
|
552
|
+
const { removeEvent } = Scroll.setEvent(scrollContainerSelector, async (payload) => {
|
|
553
|
+
const panelData = PanelForm.Data[idPanel];
|
|
554
|
+
if (!panelData) return;
|
|
555
|
+
|
|
556
|
+
// Infinite scroll: load more items at bottom
|
|
557
|
+
if (payload.atBottom && panelData.hasMore && !panelData.loading) {
|
|
558
|
+
const oldDataCount = panelData.data.length;
|
|
559
|
+
await getPanelData(true); // isLoadMore = true
|
|
560
|
+
const newItems = panelData.data.slice(oldDataCount);
|
|
561
|
+
if (newItems.length > 0) {
|
|
562
|
+
for (const item of newItems)
|
|
563
|
+
append(`.${idPanel}-render`, await Panel.Tokens[idPanel].renderPanel(item));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
this.Data[idPanel].removeScrollEvent = removeEvent;
|
|
568
|
+
|
|
569
|
+
if (!firsUpdateEvent && options.firsUpdateEvent) {
|
|
570
|
+
firsUpdateEvent = true;
|
|
571
|
+
await options.firsUpdateEvent();
|
|
572
|
+
}
|
|
573
|
+
} catch (error) {
|
|
574
|
+
logger.error(error);
|
|
538
575
|
}
|
|
539
|
-
}
|
|
540
|
-
this.Data[idPanel].removeScrollEvent = removeEvent;
|
|
576
|
+
};
|
|
541
577
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
await options.firsUpdateEvent();
|
|
545
|
-
}
|
|
578
|
+
await _updatePanel(...args);
|
|
579
|
+
loadingGetData = false;
|
|
546
580
|
};
|
|
547
581
|
if (options.route) {
|
|
548
582
|
listenQueryPathInstance({
|
|
@@ -59,7 +59,7 @@ const getProxyPath = () => {
|
|
|
59
59
|
* @returns {void | undefined} Returns `undefined` if the new path is the same as the current path, otherwise `void` (result of `history.pushState`).
|
|
60
60
|
*/
|
|
61
61
|
const setPath = (path = '/', options = { removeSearch: false, removeHash: false }, stateStorage = {}, title = '') => {
|
|
62
|
-
logger.warn(`Set path input`, `${path}`);
|
|
62
|
+
// logger.warn(`Set path input`, `${path}`);
|
|
63
63
|
if (!path) path = '/';
|
|
64
64
|
|
|
65
65
|
let [inputPath, inputSearchHash] = `${path}`.split('?');
|
|
@@ -77,18 +77,18 @@ const setPath = (path = '/', options = { removeSearch: false, removeHash: false
|
|
|
77
77
|
inputHash && !options.removeHash ? `#${inputHash}` : ''
|
|
78
78
|
}`;
|
|
79
79
|
const currentFullPath = `${window.location.pathname}${location.search}${location.hash}`;
|
|
80
|
-
logger.warn(`Set path output`, {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
});
|
|
80
|
+
// logger.warn(`Set path output`, {
|
|
81
|
+
// inputPath: inputPath,
|
|
82
|
+
// inputSearch: inputSearch,
|
|
83
|
+
// inputHash: inputHash,
|
|
84
|
+
// sanitizedPath: sanitizedPath,
|
|
85
|
+
// currentLocationSearch: location.search,
|
|
86
|
+
// currentLocationHash: location.hash,
|
|
87
|
+
// currentFullPath,
|
|
88
|
+
// newFullPath,
|
|
89
|
+
// });
|
|
90
90
|
if (currentFullPath === newFullPath) {
|
|
91
|
-
logger.warn('Prevent overwriting same path', { currentFullPath, newFullPath });
|
|
91
|
+
// logger.warn('Prevent overwriting same path', { currentFullPath, newFullPath });
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
return history.pushState.call(history, stateStorage, title, newFullPath);
|
|
@@ -149,7 +149,7 @@ const Router = function (options = { Routes: () => {}, e: new PopStateEvent() })
|
|
|
149
149
|
const { e, Routes } = options;
|
|
150
150
|
const proxyPath = getProxyPath();
|
|
151
151
|
let path = window.location.pathname;
|
|
152
|
-
logger.info(options);
|
|
152
|
+
// logger.info(options);
|
|
153
153
|
|
|
154
154
|
for (let route of Object.keys(Routes())) {
|
|
155
155
|
route = route.slice(1);
|
|
@@ -229,11 +229,11 @@ const listenQueryPathInstance = ({ id, routeId, event }, queryKey = 'cid') => {
|
|
|
229
229
|
* @memberof PwaRouter
|
|
230
230
|
*/
|
|
231
231
|
const closeModalRouteChangeEvent = (options = {}) => {
|
|
232
|
-
logger.warn('closeModalRouteChangeEvent', options);
|
|
232
|
+
// logger.warn('closeModalRouteChangeEvent', options);
|
|
233
233
|
const { closedId } = options;
|
|
234
234
|
if (!closedId) return;
|
|
235
235
|
if (coreUI.find((id) => closedId.startsWith(id))) {
|
|
236
|
-
logger.warn('prevent core ui component close');
|
|
236
|
+
// logger.warn('prevent core ui component close');
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
|