underpost 2.8.883 → 2.8.885
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/README.md +4 -116
- package/bin/deploy.js +9 -10
- package/bin/file.js +4 -6
- package/cli.md +15 -11
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/src/api/user/user.service.js +3 -10
- package/src/cli/cluster.js +21 -0
- package/src/cli/cron.js +8 -0
- package/src/cli/db.js +63 -1
- package/src/cli/deploy.js +156 -3
- package/src/cli/env.js +43 -0
- package/src/cli/fs.js +94 -0
- package/src/cli/image.js +8 -0
- package/src/cli/index.js +17 -4
- package/src/cli/monitor.js +0 -1
- package/src/cli/repository.js +95 -2
- package/src/client/components/core/Css.js +16 -0
- package/src/client/components/core/Docs.js +5 -13
- package/src/client/components/core/Modal.js +57 -39
- package/src/client/components/core/Router.js +6 -3
- package/src/client/components/core/Worker.js +205 -118
- package/src/client/components/default/MenuDefault.js +1 -0
- package/src/client.dev.js +6 -3
- package/src/db/DataBaseProvider.js +65 -12
- package/src/db/mariadb/MariaDB.js +39 -6
- package/src/db/mongo/MongooseDB.js +51 -133
- package/src/index.js +1 -1
- package/src/mailer/EmailRender.js +58 -9
- package/src/mailer/MailerProvider.js +98 -25
- package/src/runtime/express/Express.js +248 -0
- package/src/runtime/lampp/Lampp.js +27 -8
- package/src/server/auth.js +82 -43
- package/src/server/client-build-live.js +14 -5
- package/src/server/client-dev-server.js +21 -8
- package/src/server/conf.js +78 -25
- package/src/server/peer.js +2 -2
- package/src/server/runtime.js +49 -208
- package/src/server/start.js +39 -0
- package/src/ws/IoInterface.js +132 -39
- package/src/ws/IoServer.js +79 -31
- package/src/ws/core/core.ws.connection.js +50 -16
- package/src/ws/core/core.ws.emit.js +47 -8
- package/src/ws/core/core.ws.server.js +62 -10
- package/src/runtime/nginx/Nginx.js +0 -3
package/src/cli/repository.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository module for managing Git operations and configurations.
|
|
3
|
+
* @module src/cli/repository.js
|
|
4
|
+
* @namespace UnderpostRepository
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
2
8
|
import dotenv from 'dotenv';
|
|
3
9
|
import { pbcopy, shellCd, shellExec } from '../server/process.js';
|
|
@@ -11,8 +17,23 @@ dotenv.config();
|
|
|
11
17
|
|
|
12
18
|
const logger = loggerFactory(import.meta);
|
|
13
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @class UnderpostRepository
|
|
22
|
+
* @description Manages Git operations and configurations.
|
|
23
|
+
* This class provides a set of static methods to automate various
|
|
24
|
+
* Git operations, including cloning, pulling, and committing changes.
|
|
25
|
+
* @memberof UnderpostRepository
|
|
26
|
+
*/
|
|
14
27
|
class UnderpostRepository {
|
|
15
28
|
static API = {
|
|
29
|
+
/**
|
|
30
|
+
* Clones a Git repository from GitHub.
|
|
31
|
+
* @param {string} [gitUri=`${process.env.GITHUB_USERNAME}/pwa-microservices-template`] - The URI of the GitHub repository (e.g., "username/repository").
|
|
32
|
+
* @param {object} [options={ bare: false, g8: false }] - Cloning options.
|
|
33
|
+
* @param {boolean} [options.bare=false] - If true, performs a bare clone.
|
|
34
|
+
* @param {boolean} [options.g8=false] - If true, uses the .g8 extension.
|
|
35
|
+
* @memberof UnderpostRepository
|
|
36
|
+
*/
|
|
16
37
|
clone(gitUri = `${process.env.GITHUB_USERNAME}/pwa-microservices-template`, options = { bare: false, g8: false }) {
|
|
17
38
|
const gExtension = options.g8 === true ? '.g8' : '.git';
|
|
18
39
|
const repoName = gitUri.split('/').pop();
|
|
@@ -26,6 +47,14 @@ class UnderpostRepository {
|
|
|
26
47
|
},
|
|
27
48
|
);
|
|
28
49
|
},
|
|
50
|
+
/**
|
|
51
|
+
* Pulls updates from a GitHub repository.
|
|
52
|
+
* @param {string} [repoPath='./'] - The local path to the repository.
|
|
53
|
+
* @param {string} [gitUri=`${process.env.GITHUB_USERNAME}/pwa-microservices-template`] - The URI of the GitHub repository.
|
|
54
|
+
* @param {object} [options={ g8: false }] - Pulling options.
|
|
55
|
+
* @param {boolean} [options.g8=false] - If true, uses the .g8 extension.
|
|
56
|
+
* @memberof UnderpostRepository
|
|
57
|
+
*/
|
|
29
58
|
pull(
|
|
30
59
|
repoPath = './',
|
|
31
60
|
gitUri = `${process.env.GITHUB_USERNAME}/pwa-microservices-template`,
|
|
@@ -41,6 +70,18 @@ class UnderpostRepository {
|
|
|
41
70
|
},
|
|
42
71
|
);
|
|
43
72
|
},
|
|
73
|
+
/**
|
|
74
|
+
* Creates a Git commit with a conventional commit message.
|
|
75
|
+
* @param {string} [repoPath='./'] - The local path to the repository.
|
|
76
|
+
* @param {string} [commitType='feat'] - The type of commit (e.g., 'feat', 'fix', 'docs', 'reset').
|
|
77
|
+
* @param {string} [subModule=''] - The submodule or scope of the commit.
|
|
78
|
+
* @param {string} [message=''] - The commit message.
|
|
79
|
+
* @param {object} [options={ copy: false, info: false, empty: false }] - Commit options.
|
|
80
|
+
* @param {boolean} [options.copy=false] - If true, copies the commit message to the clipboard.
|
|
81
|
+
* @param {boolean} [options.info=false] - If true, displays information about commit types.
|
|
82
|
+
* @param {boolean} [options.empty=false] - If true, allows an empty commit.
|
|
83
|
+
* @memberof UnderpostRepository
|
|
84
|
+
*/
|
|
44
85
|
commit(
|
|
45
86
|
repoPath = './',
|
|
46
87
|
commitType = 'feat',
|
|
@@ -65,9 +106,18 @@ class UnderpostRepository {
|
|
|
65
106
|
shellExec(`cd ${repoPath} && git commit ${options?.empty ? `--allow-empty ` : ''}-m "${_message}"`);
|
|
66
107
|
},
|
|
67
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Pushes commits to a remote GitHub repository.
|
|
111
|
+
* @param {string} [repoPath='./'] - The local path to the repository.
|
|
112
|
+
* @param {string} [gitUri=`${process.env.GITHUB_USERNAME}/pwa-microservices-template`] - The URI of the GitHub repository.
|
|
113
|
+
* @param {object} [options={ f: false, g8: false }] - Push options.
|
|
114
|
+
* @param {boolean} [options.f=false] - If true, forces the push.
|
|
115
|
+
* @param {boolean} [options.g8=false] - If true, uses the .g8 extension.
|
|
116
|
+
* @memberof UnderpostRepository
|
|
117
|
+
*/
|
|
68
118
|
push(
|
|
69
119
|
repoPath = './',
|
|
70
|
-
gitUri = `${process.env.GITHUB_USERNAME}/pwa-microservices-template
|
|
120
|
+
gitUri = `${process.env.GITHUB_USERNAME}/pwa-microservices-template`,
|
|
71
121
|
options = { f: false, g8: false },
|
|
72
122
|
) {
|
|
73
123
|
const gExtension = options.g8 === true || options.G8 === true ? '.g8' : '.git';
|
|
@@ -90,11 +140,34 @@ class UnderpostRepository {
|
|
|
90
140
|
);
|
|
91
141
|
},
|
|
92
142
|
|
|
93
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Creates a new Underpost project, service, or configuration.
|
|
145
|
+
* @param {string} repositoryName - The name of the new project or service, or a deployId.
|
|
146
|
+
* @param {object} [options={ dev: false, deployId: false, cluster: false, subConf: '' }] - Creation options.
|
|
147
|
+
* @param {boolean} [options.dev=false] - If true, sets up a development project.
|
|
148
|
+
* @param {boolean} [options.deployId=false] - If true, creates deploy ID configuration files.
|
|
149
|
+
* @param {boolean} [options.cluster=false] - If true, creates cluster configuration files.
|
|
150
|
+
* @param {string} [options.subConf=''] - If provided, creates a sub-configuration for a deployId.
|
|
151
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
152
|
+
* @memberof UnderpostRepository
|
|
153
|
+
*/
|
|
154
|
+
new(repositoryName, options = { dev: false, deployId: false, cluster: false, subConf: '' }) {
|
|
94
155
|
return new Promise(async (resolve, reject) => {
|
|
95
156
|
try {
|
|
96
157
|
await logger.setUpInfo();
|
|
97
158
|
actionInitLog();
|
|
159
|
+
if (options.subConf && typeof options.subConf === 'string') {
|
|
160
|
+
const deployId = repositoryName;
|
|
161
|
+
logger.info('Creating sub conf', {
|
|
162
|
+
deployId,
|
|
163
|
+
subConf: options.subConf,
|
|
164
|
+
});
|
|
165
|
+
fs.copySync(
|
|
166
|
+
`./engine-private/conf/${deployId}/conf.server.json`,
|
|
167
|
+
`./engine-private/conf/${deployId}/conf.server.dev.${options.subConf}.json`,
|
|
168
|
+
);
|
|
169
|
+
return resolve();
|
|
170
|
+
}
|
|
98
171
|
if (repositoryName === 'service')
|
|
99
172
|
return resolve(
|
|
100
173
|
await UnderpostStartUp.API.listenPortController(UnderpostStartUp.API.listenServerFactory(), ':'),
|
|
@@ -126,12 +199,26 @@ class UnderpostRepository {
|
|
|
126
199
|
});
|
|
127
200
|
},
|
|
128
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Gets a list of deleted files from a Git repository.
|
|
204
|
+
* @param {string} [path='.'] - The path to the repository.
|
|
205
|
+
* @returns {string[]} An array of deleted file paths.
|
|
206
|
+
* @memberof UnderpostRepository
|
|
207
|
+
*/
|
|
129
208
|
getDeleteFiles(path = '.') {
|
|
130
209
|
const commandUntrack = `cd ${path} && git ls-files --deleted`;
|
|
131
210
|
const diffUntrackOutput = shellExec(commandUntrack, { stdout: true, silent: true });
|
|
132
211
|
return diffUntrackOutput.toString().split('\n').filter(Boolean);
|
|
133
212
|
},
|
|
134
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Gets a list of changed (modified and untracked) files in a Git repository.
|
|
216
|
+
* @param {string} [path='.'] - The path to the repository.
|
|
217
|
+
* @param {string} [extension=''] - An optional file extension to filter by.
|
|
218
|
+
* @param {boolean} [head=false] - If true, diffs against HEAD^.
|
|
219
|
+
* @returns {string[]} An array of changed file paths.
|
|
220
|
+
* @memberof UnderpostRepository
|
|
221
|
+
*/
|
|
135
222
|
getChangedFiles(path = '.', extension = '', head = false) {
|
|
136
223
|
const extensionFilter = extension ? `-- '***.${extension}'` : '';
|
|
137
224
|
const command = `cd ${path} && git diff ${head ? 'HEAD^ HEAD ' : ''}--name-only ${extensionFilter}`;
|
|
@@ -146,6 +233,12 @@ class UnderpostRepository {
|
|
|
146
233
|
.concat(diffUntrackOutput.toString().split('\n').filter(Boolean))
|
|
147
234
|
.filter((f) => !deleteFiles.includes(f));
|
|
148
235
|
},
|
|
236
|
+
/**
|
|
237
|
+
* Updates the private configuration repository for a given deployId.
|
|
238
|
+
* @param {string} deployId - The deployment ID.
|
|
239
|
+
* @returns {{validVersion: boolean, engineVersion: string, deployVersion: string}} An object indicating if the versions are valid.
|
|
240
|
+
* @memberof UnderpostRepository
|
|
241
|
+
*/
|
|
149
242
|
privateConfUpdate(deployId) {
|
|
150
243
|
shellCd(`/home/dd/engine`);
|
|
151
244
|
const privateRepoName = `engine-${deployId.split('dd-')[1]}-private`;
|
|
@@ -831,6 +831,14 @@ const subThemeManager = {
|
|
|
831
831
|
color: ${this.lightColor};
|
|
832
832
|
background-color: ${lightenHex(this.lightColor, 0.8)};
|
|
833
833
|
}
|
|
834
|
+
.main-sub-btn-active {
|
|
835
|
+
color: ${this.lightColor};
|
|
836
|
+
background-color: rgba(0, 0, 0, 0.3);
|
|
837
|
+
}
|
|
838
|
+
.main-sub-btn-active:hover {
|
|
839
|
+
color: ${this.lightColor};
|
|
840
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
841
|
+
}
|
|
834
842
|
</style>`;
|
|
835
843
|
};
|
|
836
844
|
},
|
|
@@ -845,6 +853,14 @@ const subThemeManager = {
|
|
|
845
853
|
color: ${lightenHex(this.darkColor, 0.8)};
|
|
846
854
|
background-color: ${darkenHex(this.darkColor, 0.75)};
|
|
847
855
|
}
|
|
856
|
+
.main-sub-btn-active {
|
|
857
|
+
color: ${lightenHex(this.darkColor, 0.8)};
|
|
858
|
+
background-color: rgba(255, 255, 255, 0.3);
|
|
859
|
+
}
|
|
860
|
+
.main-sub-btn-active:hover {
|
|
861
|
+
color: ${lightenHex(this.darkColor, 0.8)};
|
|
862
|
+
background-color: rgba(255, 255, 255, 0.2);
|
|
863
|
+
}
|
|
848
864
|
</style>`;
|
|
849
865
|
};
|
|
850
866
|
},
|
|
@@ -8,7 +8,7 @@ import { htmls, s } from './VanillaJs.js';
|
|
|
8
8
|
// https://mintlify.com/docs/quickstart
|
|
9
9
|
|
|
10
10
|
const Docs = {
|
|
11
|
-
RenderModal: async function (type
|
|
11
|
+
RenderModal: async function (type) {
|
|
12
12
|
const docData = this.Data.find((d) => d.type === type);
|
|
13
13
|
const ModalId = `modal-docs-${docData.type}`;
|
|
14
14
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
@@ -35,7 +35,7 @@ const Docs = {
|
|
|
35
35
|
observer: true,
|
|
36
36
|
barMode: 'top-bottom-bar',
|
|
37
37
|
query: true,
|
|
38
|
-
|
|
38
|
+
RouterInstance: Modal.Data['modal-docs'].options.RouterInstance,
|
|
39
39
|
});
|
|
40
40
|
Modal.Data[ModalId].onObserverListener[ModalId] = () => {
|
|
41
41
|
if (s(`.iframe-${ModalId}`))
|
|
@@ -118,25 +118,17 @@ const Docs = {
|
|
|
118
118
|
const { idModal } = options;
|
|
119
119
|
this.Tokens[idModal] = options;
|
|
120
120
|
setTimeout(() => {
|
|
121
|
-
const cleanActive = () => {
|
|
122
|
-
s(`.btn-docs-src`).classList.remove('main-btn-menu-active');
|
|
123
|
-
s(`.btn-docs-api`).classList.remove('main-btn-menu-active');
|
|
124
|
-
s(`.btn-docs-coverage`).classList.remove('main-btn-menu-active');
|
|
125
|
-
};
|
|
126
121
|
s(`.btn-docs-src`).onclick = async () => {
|
|
127
122
|
setQueryPath({ path: 'docs', queryPath: 'src' });
|
|
128
|
-
|
|
129
|
-
await this.RenderModal('src', options.modalOptions);
|
|
123
|
+
await this.RenderModal('src');
|
|
130
124
|
};
|
|
131
125
|
s(`.btn-docs-api`).onclick = async () => {
|
|
132
126
|
setQueryPath({ path: 'docs', queryPath: 'api' });
|
|
133
|
-
|
|
134
|
-
await this.RenderModal('api', options.modalOptions);
|
|
127
|
+
await this.RenderModal('api');
|
|
135
128
|
};
|
|
136
129
|
s(`.btn-docs-coverage`).onclick = async () => {
|
|
137
130
|
setQueryPath({ path: 'docs', queryPath: 'coverage' });
|
|
138
|
-
|
|
139
|
-
await this.RenderModal('coverage', options.modalOptions);
|
|
131
|
+
await this.RenderModal('coverage');
|
|
140
132
|
};
|
|
141
133
|
|
|
142
134
|
s(`.btn-docs-coverage-link`).onclick = () => {
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
getProxyPath,
|
|
22
22
|
setPath,
|
|
23
23
|
coreUI,
|
|
24
|
+
sanitizeRoute,
|
|
25
|
+
getQueryParams,
|
|
24
26
|
} from './Router.js';
|
|
25
27
|
import { NotificationManager } from './NotificationManager.js';
|
|
26
28
|
import { EventsUI } from './EventsUI.js';
|
|
@@ -90,11 +92,6 @@ const Modal = {
|
|
|
90
92
|
query: options.query ? `${window.location.search}` : undefined,
|
|
91
93
|
getTop: () => {
|
|
92
94
|
const result = windowGetH() - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar);
|
|
93
|
-
// TODO: mobile padding gap on init size top height, Iphone SE responsive case
|
|
94
|
-
// logger.warn('getTop', {
|
|
95
|
-
// top: result,
|
|
96
|
-
// height: Modal.Data[idModal].getHeight(),
|
|
97
|
-
// });
|
|
98
95
|
return result;
|
|
99
96
|
},
|
|
100
97
|
getHeight: () => {
|
|
@@ -120,6 +117,10 @@ const Modal = {
|
|
|
120
117
|
}px`
|
|
121
118
|
: `-${ops?.open ? '0px' : originSlideMenuWidth}px`
|
|
122
119
|
}`,
|
|
120
|
+
center: () => {
|
|
121
|
+
top = `${windowGetH() / 2 - height / 2}px`;
|
|
122
|
+
left = `${windowGetW() / 2 - width / 2}px`;
|
|
123
|
+
},
|
|
123
124
|
};
|
|
124
125
|
|
|
125
126
|
if (options && 'mode' in options) {
|
|
@@ -1169,6 +1170,7 @@ const Modal = {
|
|
|
1169
1170
|
});
|
|
1170
1171
|
EventsUI.onClick(`.action-btn-home`, async () => {
|
|
1171
1172
|
await Modal.onHomeRouterEvent();
|
|
1173
|
+
subMenuHandler(Object.keys(options.RouterInstance.Routes()));
|
|
1172
1174
|
Object.keys(this.Data[idModal].onHome).map((keyListener) => this.Data[idModal].onHome[keyListener]());
|
|
1173
1175
|
});
|
|
1174
1176
|
EventsUI.onClick(`.action-btn-app-icon`, () => s(`.action-btn-home`).click());
|
|
@@ -1349,7 +1351,6 @@ const Modal = {
|
|
|
1349
1351
|
removeEvent();
|
|
1350
1352
|
}
|
|
1351
1353
|
});
|
|
1352
|
-
// TODO: mobile padding gap on init size top height, Iphone SE responsive case
|
|
1353
1354
|
setTimeout(window.onresize);
|
|
1354
1355
|
});
|
|
1355
1356
|
})();
|
|
@@ -1387,10 +1388,7 @@ const Modal = {
|
|
|
1387
1388
|
return;
|
|
1388
1389
|
}
|
|
1389
1390
|
|
|
1390
|
-
if (idModal !== 'main-body' && options.mode !== 'view' && !options.disableCenter)
|
|
1391
|
-
top = `${windowGetH() / 2 - height / 2}px`;
|
|
1392
|
-
left = `${windowGetW() / 2 - width / 2}px`;
|
|
1393
|
-
}
|
|
1391
|
+
if (idModal !== 'main-body' && options.mode !== 'view' && !options.disableCenter) Modal.Data[idModal].center();
|
|
1394
1392
|
|
|
1395
1393
|
const render = html` <style class="style-${idModal}">
|
|
1396
1394
|
.${idModal} {
|
|
@@ -1860,26 +1858,14 @@ const Modal = {
|
|
|
1860
1858
|
s(`.btn-maximize-${idModal}`).style.display = null;
|
|
1861
1859
|
|
|
1862
1860
|
// Restore original dimensions and position
|
|
1861
|
+
this.Data[idModal].center();
|
|
1863
1862
|
modal.style.transform = '';
|
|
1864
|
-
modal.style.height =
|
|
1865
|
-
left =
|
|
1866
|
-
|
|
1867
|
-
modal.style.left = `${left}px`;
|
|
1863
|
+
modal.style.height = `${height}px`;
|
|
1864
|
+
modal.style.left = left;
|
|
1865
|
+
modal.style.top = top;
|
|
1868
1866
|
modal.style.width = `${width}px`;
|
|
1869
1867
|
modal.style.overflow = '';
|
|
1870
1868
|
|
|
1871
|
-
// Reset drag position
|
|
1872
|
-
dragPosition = { x: 0, y: 0 };
|
|
1873
|
-
|
|
1874
|
-
// Set new position
|
|
1875
|
-
modal.style.transform = `translate(0, 0)`;
|
|
1876
|
-
|
|
1877
|
-
// Adjust top position based on top bar visibility
|
|
1878
|
-
const heightDefaultTopBar = 40; // Default top bar height if not specified
|
|
1879
|
-
s(`.${idModal}`).style.top = s(`.main-body-btn-ui-close`).classList.contains('hide')
|
|
1880
|
-
? `0px`
|
|
1881
|
-
: `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
|
|
1882
|
-
|
|
1883
1869
|
// Re-enable drag after restore
|
|
1884
1870
|
if (dragInstance) {
|
|
1885
1871
|
dragInstance.updateOptions({
|
|
@@ -2191,14 +2177,13 @@ const Modal = {
|
|
|
2191
2177
|
: { ...Modal.subMenuBtnClass, _: { btnSelector, labelSelector } };
|
|
2192
2178
|
|
|
2193
2179
|
for (const keyDataBtn of Object.keys(_data)) {
|
|
2194
|
-
const {
|
|
2180
|
+
const { labelSelector, top } = _data[keyDataBtn];
|
|
2195
2181
|
if (top)
|
|
2196
2182
|
setTimeout(() => {
|
|
2197
2183
|
top();
|
|
2198
2184
|
});
|
|
2199
|
-
if (open) continue;
|
|
2200
2185
|
sa(labelSelector).forEach((el) => {
|
|
2201
|
-
el.classList.add('hide');
|
|
2186
|
+
if (!el.classList.contains('hide')) el.classList.add('hide');
|
|
2202
2187
|
el.style.transition = null;
|
|
2203
2188
|
});
|
|
2204
2189
|
|
|
@@ -2414,7 +2399,7 @@ const buildBadgeToolTipMenuOption = (id, sideKey = 'left') => {
|
|
|
2414
2399
|
};
|
|
2415
2400
|
|
|
2416
2401
|
const isSubMenuOpen = (subMenuId) => {
|
|
2417
|
-
return s(`.down-arrow-submenu-${subMenuId}`).style.rotate === '180deg';
|
|
2402
|
+
return s(`.down-arrow-submenu-${subMenuId}`) && s(`.down-arrow-submenu-${subMenuId}`).style.rotate === '180deg';
|
|
2418
2403
|
};
|
|
2419
2404
|
|
|
2420
2405
|
const subMenuRender = async (subMenuId) => {
|
|
@@ -2425,11 +2410,16 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2425
2410
|
|
|
2426
2411
|
if (!menuBtn || !menuContainer || !arrow) return;
|
|
2427
2412
|
|
|
2428
|
-
// if (Modal.subMenuBtnClass[subMenuId] && !(isSubMenuOpen(subMenuId) && Modal.subMenuBtnClass[subMenuId].open === true))
|
|
2429
|
-
// Modal.subMenuBtnClass[subMenuId].open = false;
|
|
2430
|
-
|
|
2431
2413
|
const top = () => {
|
|
2432
|
-
|
|
2414
|
+
let value = menuBtn.offsetTop + Modal.Data['modal-menu'].options.heightTopBar;
|
|
2415
|
+
|
|
2416
|
+
const isHidden = s('.main-body-btn-ui-open').classList.contains('hide');
|
|
2417
|
+
const isTopBottom = Modal.Data['modal-menu'].options.barMode === 'top-bottom-bar';
|
|
2418
|
+
|
|
2419
|
+
if (!isTopBottom && isHidden) value -= 51;
|
|
2420
|
+
else if (!isHidden) value += 51;
|
|
2421
|
+
|
|
2422
|
+
menuContainer.style.top = `${value}px`;
|
|
2433
2423
|
};
|
|
2434
2424
|
|
|
2435
2425
|
Modal.subMenuBtnClass[subMenuId] = {
|
|
@@ -2442,8 +2432,7 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2442
2432
|
menuBtn.style.transition = '.3s';
|
|
2443
2433
|
arrow.style.transition = '.3s';
|
|
2444
2434
|
|
|
2445
|
-
if (
|
|
2446
|
-
Modal.subMenuBtnClass[subMenuId].open = false;
|
|
2435
|
+
if (isSubMenuOpen(subMenuId)) {
|
|
2447
2436
|
// Close animation
|
|
2448
2437
|
menuContainer.style.overflow = 'hidden';
|
|
2449
2438
|
menuContainer.style.height = '0px';
|
|
@@ -2453,8 +2442,12 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2453
2442
|
arrow.style.rotate = '0deg';
|
|
2454
2443
|
});
|
|
2455
2444
|
} else {
|
|
2456
|
-
|
|
2457
|
-
|
|
2445
|
+
sa(`.menu-label-text-${subMenuId}`).forEach((el) => {
|
|
2446
|
+
if (!el.classList.contains('hide')) el.classList.add('hide');
|
|
2447
|
+
});
|
|
2448
|
+
setTimeout(() => {
|
|
2449
|
+
Modal.menuTextLabelAnimation('modal-menu', subMenuId);
|
|
2450
|
+
});
|
|
2458
2451
|
// Open animation
|
|
2459
2452
|
setTimeout(top, 360);
|
|
2460
2453
|
menuContainer.style.width = '320px';
|
|
@@ -2473,4 +2466,29 @@ const subMenuRender = async (subMenuId) => {
|
|
|
2473
2466
|
}, 500);
|
|
2474
2467
|
};
|
|
2475
2468
|
|
|
2476
|
-
|
|
2469
|
+
const subMenuHandler = (routes, route) => {
|
|
2470
|
+
route = sanitizeRoute(route);
|
|
2471
|
+
for (let _route of routes) {
|
|
2472
|
+
_route = sanitizeRoute(_route);
|
|
2473
|
+
if (_route !== route) {
|
|
2474
|
+
if (isSubMenuOpen(_route)) subMenuRender(_route);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
setTimeout(() => {
|
|
2478
|
+
let cid = getQueryParams().cid;
|
|
2479
|
+
if (s(`.main-sub-btn-active`)) s(`.main-sub-btn-active`).classList.remove('main-sub-btn-active');
|
|
2480
|
+
if (cid && s(`.btn-${route}-${cid}`)) {
|
|
2481
|
+
s(`.btn-${route}-${cid}`).classList.add('main-sub-btn-active');
|
|
2482
|
+
}
|
|
2483
|
+
});
|
|
2484
|
+
};
|
|
2485
|
+
|
|
2486
|
+
export {
|
|
2487
|
+
Modal,
|
|
2488
|
+
renderMenuLabel,
|
|
2489
|
+
renderViewTitle,
|
|
2490
|
+
buildBadgeToolTipMenuOption,
|
|
2491
|
+
subMenuRender,
|
|
2492
|
+
isSubMenuOpen,
|
|
2493
|
+
subMenuHandler,
|
|
2494
|
+
};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { titleFormatted } from './CommonJs.js';
|
|
8
8
|
import { loggerFactory } from './Logger.js';
|
|
9
9
|
import { htmls, s } from './VanillaJs.js';
|
|
10
|
-
import { Modal } from './Modal.js';
|
|
10
|
+
import { Modal, subMenuHandler } from './Modal.js';
|
|
11
11
|
import { Worker } from './Worker.js';
|
|
12
12
|
|
|
13
13
|
const logger = loggerFactory(import.meta, { trace: true });
|
|
@@ -162,6 +162,7 @@ const Router = function (options = { Routes: () => {}, e: new PopStateEvent() })
|
|
|
162
162
|
|
|
163
163
|
if (path === pushPath) {
|
|
164
164
|
for (const event of Object.keys(RouterEvents)) RouterEvents[event](routerEvent);
|
|
165
|
+
subMenuHandler(Object.keys(Routes()), route);
|
|
165
166
|
setDocTitle(route);
|
|
166
167
|
return Routes()[`/${route}`].render();
|
|
167
168
|
}
|
|
@@ -256,14 +257,15 @@ const closeModalRouteChangeEvent = (options = {}) => {
|
|
|
256
257
|
* @param {string} options.route - The route associated with the modal view.
|
|
257
258
|
* @memberof PwaRouter
|
|
258
259
|
*/
|
|
259
|
-
const handleModalViewRoute = (options = { route: '' }) => {
|
|
260
|
-
const { route } = options;
|
|
260
|
+
const handleModalViewRoute = (options = { RouterInstance: { Routes: () => {} }, route: '' }) => {
|
|
261
|
+
const { route, RouterInstance } = options;
|
|
261
262
|
if (!route) return;
|
|
262
263
|
|
|
263
264
|
let path = window.location.pathname;
|
|
264
265
|
if (path !== '/' && path[path.length - 1] === '/') path = path.slice(0, -1);
|
|
265
266
|
const proxyPath = getProxyPath();
|
|
266
267
|
const newPath = `${proxyPath}${route}`;
|
|
268
|
+
if (RouterInstance && RouterInstance.Routes) subMenuHandler(Object.keys(RouterInstance.Routes()), route);
|
|
267
269
|
|
|
268
270
|
if (path !== newPath) {
|
|
269
271
|
setPath(newPath);
|
|
@@ -311,4 +313,5 @@ export {
|
|
|
311
313
|
getProxyPath,
|
|
312
314
|
setPath,
|
|
313
315
|
setQueryParams,
|
|
316
|
+
sanitizeRoute,
|
|
314
317
|
};
|