underpost 2.8.84 → 2.8.85
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/.env.development +1 -0
- package/.env.production +1 -0
- package/.env.test +1 -0
- package/.github/workflows/{ghpkg.yml → ghpkg.ci.yml} +1 -1
- package/.github/workflows/{npmpkg.yml → npmpkg.ci.yml} +1 -1
- package/.github/workflows/{publish.yml → publish.ci.yml} +1 -1
- package/.github/workflows/{pwa-microservices-template.page.yml → pwa-microservices-template-page.cd.yml} +1 -1
- package/.github/workflows/{pwa-microservices-template.test.yml → pwa-microservices-template-test.ci.yml} +1 -1
- package/.vscode/settings.json +0 -1
- package/README.md +45 -2
- package/bin/build.js +15 -5
- package/bin/deploy.js +17 -82
- package/bin/file.js +15 -8
- package/cli.md +65 -44
- package/conf.js +1 -1
- package/docker-compose.yml +1 -1
- package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
- package/manifests/maas/gpu-diag.sh +1 -1
- package/package.json +4 -6
- package/src/api/user/user.router.js +24 -1
- package/src/api/user/user.service.js +1 -4
- package/src/cli/cluster.js +42 -27
- package/src/cli/deploy.js +20 -0
- package/src/cli/index.js +9 -0
- package/src/cli/monitor.js +8 -12
- package/src/cli/run.js +111 -6
- package/src/cli/ssh.js +32 -0
- package/src/client/Default.index.js +7 -3
- package/src/client/components/core/Account.js +1 -1
- package/src/client/components/core/Chat.js +1 -1
- package/src/client/components/core/CommonJs.js +24 -22
- package/src/client/components/core/Content.js +1 -5
- package/src/client/components/core/Css.js +258 -18
- package/src/client/components/core/CssCore.js +8 -8
- package/src/client/components/core/Docs.js +14 -61
- package/src/client/components/core/DropDown.js +137 -82
- package/src/client/components/core/EventsUI.js +92 -5
- package/src/client/components/core/LoadingAnimation.js +8 -15
- package/src/client/components/core/Modal.js +597 -136
- package/src/client/components/core/NotificationManager.js +2 -2
- package/src/client/components/core/ObjectLayerEngine.js +638 -0
- package/src/client/components/core/Panel.js +158 -34
- package/src/client/components/core/PanelForm.js +12 -3
- package/src/client/components/core/Recover.js +1 -1
- package/src/client/components/core/Router.js +77 -17
- package/src/client/components/core/SocketIo.js +3 -3
- package/src/client/components/core/Translate.js +6 -2
- package/src/client/components/core/VanillaJs.js +0 -3
- package/src/client/components/core/Worker.js +3 -1
- package/src/client/components/default/CssDefault.js +17 -3
- package/src/client/components/default/MenuDefault.js +264 -45
- package/src/client/components/default/RoutesDefault.js +6 -12
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/dark.svg +557 -0
- package/src/client/public/default/assets/logo/base-icon.png +0 -0
- package/src/client/public/default/assets/logo/underpost.gif +0 -0
- package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
- package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
- package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/safari-pinned-tab.svg +24 -0
- package/src/client/ssr/body/DefaultSplashScreen.js +2 -2
- package/src/index.js +9 -1
- package/src/monitor.js +24 -0
- package/src/runtime/lampp/Dockerfile +30 -39
- package/src/runtime/lampp/Lampp.js +11 -2
- package/src/server/client-build-docs.js +205 -0
- package/src/server/client-build.js +16 -166
- package/src/server/conf.js +12 -5
- package/src/server/valkey.js +102 -41
|
@@ -8,7 +8,12 @@ const DropDown = {
|
|
|
8
8
|
Tokens: {},
|
|
9
9
|
Render: async function (options) {
|
|
10
10
|
const id = options.id ? options.id : getId(this.Tokens, 'dropdown-');
|
|
11
|
-
this.Tokens[id] = {
|
|
11
|
+
this.Tokens[id] = {
|
|
12
|
+
onClickEvents: {},
|
|
13
|
+
lastSelectValue: undefined,
|
|
14
|
+
oncheckvalues: {},
|
|
15
|
+
originData: options.data ? newInstance(options.data) : [],
|
|
16
|
+
};
|
|
12
17
|
|
|
13
18
|
options.data.push({
|
|
14
19
|
value: 'reset',
|
|
@@ -39,6 +44,100 @@ const DropDown = {
|
|
|
39
44
|
else s(`.dropdown-option-${id}`).classList.add('hide');
|
|
40
45
|
};
|
|
41
46
|
|
|
47
|
+
const _render = async (data) => {
|
|
48
|
+
let render = '';
|
|
49
|
+
let index = -1;
|
|
50
|
+
for (const optionData of data) {
|
|
51
|
+
index++;
|
|
52
|
+
const i = index;
|
|
53
|
+
const valueDisplay = optionData.value.trim().replaceAll(' ', '-');
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
const onclick = (e) => {
|
|
56
|
+
if (options && options.lastSelectClass && s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`)) {
|
|
57
|
+
s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`).classList.remove(options.lastSelectClass);
|
|
58
|
+
}
|
|
59
|
+
this.Tokens[id].lastSelectValue = valueDisplay;
|
|
60
|
+
if (options && options.lastSelectClass && s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`)) {
|
|
61
|
+
s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`).classList.add(options.lastSelectClass);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
!(options && options.disableClose) &&
|
|
66
|
+
(options.type !== 'checkbox' || optionData.value === 'close' || optionData.value === 'reset')
|
|
67
|
+
)
|
|
68
|
+
s(`.dropdown-option-${id}`).classList.add('hide');
|
|
69
|
+
|
|
70
|
+
if (options.type === 'checkbox' && ToggleSwitch.Tokens[`checkbox-role-${valueDisplay}`])
|
|
71
|
+
ToggleSwitch.Tokens[`checkbox-role-${valueDisplay}`].click();
|
|
72
|
+
if (optionData.value !== 'close') {
|
|
73
|
+
if (optionData.value !== 'reset') {
|
|
74
|
+
if (options.type === 'checkbox') {
|
|
75
|
+
// const _instanValue = data
|
|
76
|
+
// .filter((d) => d.checked)
|
|
77
|
+
// .map((v, i, a) => `${v.display}${i < a.length - 1 ? ',' : ''}`)
|
|
78
|
+
// .join('');
|
|
79
|
+
const value = Object.keys(DropDown.Tokens[id].oncheckvalues);
|
|
80
|
+
htmls(
|
|
81
|
+
`.dropdown-current-${id}`,
|
|
82
|
+
value.map((v) => DropDown.Tokens[id].originData.find((_v) => _v.value === v).display),
|
|
83
|
+
);
|
|
84
|
+
} else {
|
|
85
|
+
htmls(`.dropdown-current-${id}`, optionData.display);
|
|
86
|
+
}
|
|
87
|
+
} else htmls(`.dropdown-current-${id}`, '');
|
|
88
|
+
|
|
89
|
+
this.Tokens[id].value =
|
|
90
|
+
options.type === 'checkbox' ? data.filter((d) => d.checked).map((d) => d.data) : optionData.data;
|
|
91
|
+
|
|
92
|
+
console.warn('current value dropdown id:' + id, this.Tokens[id].value);
|
|
93
|
+
|
|
94
|
+
s(`.${id}`).value = this.Tokens[id].value;
|
|
95
|
+
|
|
96
|
+
optionData.onClick(e);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
this.Tokens[id].onClickEvents[`dropdown-option-${id}-${i}`] = onclick;
|
|
101
|
+
this.Tokens[id].onClickEvents[`dropdown-option-${id}-${valueDisplay}`] = onclick;
|
|
102
|
+
this.Tokens[id].onClickEvents[`dropdown-option-${valueDisplay}`] = onclick;
|
|
103
|
+
|
|
104
|
+
s(`.dropdown-option-${id}-${i}`).onclick = onclick;
|
|
105
|
+
});
|
|
106
|
+
render += html`
|
|
107
|
+
<div
|
|
108
|
+
class="in dropdown-option dropdown-option-${id}-${i} dropdown-option-${id}-${valueDisplay} dropdown-option-${valueDisplay} ${valueDisplay ===
|
|
109
|
+
'reset' &&
|
|
110
|
+
options &&
|
|
111
|
+
!(options.resetOption === true)
|
|
112
|
+
? 'hide'
|
|
113
|
+
: ''}"
|
|
114
|
+
>
|
|
115
|
+
${options.type === 'checkbox' && optionData.value !== 'close' && optionData.value !== 'reset'
|
|
116
|
+
? html`
|
|
117
|
+
${await ToggleSwitch.Render({
|
|
118
|
+
id: `checkbox-role-${valueDisplay}`,
|
|
119
|
+
type: 'checkbox',
|
|
120
|
+
disabledOnClick: true,
|
|
121
|
+
checked: optionData.checked,
|
|
122
|
+
on: {
|
|
123
|
+
unchecked: () => {
|
|
124
|
+
optionData.checked = false;
|
|
125
|
+
delete DropDown.Tokens[id].oncheckvalues[valueDisplay];
|
|
126
|
+
},
|
|
127
|
+
checked: () => {
|
|
128
|
+
optionData.checked = true;
|
|
129
|
+
DropDown.Tokens[id].oncheckvalues[valueDisplay] = {};
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
})}
|
|
133
|
+
`
|
|
134
|
+
: ''}${optionData.display}
|
|
135
|
+
</div>
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
return { render, index };
|
|
139
|
+
};
|
|
140
|
+
|
|
42
141
|
setTimeout(() => {
|
|
43
142
|
if (options.type === 'checkbox')
|
|
44
143
|
options.data.map((optionData) => {
|
|
@@ -53,92 +152,48 @@ const DropDown = {
|
|
|
53
152
|
s(`.dropdown-label-${id}`).onclick = switchOptionsPanel;
|
|
54
153
|
s(`.dropdown-current-${id}`).onclick = switchOptionsPanel;
|
|
55
154
|
if (options && options.open) switchOptionsPanel();
|
|
56
|
-
});
|
|
57
155
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
index++;
|
|
62
|
-
const i = index;
|
|
63
|
-
const valueDisplay = optionData.value.trim().replaceAll(' ', '-');
|
|
64
|
-
setTimeout(() => {
|
|
65
|
-
const onclick = (e) => {
|
|
66
|
-
if (options && options.lastSelectClass && s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`)) {
|
|
67
|
-
s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`).classList.remove(options.lastSelectClass);
|
|
68
|
-
}
|
|
69
|
-
this.Tokens[id].lastSelectValue = valueDisplay;
|
|
70
|
-
if (options && options.lastSelectClass && s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`)) {
|
|
71
|
-
s(`.dropdown-option-${this.Tokens[id].lastSelectValue}`).classList.add(options.lastSelectClass);
|
|
72
|
-
}
|
|
156
|
+
const dropDownSearchHandle = async () => {
|
|
157
|
+
const _data = [];
|
|
158
|
+
if (!s(`.search-box-${id}`)) return;
|
|
73
159
|
|
|
160
|
+
let _value = s(`.search-box-${id}`).value.toLowerCase();
|
|
161
|
+
|
|
162
|
+
for (const objData of options.data) {
|
|
163
|
+
const objValue = objData.value.toLowerCase();
|
|
74
164
|
if (
|
|
75
|
-
|
|
76
|
-
(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (optionData.value !== 'close') {
|
|
83
|
-
if (optionData.value !== 'reset')
|
|
84
|
-
htmls(
|
|
85
|
-
`.dropdown-current-${id}`,
|
|
86
|
-
options.type === 'checkbox'
|
|
87
|
-
? options.data
|
|
88
|
-
.filter((d) => d.checked)
|
|
89
|
-
.map((v, i, a) => `${v.display}${i < a.length - 1 ? ',' : ''}`)
|
|
90
|
-
.join('')
|
|
91
|
-
: optionData.display,
|
|
92
|
-
);
|
|
93
|
-
else htmls(`.dropdown-current-${id}`, '');
|
|
94
|
-
|
|
95
|
-
this.Tokens[id].value =
|
|
96
|
-
options.type === 'checkbox' ? options.data.filter((d) => d.checked).map((d) => d.data) : optionData.data;
|
|
97
|
-
|
|
98
|
-
console.warn('current value dropdown id:' + id, this.Tokens[id].value);
|
|
99
|
-
|
|
100
|
-
s(`.${id}`).value = this.Tokens[id].value;
|
|
101
|
-
|
|
102
|
-
optionData.onClick(e);
|
|
165
|
+
objValue.match(_value) ||
|
|
166
|
+
(Translate.Data[objData.value] &&
|
|
167
|
+
Object.keys(Translate.Data[objData.value]).find((t) =>
|
|
168
|
+
Translate.Data[objData.value][t].toLowerCase().match(_value),
|
|
169
|
+
))
|
|
170
|
+
) {
|
|
171
|
+
_data.push(objData);
|
|
103
172
|
}
|
|
104
|
-
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (_data.length > 0) {
|
|
176
|
+
const { render, index } = await _render(_data);
|
|
177
|
+
htmls(`.${id}-render-container`, render);
|
|
178
|
+
} else {
|
|
179
|
+
// const { render, index } = await _render(options.data);
|
|
180
|
+
htmls(
|
|
181
|
+
`.${id}-render-container`,
|
|
182
|
+
html` <div class="inl" style="padding: 10px; color: red">
|
|
183
|
+
<i class="fas fa-exclamation-circle"></i> ${Translate.Render('no-result-found')}
|
|
184
|
+
</div>`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
s(`.search-box-${id}`).oninput = dropDownSearchHandle;
|
|
190
|
+
|
|
191
|
+
// Not use onblur generate bug on input toggle
|
|
192
|
+
// s(`.search-box-${id}`).onblur = dropDownSearchHandle;
|
|
193
|
+
});
|
|
105
194
|
|
|
106
|
-
|
|
107
|
-
this.Tokens[id].onClickEvents[`dropdown-option-${id}-${valueDisplay}`] = onclick;
|
|
108
|
-
this.Tokens[id].onClickEvents[`dropdown-option-${valueDisplay}`] = onclick;
|
|
195
|
+
const { render, index } = await _render(options.data);
|
|
109
196
|
|
|
110
|
-
s(`.dropdown-option-${id}-${i}`).onclick = onclick;
|
|
111
|
-
});
|
|
112
|
-
render += html`
|
|
113
|
-
<div
|
|
114
|
-
class="in dropdown-option dropdown-option-${id}-${i} dropdown-option-${id}-${valueDisplay} dropdown-option-${valueDisplay} ${valueDisplay ===
|
|
115
|
-
'reset' &&
|
|
116
|
-
options &&
|
|
117
|
-
!(options.resetOption === true)
|
|
118
|
-
? 'hide'
|
|
119
|
-
: ''}"
|
|
120
|
-
>
|
|
121
|
-
${options.type === 'checkbox' && optionData.value !== 'close' && optionData.value !== 'reset'
|
|
122
|
-
? html`
|
|
123
|
-
${await ToggleSwitch.Render({
|
|
124
|
-
id: `checkbox-role-${valueDisplay}`,
|
|
125
|
-
type: 'checkbox',
|
|
126
|
-
disabledOnClick: true,
|
|
127
|
-
checked: optionData.checked,
|
|
128
|
-
on: {
|
|
129
|
-
unchecked: () => {
|
|
130
|
-
optionData.checked = false;
|
|
131
|
-
},
|
|
132
|
-
checked: () => {
|
|
133
|
-
optionData.checked = true;
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
})}
|
|
137
|
-
`
|
|
138
|
-
: ''}${optionData.display}
|
|
139
|
-
</div>
|
|
140
|
-
`;
|
|
141
|
-
}
|
|
142
197
|
return html`
|
|
143
198
|
<div class="inl dropdown-container ${id} ${options?.containerClass ? options.containerClass : ''}">
|
|
144
199
|
<div class="in dropdown-option dropdown-label-${id} ${options && options.disableSelectLabel ? 'hide' : ''}">
|
|
@@ -158,7 +213,7 @@ const DropDown = {
|
|
|
158
213
|
placeholder: true,
|
|
159
214
|
})}
|
|
160
215
|
</div>
|
|
161
|
-
${render}
|
|
216
|
+
<div class="${id}-render-container">${render}</div>
|
|
162
217
|
</div>
|
|
163
218
|
</div>
|
|
164
219
|
`;
|
|
@@ -2,7 +2,7 @@ import { LoadingAnimation } from '../core/LoadingAnimation.js';
|
|
|
2
2
|
import { loggerFactory } from '../core/Logger.js';
|
|
3
3
|
import { cssEffect } from './Css.js';
|
|
4
4
|
import { NotificationManager } from './NotificationManager.js';
|
|
5
|
-
import { s } from './VanillaJs.js';
|
|
5
|
+
import { s, isActiveElement } from './VanillaJs.js';
|
|
6
6
|
|
|
7
7
|
const logger = loggerFactory(import.meta);
|
|
8
8
|
|
|
@@ -13,10 +13,37 @@ const EventsUI = {
|
|
|
13
13
|
let complete = true;
|
|
14
14
|
s(id)[type] = async function (e) {
|
|
15
15
|
if (options.clickEffect) cssEffect(id, e);
|
|
16
|
+
const noGate = !!options.noGate;
|
|
17
|
+
const noLoading = !!options.noLoading;
|
|
18
|
+
const playLoading = async () => {
|
|
19
|
+
if (!noLoading) {
|
|
20
|
+
await LoadingAnimation.spinner.play(loadingContainer ? loadingContainer : id);
|
|
21
|
+
if (options.context !== 'modal') await LoadingAnimation.bar.play(id);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const stopLoading = async () => {
|
|
25
|
+
if (!noLoading) {
|
|
26
|
+
if (options.context !== 'modal') LoadingAnimation.bar.stop(id);
|
|
27
|
+
await LoadingAnimation.spinner.stop(loadingContainer ? loadingContainer : id);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
if (noGate) {
|
|
31
|
+
try {
|
|
32
|
+
await playLoading();
|
|
33
|
+
await logic(e);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logger.error(error);
|
|
36
|
+
NotificationManager.Push({
|
|
37
|
+
status: 'error',
|
|
38
|
+
html: error?.message ? error.message : error ? error : 'Event error',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
await stopLoading();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
16
44
|
if (complete) {
|
|
17
45
|
complete = false;
|
|
18
|
-
await
|
|
19
|
-
if (options.context !== 'modal') await LoadingAnimation.bar.play(id);
|
|
46
|
+
await playLoading();
|
|
20
47
|
try {
|
|
21
48
|
await logic(e);
|
|
22
49
|
} catch (error) {
|
|
@@ -26,8 +53,7 @@ const EventsUI = {
|
|
|
26
53
|
html: error?.message ? error.message : error ? error : 'Event error',
|
|
27
54
|
});
|
|
28
55
|
}
|
|
29
|
-
|
|
30
|
-
await LoadingAnimation.spinner.stop(loadingContainer ? loadingContainer : id);
|
|
56
|
+
await stopLoading();
|
|
31
57
|
complete = true;
|
|
32
58
|
return;
|
|
33
59
|
}
|
|
@@ -41,6 +67,67 @@ const EventsUI = {
|
|
|
41
67
|
onChange: async function (id = '', logic = async function (e) {}, options = { loadingContainer: '' }) {
|
|
42
68
|
return await this.on(id, logic, 'onchange', options);
|
|
43
69
|
},
|
|
70
|
+
// Shared hover/focus controller extracted from Modal
|
|
71
|
+
HoverFocusController: function ({ inputSelector, panelSelector, activeElementId, onDismiss } = {}) {
|
|
72
|
+
let hoverPanel = false;
|
|
73
|
+
let hoverInput = false;
|
|
74
|
+
const isActive = () => (activeElementId ? isActiveElement(activeElementId) : false);
|
|
75
|
+
const shouldStay = () => isActive() || hoverPanel || hoverInput;
|
|
76
|
+
const bind = () => {
|
|
77
|
+
if (inputSelector && s(inputSelector)) {
|
|
78
|
+
s(inputSelector).onmouseover = () => {
|
|
79
|
+
hoverInput = true;
|
|
80
|
+
};
|
|
81
|
+
s(inputSelector).onmouseout = () => {
|
|
82
|
+
hoverInput = false;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (panelSelector && s(panelSelector)) {
|
|
86
|
+
s(panelSelector).onmouseover = () => {
|
|
87
|
+
hoverPanel = true;
|
|
88
|
+
};
|
|
89
|
+
s(panelSelector).onmouseout = () => {
|
|
90
|
+
hoverPanel = false;
|
|
91
|
+
if (activeElementId && s(`.${activeElementId}`) && s(`.${activeElementId}`).focus)
|
|
92
|
+
s(`.${activeElementId}`).focus();
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const checkDismiss = () => {
|
|
97
|
+
if (!shouldStay()) onDismiss && onDismiss();
|
|
98
|
+
};
|
|
99
|
+
return { bind, shouldStay, checkDismiss };
|
|
100
|
+
},
|
|
101
|
+
// Generic click-outside binding to dismiss a panel/modal
|
|
102
|
+
// Options:
|
|
103
|
+
// - shouldStay: function -> boolean
|
|
104
|
+
// - onDismiss: function
|
|
105
|
+
// - anchors: array of selectors to treat as inside clicks (e.g., input button, panel container)
|
|
106
|
+
// - graceMs: number of ms after binding to ignore clicks (avoid closing on the same click that opened)
|
|
107
|
+
bindDismissOnDocumentClick: function ({ shouldStay, onDismiss, anchors = [], graceMs = 200 } = {}) {
|
|
108
|
+
if (typeof document === 'undefined') return () => {};
|
|
109
|
+
const bindAt = Date.now();
|
|
110
|
+
const isInsideAnchors = (target) => {
|
|
111
|
+
if (!target) return false;
|
|
112
|
+
for (const sel of anchors) {
|
|
113
|
+
const el = sel && typeof sel === 'string' ? s(sel) : null;
|
|
114
|
+
if (el && (el === target || el.contains(target))) return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
118
|
+
const handler = (e) => {
|
|
119
|
+
// Ignore very quick clicks right after binding
|
|
120
|
+
if (Date.now() - bindAt < graceMs) return;
|
|
121
|
+
// If click is within anchors, ignore
|
|
122
|
+
if (isInsideAnchors(e?.target)) return;
|
|
123
|
+
// Defer to allow hover flags to update first
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
if (!shouldStay || !shouldStay()) onDismiss && onDismiss();
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
document.addEventListener('click', handler, true);
|
|
129
|
+
return () => document.removeEventListener('click', handler, true);
|
|
130
|
+
},
|
|
44
131
|
};
|
|
45
132
|
|
|
46
133
|
export { EventsUI };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CoreService } from '../../services/core/core.service.js';
|
|
2
2
|
import { BtnIcon } from './BtnIcon.js';
|
|
3
3
|
import { s4 } from './CommonJs.js';
|
|
4
|
-
import { darkTheme, renderCssAttr } from './Css.js';
|
|
4
|
+
import { darkTheme, renderCssAttr, subThemeManager } from './Css.js';
|
|
5
5
|
import { loggerFactory } from './Logger.js';
|
|
6
6
|
import { append, getAllChildNodes, getProxyPath, htmls, s, sa } from './VanillaJs.js';
|
|
7
7
|
|
|
@@ -23,12 +23,12 @@ const LoadingAnimation = {
|
|
|
23
23
|
<div
|
|
24
24
|
class="fix progress-bar box-shadow ${id}"
|
|
25
25
|
style="left: -100%; background: ${darkTheme
|
|
26
|
-
?
|
|
27
|
-
?
|
|
28
|
-
: `#
|
|
29
|
-
:
|
|
30
|
-
?
|
|
31
|
-
: `#
|
|
26
|
+
? subThemeManager.darkColor
|
|
27
|
+
? subThemeManager.darkColor
|
|
28
|
+
: `#66e400`
|
|
29
|
+
: subThemeManager.lightColor
|
|
30
|
+
? subThemeManager.lightColor
|
|
31
|
+
: `#157e00`};"
|
|
32
32
|
></div>
|
|
33
33
|
`,
|
|
34
34
|
);
|
|
@@ -140,14 +140,7 @@ const LoadingAnimation = {
|
|
|
140
140
|
}, 300);
|
|
141
141
|
});
|
|
142
142
|
},
|
|
143
|
-
|
|
144
|
-
setLightColor: function (color) {
|
|
145
|
-
this.lightColor = color;
|
|
146
|
-
},
|
|
147
|
-
darkColor: null,
|
|
148
|
-
setDarkColor: function (color) {
|
|
149
|
-
this.darkColor = color;
|
|
150
|
-
},
|
|
143
|
+
|
|
151
144
|
RenderCurrentSrcLoad: function (event) {
|
|
152
145
|
if (s(`.ssr-loading-info`)) {
|
|
153
146
|
let nameSrcLoad = event.data.path;
|