underpost 3.2.5 → 3.2.8
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/CHANGELOG.md +251 -1
- package/CLI-HELP.md +26 -13
- package/Dockerfile +0 -4
- package/README.md +3 -3
- package/bin/build.js +13 -3
- package/bin/deploy.js +570 -1
- package/bin/file.js +5 -0
- package/conf.js +11 -2
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +20 -11
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.service.js +36 -36
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +3 -20
- package/src/cli/deploy.js +33 -30
- package/src/cli/fs.js +62 -5
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +5 -1
- package/src/cli/release.js +57 -1
- package/src/cli/repository.js +35 -3
- package/src/cli/run.js +300 -35
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Default.index.js +21 -33
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +1 -1
- package/src/client/components/core/Auth.js +20 -32
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +42 -63
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +60 -59
- package/src/client/components/core/DropDown.js +69 -91
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +102 -234
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +25 -18
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +397 -176
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +52 -48
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Worker.js +140 -25
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/services/core/core.service.js +17 -49
- package/src/client/services/default/default.management.js +139 -242
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +79 -0
- package/src/client/services/user/user.management.js +5 -5
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/index.js +1 -1
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +5 -4
- package/src/server/ipfs-client.js +232 -91
- package/src/server/process.js +13 -27
- package/src/server/start.js +6 -3
- package/src/server/valkey.js +134 -235
- package/tsconfig.docs.json +15 -0
- package/typedoc.json +20 -0
- package/jsdoc.json +0 -52
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
|
@@ -12,6 +12,25 @@ import { Worker } from './Worker.js';
|
|
|
12
12
|
|
|
13
13
|
const logger = loggerFactory(import.meta, { trace: true });
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @type {function | null}
|
|
17
|
+
* @description The active routes function registered by the current app router.
|
|
18
|
+
* Replaces the former `window.Routes` global so `getProxyPath` can resolve
|
|
19
|
+
* sub-directory proxy paths without polluting the global scope.
|
|
20
|
+
* @memberof PwaRouter
|
|
21
|
+
*/
|
|
22
|
+
let _activeRoutes = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Registers the active routes function for the current app.
|
|
26
|
+
* Called automatically by `LoadRouter`; should not be called manually.
|
|
27
|
+
* @param {function} routesFn - A function returning the routes object.
|
|
28
|
+
* @memberof PwaRouter
|
|
29
|
+
*/
|
|
30
|
+
const registerRoutes = (routesFn) => {
|
|
31
|
+
_activeRoutes = routesFn;
|
|
32
|
+
};
|
|
33
|
+
|
|
15
34
|
/**
|
|
16
35
|
* @type {Object.<string, function>}
|
|
17
36
|
* @description Holds event listeners for router changes.
|
|
@@ -71,15 +90,15 @@ const setRouterReady = () => {
|
|
|
71
90
|
|
|
72
91
|
/**
|
|
73
92
|
* Determines the base path for the application, often used for routing within a sub-directory.
|
|
74
|
-
* It checks the current URL's pathname and
|
|
93
|
+
* It checks the current URL's pathname and the active registered routes to return the appropriate proxy path.
|
|
75
94
|
*
|
|
76
95
|
* @returns {string} The calculated proxy path. Returns `/<first-segment>/` if a segment exists,
|
|
77
|
-
* otherwise `/`. If
|
|
96
|
+
* otherwise `/`. If the registered routes indicate the path is a root route, it returns `/`.
|
|
78
97
|
* @memberof PwaRouter
|
|
79
98
|
*/
|
|
80
99
|
const getProxyPath = () => {
|
|
81
100
|
let path = location.pathname.split('/')[1] ? `/${location.pathname.split('/')[1]}/` : '/';
|
|
82
|
-
if (
|
|
101
|
+
if (_activeRoutes && path !== '/' && path.slice(0, -1) in _activeRoutes()) path = '/';
|
|
83
102
|
return path;
|
|
84
103
|
};
|
|
85
104
|
|
|
@@ -241,6 +260,7 @@ const Router = function (options = { Routes: () => {}, e: new PopStateEvent() })
|
|
|
241
260
|
*/
|
|
242
261
|
const LoadRouter = async function (RouterInstance) {
|
|
243
262
|
await RouterReady;
|
|
263
|
+
if (RouterInstance.Routes) registerRoutes(RouterInstance.Routes);
|
|
244
264
|
Router(RouterInstance);
|
|
245
265
|
window.onpopstate = (e) => {
|
|
246
266
|
Router({ ...RouterInstance, e });
|
|
@@ -478,6 +498,7 @@ const setQueryParams = (newParams, options = { replace: true }) => {
|
|
|
478
498
|
|
|
479
499
|
export {
|
|
480
500
|
RouterEvents,
|
|
501
|
+
registerRoutes,
|
|
481
502
|
navigateToProfile,
|
|
482
503
|
closeModalRouteChangeEvents,
|
|
483
504
|
coreUI,
|
|
@@ -14,18 +14,18 @@ import { darkTheme, ThemeEvents, subThemeManager, lightenHex, darkenHex } from '
|
|
|
14
14
|
const logger = loggerFactory(import.meta);
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* SearchBox
|
|
17
|
+
* SearchBox class providing extensible search functionality.
|
|
18
18
|
* Supports default menu/route search and pluggable search providers with
|
|
19
19
|
* custom rendering, click handlers, and result merging.
|
|
20
20
|
* @memberof SearchBoxClient
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
class SearchBox {
|
|
23
23
|
/**
|
|
24
24
|
* Internal data storage for search state and handlers.
|
|
25
25
|
* @type {object}
|
|
26
26
|
* @memberof SearchBoxClient.SearchBox
|
|
27
27
|
*/
|
|
28
|
-
Data
|
|
28
|
+
static Data = {};
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Registry of registered search provider plugins.
|
|
@@ -38,7 +38,7 @@ const SearchBox = {
|
|
|
38
38
|
* @type {Array<object>}
|
|
39
39
|
* @memberof SearchBoxClient.SearchBox
|
|
40
40
|
*/
|
|
41
|
-
providers
|
|
41
|
+
static providers = [];
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Recent search results manager with localStorage persistence.
|
|
@@ -47,7 +47,7 @@ const SearchBox = {
|
|
|
47
47
|
* @type {object}
|
|
48
48
|
* @memberof SearchBoxClient.SearchBox
|
|
49
49
|
*/
|
|
50
|
-
RecentResults
|
|
50
|
+
static RecentResults = {
|
|
51
51
|
/**
|
|
52
52
|
* Storage key for localStorage persistence
|
|
53
53
|
* @type {string}
|
|
@@ -159,7 +159,7 @@ const SearchBox = {
|
|
|
159
159
|
});
|
|
160
160
|
this.saveAll(filtered);
|
|
161
161
|
},
|
|
162
|
-
}
|
|
162
|
+
};
|
|
163
163
|
|
|
164
164
|
/**
|
|
165
165
|
* Registers a search provider plugin for extensible search functionality.
|
|
@@ -173,7 +173,7 @@ const SearchBox = {
|
|
|
173
173
|
* @param {number} [provider.priority=50] - Priority for result ordering (lower = higher priority).
|
|
174
174
|
* @returns {void}
|
|
175
175
|
*/
|
|
176
|
-
registerProvider
|
|
176
|
+
static registerProvider(provider) {
|
|
177
177
|
if (!provider.id || !provider.search) {
|
|
178
178
|
logger.error('Invalid provider. Must have id and search function');
|
|
179
179
|
return;
|
|
@@ -192,7 +192,7 @@ const SearchBox = {
|
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
logger.info(`Registered search provider: ${provider.id}`);
|
|
195
|
-
}
|
|
195
|
+
}
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
198
|
* Unregisters a search provider by its ID.
|
|
@@ -200,10 +200,10 @@ const SearchBox = {
|
|
|
200
200
|
* @param {string} providerId - The ID of the provider to unregister.
|
|
201
201
|
* @returns {void}
|
|
202
202
|
*/
|
|
203
|
-
unregisterProvider
|
|
203
|
+
static unregisterProvider(providerId) {
|
|
204
204
|
this.providers = this.providers.filter((p) => p.id !== providerId);
|
|
205
205
|
logger.info(`Unregistered search provider: ${providerId}`);
|
|
206
|
-
}
|
|
206
|
+
}
|
|
207
207
|
|
|
208
208
|
/**
|
|
209
209
|
* Default result renderer with support for tags and badges.
|
|
@@ -219,13 +219,13 @@ const SearchBox = {
|
|
|
219
219
|
* @param {string} result.providerId - Provider ID that generated this result.
|
|
220
220
|
* @returns {string} HTML string for the search result.
|
|
221
221
|
*/
|
|
222
|
-
defaultRenderResult
|
|
222
|
+
static defaultRenderResult(result) {
|
|
223
223
|
const icon = result.icon || '<i class="fas fa-file"></i>';
|
|
224
224
|
const title = result.title || result.id || 'Untitled';
|
|
225
225
|
const subtitle = result.subtitle || '';
|
|
226
226
|
const tags = result.tags || [];
|
|
227
227
|
|
|
228
|
-
//
|
|
228
|
+
// instance tags if available
|
|
229
229
|
const tagsHtml =
|
|
230
230
|
tags.length > 0
|
|
231
231
|
? `<div class="search-result-tags">
|
|
@@ -247,7 +247,7 @@ const SearchBox = {
|
|
|
247
247
|
</div>
|
|
248
248
|
</div>
|
|
249
249
|
`;
|
|
250
|
-
}
|
|
250
|
+
}
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
253
|
* Navigates through search results using keyboard arrow keys.
|
|
@@ -260,7 +260,7 @@ const SearchBox = {
|
|
|
260
260
|
* @param {number} totalItems - Total number of result items.
|
|
261
261
|
* @returns {number} New active index after navigation.
|
|
262
262
|
*/
|
|
263
|
-
navigateResults
|
|
263
|
+
static navigateResults(direction, containerId, currentIndex, totalItems) {
|
|
264
264
|
if (!containerId || totalItems === 0) return currentIndex;
|
|
265
265
|
|
|
266
266
|
const container = s(`#${containerId}`) || s(`.${containerId}`);
|
|
@@ -289,7 +289,7 @@ const SearchBox = {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
return newIndex;
|
|
292
|
-
}
|
|
292
|
+
}
|
|
293
293
|
|
|
294
294
|
/**
|
|
295
295
|
* Searches through default application routes for matches.
|
|
@@ -303,7 +303,7 @@ const SearchBox = {
|
|
|
303
303
|
* @param {string} [context.options.searchCustomImgClass] - Custom image class to search for.
|
|
304
304
|
* @returns {Array<object>} Array of route search results.
|
|
305
305
|
*/
|
|
306
|
-
searchRoutes
|
|
306
|
+
static searchRoutes(query, context) {
|
|
307
307
|
const results = [];
|
|
308
308
|
const { RouterInstance, options = {} } = context;
|
|
309
309
|
|
|
@@ -346,7 +346,7 @@ const SearchBox = {
|
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
348
|
return results;
|
|
349
|
-
}
|
|
349
|
+
}
|
|
350
350
|
|
|
351
351
|
/**
|
|
352
352
|
* Executes search across all registered providers and default routes.
|
|
@@ -356,7 +356,7 @@ const SearchBox = {
|
|
|
356
356
|
* @param {object} [context={}] - Search context object passed to all providers.
|
|
357
357
|
* @returns {Promise<Array<object>>} Promise resolving to combined, priority-sorted results array.
|
|
358
358
|
*/
|
|
359
|
-
|
|
359
|
+
static async search(query, context = {}) {
|
|
360
360
|
const allResults = [];
|
|
361
361
|
|
|
362
362
|
// Always include default route search (backward compatible)
|
|
@@ -387,7 +387,7 @@ const SearchBox = {
|
|
|
387
387
|
allResults.sort((a, b) => (a.priority || 50) - (b.priority || 50));
|
|
388
388
|
|
|
389
389
|
return allResults;
|
|
390
|
-
}
|
|
390
|
+
}
|
|
391
391
|
|
|
392
392
|
/**
|
|
393
393
|
* Renders search results into a container element.
|
|
@@ -396,10 +396,10 @@ const SearchBox = {
|
|
|
396
396
|
* @memberof SearchBoxClient.SearchBox
|
|
397
397
|
* @param {Array<object>} results - Array of search results to render.
|
|
398
398
|
* @param {string} containerId - Results container element ID or class name.
|
|
399
|
-
* @param {object} [context={}] -
|
|
399
|
+
* @param {object} [context={}] - instance context passed to renderers and handlers.
|
|
400
400
|
* @returns {void}
|
|
401
401
|
*/
|
|
402
|
-
renderResults
|
|
402
|
+
static renderResults(results, containerId, context = {}) {
|
|
403
403
|
const container = s(`#${containerId}`) || s(`.${containerId}`);
|
|
404
404
|
if (!container) {
|
|
405
405
|
logger.warn(`Container ${containerId} not found`);
|
|
@@ -468,7 +468,7 @@ const SearchBox = {
|
|
|
468
468
|
provider.attachTagHandlers();
|
|
469
469
|
}
|
|
470
470
|
});
|
|
471
|
-
}
|
|
471
|
+
}
|
|
472
472
|
|
|
473
473
|
/**
|
|
474
474
|
* Attaches delete event handlers to result delete buttons within a specific container.
|
|
@@ -481,7 +481,7 @@ const SearchBox = {
|
|
|
481
481
|
* @param {object} [context={}] - Context object.
|
|
482
482
|
* @returns {void}
|
|
483
483
|
*/
|
|
484
|
-
attachDeleteHandlers
|
|
484
|
+
static attachDeleteHandlers(container, results, containerId, context = {}) {
|
|
485
485
|
// Only select delete buttons within this specific container
|
|
486
486
|
const deleteButtons = container.querySelectorAll('.search-result-delete-btn');
|
|
487
487
|
deleteButtons.forEach((btn) => {
|
|
@@ -530,7 +530,7 @@ const SearchBox = {
|
|
|
530
530
|
}
|
|
531
531
|
});
|
|
532
532
|
});
|
|
533
|
-
}
|
|
533
|
+
}
|
|
534
534
|
|
|
535
535
|
/**
|
|
536
536
|
* Renders a default route search result.
|
|
@@ -542,11 +542,11 @@ const SearchBox = {
|
|
|
542
542
|
* @param {HTMLElement} [result.fontAwesomeIcon] - FontAwesome icon element.
|
|
543
543
|
* @param {HTMLElement} [result.imgElement] - Image icon element.
|
|
544
544
|
* @param {number} index - The index of this result in the results array.
|
|
545
|
-
* @param {object} [context={}] -
|
|
545
|
+
* @param {object} [context={}] - instance context object.
|
|
546
546
|
* @param {object} [context.options] - Additional rendering options.
|
|
547
547
|
* @returns {string} HTML string for the route search result.
|
|
548
548
|
*/
|
|
549
|
-
renderRouteResult
|
|
549
|
+
static renderRouteResult(result, index, context = {}) {
|
|
550
550
|
const { options = {} } = context;
|
|
551
551
|
const routerId = result.routerId;
|
|
552
552
|
const fontAwesomeIcon = result.fontAwesomeIcon;
|
|
@@ -584,7 +584,7 @@ const SearchBox = {
|
|
|
584
584
|
}
|
|
585
585
|
}
|
|
586
586
|
|
|
587
|
-
const translatedText = Translate.
|
|
587
|
+
const translatedText = Translate.instance(routerId);
|
|
588
588
|
|
|
589
589
|
return html`
|
|
590
590
|
<div
|
|
@@ -600,7 +600,7 @@ const SearchBox = {
|
|
|
600
600
|
</div>
|
|
601
601
|
</div>
|
|
602
602
|
`;
|
|
603
|
-
}
|
|
603
|
+
}
|
|
604
604
|
|
|
605
605
|
/**
|
|
606
606
|
* Attaches click event handlers to all rendered search results.
|
|
@@ -612,7 +612,7 @@ const SearchBox = {
|
|
|
612
612
|
* @param {Function} [context.onResultClick] - Callback invoked after any result is clicked.
|
|
613
613
|
* @returns {void}
|
|
614
614
|
*/
|
|
615
|
-
attachClickHandlers
|
|
615
|
+
static attachClickHandlers(results, containerId, context = {}) {
|
|
616
616
|
results.forEach((result, index) => {
|
|
617
617
|
const element = s(`[data-result-index="${index}"]`);
|
|
618
618
|
if (!element) return;
|
|
@@ -643,7 +643,7 @@ const SearchBox = {
|
|
|
643
643
|
}
|
|
644
644
|
};
|
|
645
645
|
});
|
|
646
|
-
}
|
|
646
|
+
}
|
|
647
647
|
|
|
648
648
|
/**
|
|
649
649
|
* Scrolls an element into view within a scrollable container if needed.
|
|
@@ -668,7 +668,7 @@ const SearchBox = {
|
|
|
668
668
|
* @param {HTMLElement} container - The scrollable container (or parent of scrollable).
|
|
669
669
|
* @returns {void}
|
|
670
670
|
*/
|
|
671
|
-
scrollIntoViewIfNeeded
|
|
671
|
+
static scrollIntoViewIfNeeded(element, container) {
|
|
672
672
|
if (!element || !container) return;
|
|
673
673
|
|
|
674
674
|
// CRITICAL FIX: Find the actual scrollable container
|
|
@@ -744,7 +744,7 @@ const SearchBox = {
|
|
|
744
744
|
});
|
|
745
745
|
}
|
|
746
746
|
}, 0);
|
|
747
|
-
}
|
|
747
|
+
}
|
|
748
748
|
|
|
749
749
|
/**
|
|
750
750
|
* Gets base CSS styles for SearchBox with theme-aware styling.
|
|
@@ -753,7 +753,7 @@ const SearchBox = {
|
|
|
753
753
|
* @memberof SearchBoxClient.SearchBox
|
|
754
754
|
* @returns {string} CSS string containing all base SearchBox styles.
|
|
755
755
|
*/
|
|
756
|
-
getBaseStyles
|
|
756
|
+
static getBaseStyles = () => {
|
|
757
757
|
// Get theme color from subThemeManager
|
|
758
758
|
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
759
759
|
const hasThemeColor = themeColor && themeColor !== null;
|
|
@@ -968,7 +968,7 @@ const SearchBox = {
|
|
|
968
968
|
transition: all 0.2s ease;
|
|
969
969
|
}
|
|
970
970
|
`;
|
|
971
|
-
}
|
|
971
|
+
};
|
|
972
972
|
|
|
973
973
|
/**
|
|
974
974
|
* Injects base SearchBox styles into the document head.
|
|
@@ -977,7 +977,7 @@ const SearchBox = {
|
|
|
977
977
|
* @memberof SearchBoxClient.SearchBox
|
|
978
978
|
* @returns {void}
|
|
979
979
|
*/
|
|
980
|
-
injectStyles
|
|
980
|
+
static injectStyles() {
|
|
981
981
|
const styleId = 'search-box-base-styles';
|
|
982
982
|
let styleTag = document.getElementById(styleId);
|
|
983
983
|
|
|
@@ -1001,7 +1001,7 @@ const SearchBox = {
|
|
|
1001
1001
|
}
|
|
1002
1002
|
};
|
|
1003
1003
|
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
1006
|
|
|
1007
1007
|
export { SearchBox };
|
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { UserService } from '../../services/user/user.service.js';
|
|
2
2
|
import { Auth } from './Auth.js';
|
|
3
3
|
import { BtnIcon } from './BtnIcon.js';
|
|
4
|
+
import { AuthEventType, authSignupEvents } from './ClientEvents.js';
|
|
4
5
|
import { EventsUI } from './EventsUI.js';
|
|
5
6
|
import { Input } from './Input.js';
|
|
6
7
|
import { NotificationManager } from './NotificationManager.js';
|
|
7
8
|
import { Translate } from './Translate.js';
|
|
8
9
|
import { Validator } from './Validator.js';
|
|
9
10
|
import { s } from './VanillaJs.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
class SignUp {
|
|
12
|
+
static Event = {};
|
|
13
|
+
static onSignup(listener, options = {}) {
|
|
14
|
+
return authSignupEvents.on(AuthEventType.signup, listener, options);
|
|
15
|
+
}
|
|
16
|
+
static offSignup(key) {
|
|
17
|
+
return authSignupEvents.off(key);
|
|
18
|
+
}
|
|
19
|
+
static hasSignupListener(key) {
|
|
20
|
+
return authSignupEvents.has(key);
|
|
21
|
+
}
|
|
22
|
+
static async Trigger(options) {
|
|
23
|
+
await authSignupEvents.emit(AuthEventType.signup, options);
|
|
24
|
+
for (const eventKey of Object.keys(SignUp.Event)) await SignUp.Event[eventKey](options);
|
|
25
|
+
}
|
|
26
|
+
static async instance(options = { bottomRender: async () => '' }) {
|
|
17
27
|
setTimeout(async () => {
|
|
18
28
|
const formData = [
|
|
19
29
|
{
|
|
@@ -33,7 +43,6 @@ const SignUp = {
|
|
|
33
43
|
},
|
|
34
44
|
];
|
|
35
45
|
const validators = await Validator.instance(formData);
|
|
36
|
-
|
|
37
46
|
EventsUI.onClick(`.btn-sign-up`, async (e) => {
|
|
38
47
|
e.preventDefault();
|
|
39
48
|
const { errorMessage } = await validators();
|
|
@@ -47,23 +56,23 @@ const SignUp = {
|
|
|
47
56
|
let error = '';
|
|
48
57
|
if (data.message) {
|
|
49
58
|
if (data.message.match('duplicate')) {
|
|
50
|
-
if (data.message.match('username')) error += Translate.
|
|
51
|
-
if (data.message.match('email')) error += Translate.
|
|
59
|
+
if (data.message.match('username')) error += Translate.instance('error-username-taken');
|
|
60
|
+
if (data.message.match('email')) error += Translate.instance('error-email-taken');
|
|
52
61
|
} else {
|
|
53
|
-
if (data.message.match('username')) error += Translate.
|
|
54
|
-
if (data.message.match('email')) error += Translate.
|
|
55
|
-
if (data.message.match('password')) error += Translate.
|
|
62
|
+
if (data.message.match('username')) error += Translate.instance('error-username-invalid');
|
|
63
|
+
if (data.message.match('email')) error += Translate.instance('error-email-invalid');
|
|
64
|
+
if (data.message.match('password')) error += Translate.instance('error-password-invalid');
|
|
56
65
|
}
|
|
57
66
|
return error;
|
|
58
67
|
}
|
|
59
|
-
return Translate.
|
|
68
|
+
return Translate.instance('error-register-user');
|
|
60
69
|
};
|
|
61
70
|
NotificationManager.Push({
|
|
62
71
|
html:
|
|
63
72
|
typeof result.data === 'string'
|
|
64
73
|
? result.data
|
|
65
74
|
: result.status === 'success'
|
|
66
|
-
? Translate.
|
|
75
|
+
? Translate.instance(`success-register-user`)
|
|
67
76
|
: handleSignUpError(result),
|
|
68
77
|
status: result.status,
|
|
69
78
|
});
|
|
@@ -81,64 +90,64 @@ const SignUp = {
|
|
|
81
90
|
});
|
|
82
91
|
});
|
|
83
92
|
return html`
|
|
84
|
-
${await BtnIcon.
|
|
93
|
+
${await BtnIcon.instance({
|
|
85
94
|
class: 'in section-mp form-button btn-sign-up-i-have-account',
|
|
86
|
-
label: html`<i class="fas fa-sign-in-alt"></i> ${Translate.
|
|
95
|
+
label: html`<i class="fas fa-sign-in-alt"></i> ${Translate.instance('i-have-account')}<br />${Translate.instance(
|
|
87
96
|
'log-in',
|
|
88
97
|
)}`,
|
|
89
98
|
type: 'button',
|
|
90
99
|
})}
|
|
91
100
|
<form class="in">
|
|
92
101
|
<div class="in">
|
|
93
|
-
${await Input.
|
|
102
|
+
${await Input.instance({
|
|
94
103
|
id: `sign-up-username`,
|
|
95
104
|
type: 'text',
|
|
96
|
-
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.
|
|
105
|
+
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.instance('username')}`,
|
|
97
106
|
containerClass: 'inl section-mp width-mini-box input-container',
|
|
98
107
|
placeholder: true,
|
|
99
108
|
})}
|
|
100
109
|
</div>
|
|
101
110
|
<div class="in">
|
|
102
|
-
${await Input.
|
|
111
|
+
${await Input.instance({
|
|
103
112
|
id: `sign-up-email`,
|
|
104
113
|
type: 'email',
|
|
105
|
-
label: html`<i class="fa-solid fa-envelope"></i> ${Translate.
|
|
114
|
+
label: html`<i class="fa-solid fa-envelope"></i> ${Translate.instance('email')}`,
|
|
106
115
|
containerClass: 'inl section-mp width-mini-box input-container',
|
|
107
116
|
placeholder: true,
|
|
108
117
|
autocomplete: 'email',
|
|
109
118
|
})}
|
|
110
119
|
</div>
|
|
111
120
|
<div class="in">
|
|
112
|
-
${await Input.
|
|
121
|
+
${await Input.instance({
|
|
113
122
|
id: `sign-up-password`,
|
|
114
123
|
type: 'password',
|
|
115
124
|
autocomplete: 'new-password',
|
|
116
|
-
label: html`<i class="fa-solid fa-lock"></i> ${Translate.
|
|
125
|
+
label: html`<i class="fa-solid fa-lock"></i> ${Translate.instance('password')}`,
|
|
117
126
|
containerClass: 'inl section-mp width-mini-box input-container',
|
|
118
127
|
placeholder: true,
|
|
119
128
|
})}
|
|
120
129
|
</div>
|
|
121
130
|
<div class="in">
|
|
122
|
-
${await Input.
|
|
131
|
+
${await Input.instance({
|
|
123
132
|
id: `sign-up-repeat-password`,
|
|
124
133
|
type: 'password',
|
|
125
134
|
autocomplete: 'new-password',
|
|
126
|
-
label: html`<i class="fa-solid fa-lock"></i> ${Translate.
|
|
135
|
+
label: html`<i class="fa-solid fa-lock"></i> ${Translate.instance('repeat')}
|
|
136
|
+
${Translate.instance('password')}`,
|
|
127
137
|
containerClass: 'inl section-mp width-mini-box input-container',
|
|
128
138
|
placeholder: true,
|
|
129
139
|
})}
|
|
130
140
|
</div>
|
|
131
141
|
${options?.bottomRender ? await options.bottomRender() : ``}
|
|
132
142
|
<div class="in">
|
|
133
|
-
${await BtnIcon.
|
|
143
|
+
${await BtnIcon.instance({
|
|
134
144
|
class: 'in section-mp form-button btn-sign-up',
|
|
135
|
-
label: Translate.
|
|
145
|
+
label: Translate.instance('sign-up'),
|
|
136
146
|
type: 'submit',
|
|
137
147
|
})}
|
|
138
148
|
</div>
|
|
139
149
|
</form>
|
|
140
150
|
`;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
151
|
+
}
|
|
152
|
+
}
|
|
144
153
|
export { SignUp };
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @namespace SocketIoProvider
|
|
7
7
|
*/
|
|
8
8
|
import { io } from 'socket.io/client-dist/socket.io.esm.min.js';
|
|
9
|
+
import { SocketEventType, socketEvents } from './ClientEvents.js';
|
|
9
10
|
import { loggerFactory } from './Logger.js';
|
|
10
11
|
import { getWsBasePath, getWsBaseUrl } from '../../services/core/core.service.js';
|
|
11
12
|
|
|
@@ -46,6 +47,30 @@ class SocketIoProvider {
|
|
|
46
47
|
* @type {string|undefined}
|
|
47
48
|
*/
|
|
48
49
|
static host;
|
|
50
|
+
static onConnect(listener, options = {}) {
|
|
51
|
+
return socketEvents.on(SocketEventType.connect, listener, options);
|
|
52
|
+
}
|
|
53
|
+
static offConnect(key) {
|
|
54
|
+
return socketEvents.off(key);
|
|
55
|
+
}
|
|
56
|
+
static onConnectError(listener, options = {}) {
|
|
57
|
+
return socketEvents.on(SocketEventType.connectError, listener, options);
|
|
58
|
+
}
|
|
59
|
+
static offConnectError(key) {
|
|
60
|
+
return socketEvents.off(key);
|
|
61
|
+
}
|
|
62
|
+
static onDisconnect(listener, options = {}) {
|
|
63
|
+
return socketEvents.on(SocketEventType.disconnect, listener, options);
|
|
64
|
+
}
|
|
65
|
+
static offDisconnect(key) {
|
|
66
|
+
return socketEvents.off(key);
|
|
67
|
+
}
|
|
68
|
+
static onChannel(type, listener, options = {}) {
|
|
69
|
+
return socketEvents.on(SocketEventType.channel(type), listener, options);
|
|
70
|
+
}
|
|
71
|
+
static offChannel(key) {
|
|
72
|
+
return socketEvents.off(key);
|
|
73
|
+
}
|
|
49
74
|
|
|
50
75
|
/**
|
|
51
76
|
* Emits a JSON-serialized payload to the server on the specified channel.
|
|
@@ -75,7 +100,7 @@ class SocketIoProvider {
|
|
|
75
100
|
* @param {Object.<string, Object>} [options.channels] - Channel definitions to register listeners for.
|
|
76
101
|
* @returns {Promise<void>}
|
|
77
102
|
*/
|
|
78
|
-
static async
|
|
103
|
+
static async instance(options) {
|
|
79
104
|
if (this.socket) this.socket.disconnect();
|
|
80
105
|
const path = getWsBasePath();
|
|
81
106
|
this.host = options.host ? options.host : getWsBaseUrl({ wsBasePath: '' });
|
|
@@ -93,16 +118,19 @@ class SocketIoProvider {
|
|
|
93
118
|
|
|
94
119
|
this.socket.on('connect', () => {
|
|
95
120
|
logger.info(`event: connect | session id: ${this.socket.id}`);
|
|
121
|
+
socketEvents.emit(SocketEventType.connect, { id: this.socket.id });
|
|
96
122
|
Object.keys(this.Event.connect).map((keyEvent) => this.Event.connect[keyEvent]());
|
|
97
123
|
});
|
|
98
124
|
|
|
99
125
|
this.socket.on('connect_error', (err) => {
|
|
100
126
|
logger.info(`event: connect_error | reason: ${err.message}`);
|
|
127
|
+
socketEvents.emit(SocketEventType.connectError, { error: err });
|
|
101
128
|
Object.keys(this.Event.connect_error).map((keyEvent) => this.Event.connect_error[keyEvent](err));
|
|
102
129
|
});
|
|
103
130
|
|
|
104
131
|
this.socket.on('disconnect', (reason) => {
|
|
105
132
|
logger.info(`event: disconnect | reason: ${reason}`);
|
|
133
|
+
socketEvents.emit(SocketEventType.disconnect, { reason });
|
|
106
134
|
Object.keys(this.Event.disconnect).map((keyEvent) => this.Event.disconnect[keyEvent](reason));
|
|
107
135
|
});
|
|
108
136
|
|
|
@@ -120,8 +148,9 @@ class SocketIoProvider {
|
|
|
120
148
|
static setChannels(channels) {
|
|
121
149
|
Object.keys(channels).map((type) => {
|
|
122
150
|
logger.info(`load chanel`, type);
|
|
123
|
-
this.Event[type] = {};
|
|
151
|
+
if (!this.Event[type]) this.Event[type] = {};
|
|
124
152
|
this.socket.on(type, (...args) => {
|
|
153
|
+
socketEvents.emit(SocketEventType.channel(type), { type, args });
|
|
125
154
|
Object.keys(this.Event[type]).map((keyEvent) => this.Event[type][keyEvent](args));
|
|
126
155
|
});
|
|
127
156
|
});
|
|
@@ -28,14 +28,14 @@ class SocketIoHandlerProvider {
|
|
|
28
28
|
*
|
|
29
29
|
* @static
|
|
30
30
|
* @param {import('./AppStore.js').AppStore} appStore - The app-specific AppStore instance.
|
|
31
|
-
* @returns {{
|
|
31
|
+
* @returns {{ instance: function(): Promise<void> }} An object with an `instance` method for SocketIo event registration.
|
|
32
32
|
*/
|
|
33
33
|
static create(appStore) {
|
|
34
34
|
return {
|
|
35
|
-
|
|
35
|
+
instance() {
|
|
36
36
|
return new Promise((resolve) => {
|
|
37
37
|
for (const type of Object.keys(appStore.Data)) {
|
|
38
|
-
SocketIo.
|
|
38
|
+
SocketIo.onChannel(type, async ({ args }) => {
|
|
39
39
|
args = JSON.parse(args[0]);
|
|
40
40
|
switch (type) {
|
|
41
41
|
case 'chat':
|
|
@@ -61,10 +61,10 @@ class SocketIoHandlerProvider {
|
|
|
61
61
|
default:
|
|
62
62
|
break;
|
|
63
63
|
}
|
|
64
|
-
};
|
|
64
|
+
}, { key: s4() });
|
|
65
65
|
}
|
|
66
|
-
SocketIo.
|
|
67
|
-
SocketIo.
|
|
66
|
+
SocketIo.onConnect(async ({ id }) => {}, { key: s4() });
|
|
67
|
+
SocketIo.onDisconnect(async ({ reason }) => {}, { key: s4() });
|
|
68
68
|
return resolve();
|
|
69
69
|
});
|
|
70
70
|
},
|