underpost 2.8.1 → 2.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/ghpkg.yml +19 -49
  3. package/.github/workflows/npmpkg.yml +67 -0
  4. package/.github/workflows/publish.yml +5 -5
  5. package/.github/workflows/pwa-microservices-template.page.yml +12 -4
  6. package/.github/workflows/pwa-microservices-template.test.yml +2 -2
  7. package/.vscode/extensions.json +18 -71
  8. package/.vscode/settings.json +20 -3
  9. package/AUTHORS.md +16 -5
  10. package/CHANGELOG.md +123 -3
  11. package/Dockerfile +27 -70
  12. package/README.md +39 -29
  13. package/bin/build.js +186 -0
  14. package/bin/db.js +2 -24
  15. package/bin/deploy.js +1467 -236
  16. package/bin/file.js +67 -16
  17. package/bin/hwt.js +0 -10
  18. package/bin/index.js +1 -77
  19. package/bin/ssl.js +19 -11
  20. package/bin/util.js +9 -104
  21. package/bin/vs.js +26 -2
  22. package/cli.md +451 -0
  23. package/conf.js +29 -138
  24. package/docker-compose.yml +1 -1
  25. package/jsdoc.json +1 -1
  26. package/manifests/calico-custom-resources.yaml +25 -0
  27. package/manifests/deployment/adminer/deployment.yaml +32 -0
  28. package/manifests/deployment/adminer/kustomization.yaml +7 -0
  29. package/manifests/deployment/adminer/service.yaml +13 -0
  30. package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
  31. package/manifests/deployment/fastapi/backend-service.yml +19 -0
  32. package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
  33. package/manifests/deployment/fastapi/frontend-service.yml +15 -0
  34. package/manifests/deployment/kafka/deployment.yaml +69 -0
  35. package/manifests/deployment/mongo-express/deployment.yaml +60 -0
  36. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  37. package/manifests/kind-config-dev.yaml +12 -0
  38. package/manifests/kind-config.yaml +12 -0
  39. package/manifests/kubeadm-calico-config.yaml +119 -0
  40. package/manifests/letsencrypt-prod.yaml +15 -0
  41. package/manifests/mariadb/config.yaml +10 -0
  42. package/manifests/mariadb/kustomization.yaml +9 -0
  43. package/manifests/mariadb/pv.yaml +12 -0
  44. package/manifests/mariadb/pvc.yaml +10 -0
  45. package/manifests/mariadb/secret.yaml +8 -0
  46. package/manifests/mariadb/service.yaml +10 -0
  47. package/manifests/mariadb/statefulset.yaml +55 -0
  48. package/manifests/mongodb/backup-access.yaml +16 -0
  49. package/manifests/mongodb/backup-cronjob.yaml +42 -0
  50. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  51. package/manifests/mongodb/configmap.yaml +26 -0
  52. package/manifests/mongodb/headless-service.yaml +10 -0
  53. package/manifests/mongodb/kustomization.yaml +11 -0
  54. package/manifests/mongodb/pv-pvc.yaml +23 -0
  55. package/manifests/mongodb/statefulset.yaml +125 -0
  56. package/manifests/mongodb-4.4/kustomization.yaml +7 -0
  57. package/manifests/mongodb-4.4/pv-pvc.yaml +23 -0
  58. package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
  59. package/manifests/postgresql/configmap.yaml +9 -0
  60. package/manifests/postgresql/kustomization.yaml +10 -0
  61. package/manifests/postgresql/pv.yaml +15 -0
  62. package/manifests/postgresql/pvc.yaml +13 -0
  63. package/manifests/postgresql/service.yaml +10 -0
  64. package/manifests/postgresql/statefulset.yaml +37 -0
  65. package/manifests/valkey/kustomization.yaml +7 -0
  66. package/manifests/valkey/service.yaml +17 -0
  67. package/manifests/valkey/statefulset.yaml +41 -0
  68. package/package.json +127 -136
  69. package/src/api/core/core.service.js +1 -1
  70. package/src/api/default/default.service.js +1 -1
  71. package/src/api/user/user.model.js +16 -3
  72. package/src/api/user/user.service.js +15 -12
  73. package/src/cli/cluster.js +389 -0
  74. package/src/cli/cron.js +121 -0
  75. package/src/cli/db.js +222 -0
  76. package/src/cli/deploy.js +487 -0
  77. package/src/cli/env.js +58 -0
  78. package/src/cli/fs.js +161 -0
  79. package/src/cli/image.js +66 -0
  80. package/src/cli/index.js +312 -0
  81. package/src/cli/monitor.js +236 -0
  82. package/src/cli/repository.js +128 -0
  83. package/src/cli/script.js +53 -0
  84. package/src/cli/secrets.js +37 -0
  85. package/src/cli/test.js +118 -0
  86. package/src/client/components/core/Account.js +28 -24
  87. package/src/client/components/core/Auth.js +22 -4
  88. package/src/client/components/core/Blockchain.js +1 -1
  89. package/src/client/components/core/CalendarCore.js +128 -121
  90. package/src/client/components/core/CommonJs.js +283 -19
  91. package/src/client/components/core/CssCore.js +16 -4
  92. package/src/client/components/core/Docs.js +1 -2
  93. package/src/client/components/core/DropDown.js +5 -1
  94. package/src/client/components/core/EventsUI.js +3 -3
  95. package/src/client/components/core/FileExplorer.js +86 -78
  96. package/src/client/components/core/Input.js +22 -6
  97. package/src/client/components/core/JoyStick.js +2 -2
  98. package/src/client/components/core/LoadingAnimation.js +3 -12
  99. package/src/client/components/core/LogIn.js +3 -3
  100. package/src/client/components/core/LogOut.js +1 -1
  101. package/src/client/components/core/Modal.js +54 -20
  102. package/src/client/components/core/Panel.js +109 -90
  103. package/src/client/components/core/PanelForm.js +23 -30
  104. package/src/client/components/core/Recover.js +3 -3
  105. package/src/client/components/core/RichText.js +1 -11
  106. package/src/client/components/core/Router.js +3 -1
  107. package/src/client/components/core/Scroll.js +1 -0
  108. package/src/client/components/core/SignUp.js +2 -2
  109. package/src/client/components/core/Translate.js +47 -9
  110. package/src/client/components/core/Validator.js +9 -1
  111. package/src/client/components/core/VanillaJs.js +0 -9
  112. package/src/client/components/core/Worker.js +34 -31
  113. package/src/client/components/default/RoutesDefault.js +3 -2
  114. package/src/client/services/core/core.service.js +15 -10
  115. package/src/client/services/default/default.management.js +46 -37
  116. package/src/client/ssr/Render.js +6 -1
  117. package/src/client/ssr/body/CacheControl.js +2 -3
  118. package/src/client/sw/default.sw.js +3 -3
  119. package/src/db/mongo/MongooseDB.js +29 -1
  120. package/src/index.js +101 -19
  121. package/src/mailer/MailerProvider.js +3 -0
  122. package/src/runtime/lampp/Dockerfile +65 -0
  123. package/src/runtime/lampp/Lampp.js +1 -13
  124. package/src/runtime/xampp/Xampp.js +0 -13
  125. package/src/server/auth.js +3 -3
  126. package/src/server/backup.js +49 -93
  127. package/src/server/client-build.js +49 -46
  128. package/src/server/client-formatted.js +6 -3
  129. package/src/server/conf.js +297 -55
  130. package/src/server/dns.js +75 -62
  131. package/src/server/downloader.js +0 -8
  132. package/src/server/json-schema.js +77 -0
  133. package/src/server/logger.js +15 -10
  134. package/src/server/network.js +20 -161
  135. package/src/server/peer.js +2 -2
  136. package/src/server/process.js +25 -2
  137. package/src/server/proxy.js +7 -29
  138. package/src/server/runtime.js +53 -40
  139. package/src/server/ssl.js +1 -1
  140. package/src/server/start.js +122 -0
  141. package/src/server/valkey.js +27 -11
  142. package/test/api.test.js +0 -8
  143. package/src/dns.js +0 -22
  144. package/src/server/prompt-optimizer.js +0 -28
  145. package/startup.js +0 -11
@@ -1,4 +1,4 @@
1
- import { getId } from './CommonJs.js';
1
+ import { getId, isValidDate, newInstance } from './CommonJs.js';
2
2
  import { LoadingAnimation } from '../core/LoadingAnimation.js';
3
3
  import { Validator } from '../core/Validator.js';
4
4
  import { Input } from '../core/Input.js';
@@ -26,6 +26,7 @@ const Panel = {
26
26
  idPanel: '',
27
27
  parentIdModal: '',
28
28
  scrollClassContainer: '',
29
+ htmlFormHeader: async () => '',
29
30
  formData: [],
30
31
  data: [],
31
32
  originData: () => [],
@@ -51,12 +52,10 @@ const Panel = {
51
52
  <i style="font-size: 25px" class="fa-solid fa-cloud"></i>
52
53
  </div>`;
53
54
 
54
- let editId;
55
-
56
55
  const openPanelForm = () => {
57
56
  s(`.${idPanel}-form-body`).classList.remove('hide');
58
57
  s(`.btn-${idPanel}-add`).classList.add('hide');
59
- s(`.${scrollClassContainer}`).style.overflow = 'hidden';
58
+ // s(`.${scrollClassContainer}`).style.overflow = 'hidden';
60
59
  if (options.customButtons) {
61
60
  let customBtnIndex = -1;
62
61
  for (const dataBtn of options.customButtons) {
@@ -72,7 +71,7 @@ const Panel = {
72
71
  };
73
72
 
74
73
  const renderPanel = async (payload) => {
75
- const obj = payload;
74
+ const obj = newInstance(payload);
76
75
  if ('_id' in obj) obj.id = obj._id;
77
76
  const { id } = obj;
78
77
 
@@ -90,16 +89,20 @@ const Panel = {
90
89
  htmls(`.${idPanel}-cell-col-a-${id}`, render);
91
90
  },
92
91
  });
93
- EventsUI.onClick(`.${idPanel}-btn-delete-${id}`, async (e) => {
94
- logger.warn('delete', obj);
95
- const { status } = await options.on.remove({ e, data: obj });
96
- if (status === 'error') return;
97
- if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
98
- });
92
+ EventsUI.onClick(
93
+ `.${idPanel}-btn-delete-${id}`,
94
+ async (e) => {
95
+ logger.warn('delete', obj);
96
+ const { status } = await options.on.remove({ e, data: obj });
97
+ if (status === 'error') return;
98
+ if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
99
+ },
100
+ { context: 'modal' },
101
+ );
99
102
  EventsUI.onClick(`.${idPanel}-btn-edit-${id}`, async () => {
100
103
  logger.warn('edit', obj);
101
- if (obj._id) editId = obj._id;
102
- else if (obj.id) editId = obj.id;
104
+ if (obj._id) Panel.Tokens[idPanel].editId = obj._id;
105
+ else if (obj.id) Panel.Tokens[idPanel].editId = obj.id;
103
106
 
104
107
  s(`.btn-${idPanel}-label-edit`).classList.remove('hide');
105
108
  s(`.btn-${idPanel}-label-add`).classList.add('hide');
@@ -122,7 +125,7 @@ const Panel = {
122
125
  if (options.onClick) await options.onClick({ payload });
123
126
  };
124
127
  });
125
-
128
+ if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
126
129
  return html` <div class="in box-shadow ${idPanel} ${idPanel}-${id}">
127
130
  <div class="fl ${idPanel}-tools session-fl-log-in ${obj.tools ? '' : 'hide'}">
128
131
  ${await BtnIcon.Render({
@@ -171,6 +174,10 @@ const Panel = {
171
174
  const valueIcon = formObjData?.panel?.icon?.value ? formObjData.panel.icon.value : '';
172
175
  const keyIcon = formObjData?.panel?.icon?.key ? formObjData.panel.icon.key : '';
173
176
 
177
+ if (formObjData && ['datetime-local'].includes(formObjData.inputType) && isValidDate(obj[infoKey])) {
178
+ obj[infoKey] = `${obj[infoKey]}`.replace('T', ' ').replace('.000Z', '');
179
+ }
180
+
174
181
  if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'tags')) {
175
182
  setTimeout(async () => {
176
183
  let tagRender = html``;
@@ -186,22 +193,50 @@ const Panel = {
186
193
  });
187
194
  return html``;
188
195
  }
196
+ {
197
+ const formDataObj = formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'list');
198
+ if (obj[infoKey] && obj[infoKey].length > 0 && formDataObj)
199
+ return html`<div class="in ${idPanel}-row">
200
+ <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
201
+ ${keyIcon} ${Translate.Render(infoKey)}:</span
202
+ >
203
+ <span class="${idPanel}-row-value"
204
+ >${valueIcon} ${obj[infoKey].map((k) => Translate.Render(k)).join(', ')}</span
205
+ >
206
+ </div> `;
207
+ }
189
208
 
190
- if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'info-row-pin'))
191
- return html`<div class="in ${idPanel}-row">
192
- <span class="${idPanel}-row-pin-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
193
- ${keyIcon} ${infoKey}:</span
194
- >
195
- <span class="${idPanel}-row-pin-value">${valueIcon} ${obj[infoKey]}</span>
196
- </div> `;
209
+ {
210
+ const formDataObj = formData.find(
211
+ (f) => f.model === infoKey && f.panel && f.panel.type === 'info-row-pin',
212
+ );
213
+ if (obj[infoKey] && formDataObj)
214
+ return html`<div class="in ${idPanel}-row">
215
+ <span class="${idPanel}-row-pin-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
216
+ ${keyIcon}
217
+ ${formDataObj.translateCode
218
+ ? Translate.Render(formDataObj.translateCode)
219
+ : Translate.Render(infoKey)}:</span
220
+ >
221
+ <span class="${idPanel}-row-pin-value">${valueIcon} ${obj[infoKey]}</span>
222
+ </div> `;
223
+ }
197
224
 
198
- if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'info-row'))
199
- return html`<div class="in ${idPanel}-row">
200
- <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
201
- ${keyIcon} ${infoKey}:</span
202
- >
203
- <span class="${idPanel}-row-value"> ${valueIcon} ${obj[infoKey]}</span>
204
- </div> `;
225
+ {
226
+ const formDataObj = formData.find(
227
+ (f) => f.model === infoKey && f.panel && f.panel.type === 'info-row',
228
+ );
229
+ if (obj[infoKey] && formDataObj)
230
+ return html`<div class="in ${idPanel}-row">
231
+ <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
232
+ ${keyIcon}
233
+ ${formDataObj.translateCode
234
+ ? Translate.Render(formDataObj.translateCode)
235
+ : Translate.Render(infoKey)}:</span
236
+ >
237
+ <span class="${idPanel}-row-value"> ${valueIcon} ${obj[infoKey]}</span>
238
+ </div> `;
239
+ }
205
240
 
206
241
  return html``;
207
242
  })
@@ -213,17 +248,42 @@ const Panel = {
213
248
  };
214
249
 
215
250
  let render = '';
216
- let renderForm = html` <div class="in modal stq" style="top: 0px; z-index: 1; padding-bottom: 5px">
217
- ${await BtnIcon.Render({
218
- class: `section-mp btn-custom btn-${idPanel}-close`,
219
- label: html`<i class="fa-solid fa-xmark"></i> ${Translate.Render('close')}`,
220
- type: 'button',
221
- })}
222
- </div>`;
251
+ let renderForm = html` <div class="in modal" style="top: 0px; z-index: 1; padding-bottom: 5px">
252
+ ${await BtnIcon.Render({
253
+ class: `inl section-mp btn-custom btn-${idPanel}-close`,
254
+ label: html`<i class="fa-solid fa-xmark"></i> ${Translate.Render('close')}`,
255
+ type: 'button',
256
+ })}
257
+ </div>
258
+ ${options?.htmlFormHeader ? await options.htmlFormHeader() : ''}`;
223
259
 
224
260
  for (const modelData of formData) {
225
261
  if (modelData.disableRender) continue;
226
262
  switch (modelData.inputType) {
263
+ case 'dropdown-checkbox': {
264
+ renderForm += html`<div class="in section-mp">
265
+ ${await DropDown.Render({
266
+ id: `${modelData.id}`,
267
+ label: html`${Translate.Render(modelData.model)}`,
268
+ type: 'checkbox',
269
+ value: modelData.dropdown.options[0],
270
+ resetOption: true,
271
+ containerClass: `${idPanel}-dropdown-checkbox`,
272
+ data: modelData.dropdown.options.map((dKey) => {
273
+ return {
274
+ value: dKey,
275
+ data: dKey,
276
+ checked: false,
277
+ display: html`${Translate.Render(dKey)}`,
278
+ onClick: function () {
279
+ logger.info('DropDown onClick', this.checked);
280
+ },
281
+ };
282
+ }),
283
+ })}
284
+ </div>`;
285
+ break;
286
+ }
227
287
  case 'dropdown':
228
288
  renderForm += html` <div class="in section-mp">
229
289
  ${await DropDown.Render({
@@ -348,62 +408,19 @@ const Panel = {
348
408
  }
349
409
  let renderFormBtn = html`
350
410
  ${await BtnIcon.Render({
351
- class: `section-mp btn-custom btn-${idPanel}-submit`,
411
+ class: `inl section-mp btn-custom btn-${idPanel}-submit`,
352
412
  label: html`<span class="btn-${idPanel}-label-add"><i class="fas fa-plus"></i> ${Translate.Render('add')}</span
353
413
  ><span class="btn-${idPanel}-label-edit hide"><i class="fas fa-edit"></i> ${Translate.Render('edit')}</span>`,
354
414
  type: 'submit',
355
415
  })}
356
416
  ${await BtnIcon.Render({
357
- class: `section-mp btn-custom btn-${idPanel}-clean`,
417
+ class: `inl section-mp btn-custom btn-${idPanel}-clean`,
358
418
  label: html`<i class="fa-solid fa-broom"></i> ${Translate.Render('clear')}`,
359
419
  type: 'button',
360
420
  })}
361
421
  `;
362
422
 
363
423
  setTimeout(async () => {
364
- const resizeParentModal = () => {
365
- if (options.parentIdModal) {
366
- Modal.Data[options.parentIdModal].onObserverListener[`form-panel-${options.parentIdModal}`] = () => {
367
- if (s(`.${idPanel}-form-container`))
368
- s(`.${idPanel}-form-container`).style.maxHeight = `${
369
- s(`.${options.parentIdModal}`).offsetHeight - Modal.headerTitleHeight
370
- }px`;
371
- };
372
- Modal.Data[options.parentIdModal].onObserverListener[`form-panel-${options.parentIdModal}`]();
373
- } else {
374
- Responsive.Event[`${idPanel}-responsive`] = () => {
375
- if (s(`.${idPanel}-form-container`))
376
- s(`.${idPanel}-form-container`).style.maxHeight =
377
- options.route === 'home' &&
378
- s(`.${idPanel}-form-body`) &&
379
- !s(`.${idPanel}-form-body`).classList.contains('hide') &&
380
- !s(`.main-body-btn-ui-open`).classList.contains('hide')
381
- ? `${window.innerHeight}px`
382
- : `${window.innerHeight - heightTopBar - heightBottomBar}px`;
383
- };
384
- Responsive.Event[`${idPanel}-responsive`]();
385
- }
386
- };
387
- if (options.route === 'home') {
388
- Modal.Data['modal-menu'].onBarUiClose[`${idPanel}-responsive`] = () => {
389
- resizeParentModal();
390
- };
391
-
392
- Modal.Data['modal-menu'].onBarUiOpen[`${idPanel}-responsive`] = () => {
393
- resizeParentModal();
394
- };
395
- }
396
- setTimeout(resizeParentModal);
397
- if (options.route) {
398
- RouterEvents[options.parentIdModal] = ({ route }) => {
399
- if (route === options.route) {
400
- setTimeout(() => {
401
- resizeParentModal();
402
- }, 350);
403
- }
404
- };
405
- }
406
-
407
424
  const validators = await Validator.instance(formData);
408
425
 
409
426
  s(`.${idPanel}-form`).onsubmit = (e) => {
@@ -418,21 +435,23 @@ const Panel = {
418
435
  obj.id = `${data.length}`;
419
436
  let documents;
420
437
  if (options && options.on && options.on.add) {
421
- const { status, data } = await options.on.add({ data: obj, editId });
438
+ const { status, data } = await options.on.add({ data: obj, editId: Panel.Tokens[idPanel].editId });
422
439
  if (status === 'error') return;
423
440
  documents = data;
424
441
  }
425
442
  s(`.btn-${idPanel}-clean`).click();
426
- if (editId && s(`.${idPanel}-${editId}`)) s(`.${idPanel}-${editId}`).remove();
443
+ if (Panel.Tokens[idPanel].editId && s(`.${idPanel}-${Panel.Tokens[idPanel].editId}`))
444
+ s(`.${idPanel}-${Panel.Tokens[idPanel].editId}`).remove();
427
445
  if (Array.isArray(documents)) {
428
446
  htmls(`.${idPanel}-render`, '');
429
447
  for (const doc of documents) {
430
448
  append(`.${idPanel}-render`, await renderPanel(doc));
431
449
  }
432
- } else htmls(`.${idPanel}-render`, await renderPanel(obj));
450
+ } else htmls(`.${idPanel}-render`, await renderPanel({ ...obj, ...documents }));
433
451
  Input.cleanValues(formData);
434
452
  s(`.btn-${idPanel}-close`).click();
435
453
  s(`.${scrollClassContainer}`).scrollTop = 0;
454
+ if (s(`.${scrollClassContainer}`)) s(`.${scrollClassContainer}`).style.overflow = 'auto';
436
455
  });
437
456
  s(`.btn-${idPanel}-clean`).onclick = () => {
438
457
  Input.cleanValues(formData);
@@ -458,13 +477,14 @@ const Panel = {
458
477
  s(`.btn-${idPanel}-add`).onclick = (e) => {
459
478
  e.preventDefault();
460
479
  // s(`.btn-${idPanel}-clean`).click();
461
- editId = undefined;
480
+ Panel.Tokens[idPanel].editId = undefined;
462
481
  s(`.btn-${idPanel}-label-add`).classList.remove('hide');
463
482
  s(`.btn-${idPanel}-label-edit`).classList.add('hide');
464
483
  s(`.${scrollClassContainer}`).scrollTop = 0;
465
484
 
466
485
  openPanelForm();
467
486
  };
487
+ if (s(`.${scrollClassContainer}`)) s(`.${scrollClassContainer}`).style.overflow = 'auto';
468
488
  });
469
489
 
470
490
  if (data.length > 0) for (const obj of data) render += await renderPanel(obj);
@@ -487,7 +507,7 @@ const Panel = {
487
507
  s(`.${btnSelector}`).onclick = () => dataBtn.onClick();
488
508
  });
489
509
  customButtonsRender += ` ${await BtnIcon.Render({
490
- class: `section-mp btn-custom ${btnSelector}`,
510
+ class: `inl section-mp btn-custom ${btnSelector}`,
491
511
  label: dataBtn.label,
492
512
  type: 'button',
493
513
  })}`;
@@ -522,7 +542,6 @@ const Panel = {
522
542
  padding: 10px;
523
543
  cursor: pointer;
524
544
  min-height: 400px;
525
- overflow: hidden;
526
545
  }
527
546
  .${idPanel}:hover {
528
547
  background: #ffffff;
@@ -592,12 +611,12 @@ const Panel = {
592
611
  }
593
612
  </style>
594
613
  <div class="${idPanel}-container">
595
- <div
596
- class="stq modal ${idPanel}-form-container ${options.formContainerClass ? options.formContainerClass : ''}"
597
- >
614
+ <div class="in modal ${idPanel}-form-container ${options.formContainerClass ? options.formContainerClass : ''}">
598
615
  <div class="in ${idPanel}-form-header">
599
616
  ${await BtnIcon.Render({
600
- class: `section-mp btn-custom btn-${idPanel}-add`,
617
+ class: `inl section-mp btn-custom btn-${idPanel}-add ${
618
+ options?.role?.add ? (!options.role.add() ? 'hide' : '') : ''
619
+ }`,
601
620
  label: html`<i class="fas fa-plus"></i> ${Translate.Render('add')}`,
602
621
  type: 'button',
603
622
  })}
@@ -1,4 +1,4 @@
1
- import { getCapVariableName, getId, newInstance, random, range, timer, uniqueArray } from './CommonJs.js';
1
+ import { getCapVariableName, newInstance, random, range, uniqueArray } from './CommonJs.js';
2
2
  import { marked } from 'marked';
3
3
  import {
4
4
  getBlobFromUint8ArrayFile,
@@ -12,7 +12,6 @@ import { NotificationManager } from './NotificationManager.js';
12
12
  import { DocumentService } from '../../services/document/document.service.js';
13
13
  import { FileService } from '../../services/file/file.service.js';
14
14
  import { getSrcFromFileData } from './Input.js';
15
- import { Auth } from './Auth.js';
16
15
  import { imageShimmer, renderCssAttr } from './Css.js';
17
16
  import { Translate } from './Translate.js';
18
17
  import { Modal } from './Modal.js';
@@ -29,6 +28,8 @@ const PanelForm = {
29
28
  Elements: {},
30
29
  parentIdModal: undefined,
31
30
  route: 'home',
31
+ htmlFormHeader: async () => '',
32
+ firsUpdateEvent: async () => {},
32
33
  },
33
34
  ) {
34
35
  const { idPanel, heightTopBar, heightBottomBar, defaultUrlImage, Elements } = options;
@@ -90,16 +91,7 @@ const PanelForm = {
90
91
  },
91
92
  },
92
93
  ];
93
- const dateFormat = (date) =>
94
- html`<span
95
- style="${renderCssAttr({
96
- style: {
97
- 'font-size': '14px',
98
- color: '#888',
99
- },
100
- })}"
101
- >${new Date(date).toLocaleString().replaceAll(',', '')}</span
102
- >`;
94
+
103
95
  const titleIcon = html`<i class="fa-solid fa-quote-left"></i>`;
104
96
  const panelRender = async ({ data }) =>
105
97
  await Panel.Render({
@@ -108,6 +100,7 @@ const PanelForm = {
108
100
  heightTopBar,
109
101
  heightBottomBar,
110
102
  data,
103
+ htmlFormHeader: options.htmlFormHeader,
111
104
  parentIdModal: options.parentIdModal,
112
105
  originData: () => PanelForm.Data[idPanel].originData,
113
106
  filesData: () => PanelForm.Data[idPanel].filesData,
@@ -271,7 +264,7 @@ const PanelForm = {
271
264
  fileId: file ? URL.createObjectURL(file) : undefined,
272
265
  _id: documentData._id,
273
266
  id: documentData._id,
274
- createdAt: dateFormat(documentData.createdAt),
267
+ createdAt: documentData.createdAt,
275
268
  };
276
269
 
277
270
  if (documentStatus === 'error') status = 'error';
@@ -376,7 +369,7 @@ const PanelForm = {
376
369
  PanelForm.Data[idPanel].data.push({
377
370
  id: documentObject._id,
378
371
  title: documentObject.title,
379
- createdAt: dateFormat(documentObject.createdAt),
372
+ createdAt: documentObject.createdAt,
380
373
  tags: documentObject.tags.filter((t) => !prefixTags.includes(t)),
381
374
  mdFileId: marked.parse(mdFileId),
382
375
  userId: documentObject.userId._id,
@@ -389,7 +382,7 @@ const PanelForm = {
389
382
  };
390
383
  const renderSrrPanelData = async () =>
391
384
  await panelRender({
392
- data: range(0, 5).map((i) => ({
385
+ data: range(0, 0).map((i) => ({
393
386
  id: i,
394
387
  title: html`<div class="fl">
395
388
  <div
@@ -430,23 +423,25 @@ const PanelForm = {
430
423
  ssr: true,
431
424
  })),
432
425
  });
433
-
426
+ let firsUpdateEvent = false;
434
427
  let lastCid;
435
- let lasUserId;
436
428
  this.Data[idPanel].updatePanel = async () => {
437
429
  const cid = getQueryParams().cid ? getQueryParams().cid : '';
438
- if (lastCid === cid && lasUserId === Elements.Data.user.main.model.user._id) return;
439
- if (options.route === 'home') Modal.homeCid = newInstance(cid);
430
+ if (lastCid === cid) return;
440
431
  lastCid = cid;
441
- lasUserId = newInstance(Elements.Data.user.main.model.user._id);
432
+ if (options.route === 'home') Modal.homeCid = newInstance(cid);
442
433
  htmls(`.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`, await renderSrrPanelData());
443
434
  await getPanelData();
444
435
  htmls(
445
436
  `.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`,
446
437
  await panelRender({ data: this.Data[idPanel].data }),
447
438
  );
439
+ if (!firsUpdateEvent && options.firsUpdateEvent) {
440
+ firsUpdateEvent = true;
441
+ await options.firsUpdateEvent();
442
+ }
448
443
  };
449
- if (options.route)
444
+ if (options.route) {
450
445
  listenQueryPathInstance({
451
446
  id: options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body',
452
447
  routeId: options.route,
@@ -454,15 +449,13 @@ const PanelForm = {
454
449
  await this.Data[idPanel].updatePanel();
455
450
  },
456
451
  });
457
-
458
- // if (options.route === 'home') setTimeout(this.Data[idPanel].updatePanel);
459
- setTimeout(() => {
460
- if (
461
- options.route !== 'home' &&
462
- (!PanelForm.Data[idPanel].originData || PanelForm.Data[idPanel].originData.length === 0)
463
- )
464
- this.Data[idPanel].updatePanel();
465
- });
452
+ if (!options.parentIdModal)
453
+ Modal.Data['modal-menu'].onHome[idPanel] = async () => {
454
+ lastCid = undefined;
455
+ setQueryPath({ path: options.route, queryPath: '' });
456
+ await this.Data[idPanel].updatePanel();
457
+ };
458
+ }
466
459
 
467
460
  if (options.parentIdModal) {
468
461
  htmls(`.html-${options.parentIdModal}`, await renderSrrPanelData());
@@ -126,7 +126,7 @@ const Recover = {
126
126
  });
127
127
  return html`
128
128
  ${await BtnIcon.Render({
129
- class: 'section-mp form-button btn-recover-log-in hide',
129
+ class: 'in section-mp form-button btn-recover-log-in hide',
130
130
  label: Translate.Render('log-in'),
131
131
  type: 'button',
132
132
  })}
@@ -181,7 +181,7 @@ const Recover = {
181
181
  ${options?.bottomRender ? await options.bottomRender() : ``}
182
182
  <div class="in recover-send-btn-container">
183
183
  ${await BtnIcon.Render({
184
- class: 'section-mp form-button btn-recover',
184
+ class: 'in section-mp form-button btn-recover',
185
185
  label: Translate.Render(mode === 'recover-verify-email' ? 'send-recover-verify-email' : 'change-password'),
186
186
  type: 'button',
187
187
  })}
@@ -191,7 +191,7 @@ const Recover = {
191
191
  <i class="fa-solid fa-triangle-exclamation"></i> ${Translate.Render('15-min-valid-recover-email')}
192
192
  </div>
193
193
  ${await BtnIcon.Render({
194
- class: 'section-mp form-button btn-recover-resend',
194
+ class: 'in section-mp form-button btn-recover-resend',
195
195
  label: html`${Translate.Render('resend')} ${Translate.Render('recover-verify-email')}`,
196
196
  type: 'submit',
197
197
  })}
@@ -7,28 +7,18 @@ const RichText = {
7
7
  Render: async function (options = { id: '', parentIdModal: '' }) {
8
8
  const id = options?.id ? options.id : getId(this.Tokens, 'rich-text-');
9
9
  this.Tokens[id] = {};
10
- let top, height;
11
10
  setTimeout(() => {
12
11
  const easyMDE = new EasyMDE({
13
12
  element: s(`.${id}`),
13
+ hideIcons: ['fullscreen', 'side-by-side'],
14
14
  onToggleFullScreen: (onFs) => {
15
15
  if (onFs) {
16
16
  if (options.parentIdModal) {
17
- s(`.btn-bar-modal-container-${options.parentIdModal}`).classList.add('hide');
18
- top = newInstance(s(`.${options.parentIdModal}`).style.top);
19
- height = newInstance(s(`.${options.parentIdModal}`).style.height);
20
- s(`.${options.parentIdModal}`).style.top = '0px';
21
- s(`.${options.parentIdModal}`).style.height = `${window.innerHeight}px`;
22
17
  }
23
18
  // Modal.cleanUI();
24
- if (s(`.slide-menu-top-bar`)) s(`.slide-menu-top-bar`).classList.add('hide');
25
19
  } else {
26
20
  if (options.parentIdModal) {
27
- s(`.btn-bar-modal-container-${options.parentIdModal}`).classList.remove('hide');
28
- s(`.${options.parentIdModal}`).style.top = top;
29
- s(`.${options.parentIdModal}`).style.height = height;
30
21
  }
31
- if (s(`.slide-menu-top-bar`)) s(`.slide-menu-top-bar`).classList.add('remove');
32
22
  // Modal.restoreUI();
33
23
  }
34
24
  },
@@ -52,7 +52,9 @@ const LoadRouter = function (RouterInstance) {
52
52
 
53
53
  const setQueryPath = (options = { path: '', queryPath: '' }, queryKey = 'cid') => {
54
54
  const { queryPath, path } = options;
55
- const newUri = `${getProxyPath()}${path === 'home' ? '' : `${path}/`}${queryPath ? `?${queryKey}=${queryPath}` : ''}`;
55
+ const newUri = `${getProxyPath()}${path === 'home' ? '' : `${path}/`}${
56
+ typeof queryPath === 'string' ? `?${queryKey}=${queryPath}` : ''
57
+ }`;
56
58
  const currentUri = `${window.location.pathname}${location.search}`;
57
59
  if (currentUri !== newUri && currentUri !== `${newUri}/`) setPath(newUri);
58
60
  };
@@ -39,6 +39,7 @@ const Scroll = {
39
39
  delete this.topRefreshEvents[id];
40
40
  },
41
41
  pullTopRefresh: function () {
42
+ return;
42
43
  append(
43
44
  'body',
44
45
  html` <style>
@@ -63,7 +63,7 @@ const SignUp = {
63
63
  });
64
64
  return html`
65
65
  ${await BtnIcon.Render({
66
- class: 'section-mp form-button btn-sign-up-i-have-account',
66
+ class: 'in section-mp form-button btn-sign-up-i-have-account',
67
67
  label: html`<i class="fas fa-sign-in-alt"></i> ${Translate.Render('i-have-account')}<br />${Translate.Render(
68
68
  'log-in',
69
69
  )}`,
@@ -112,7 +112,7 @@ const SignUp = {
112
112
  ${options?.bottomRender ? await options.bottomRender() : ``}
113
113
  <div class="in">
114
114
  ${await BtnIcon.Render({
115
- class: 'section-mp form-button btn-sign-up',
115
+ class: 'in section-mp form-button btn-sign-up',
116
116
  label: Translate.Render('sign-up'),
117
117
  type: 'submit',
118
118
  })}
@@ -11,35 +11,49 @@ const Translate = {
11
11
  Data: {},
12
12
  Token: {},
13
13
  Event: {},
14
+ Options: {},
14
15
  Parse: function (lang) {
15
16
  s('html').lang = lang;
16
17
  Object.keys(this.Token).map((translateHash) => {
17
18
  if (translateHash in this.Token && lang in this.Token[translateHash]) {
18
- if (!('placeholder' in this.Token[translateHash]) && s(`.${translateHash}`))
19
- htmls(`.${translateHash}`, textFormatted(this.Token[translateHash][lang]));
19
+ if (!('placeholder' in this.Options[translateHash]) && s(`.${translateHash}`))
20
+ htmls(
21
+ `.${translateHash}`,
22
+ this.Options[translateHash]?.disableTextFormat
23
+ ? this.Token[translateHash][lang]
24
+ : textFormatted(this.Token[translateHash][lang]),
25
+ );
20
26
  else if ('placeholder' in this.Token[translateHash] && s(this.Token[translateHash].placeholder))
21
- s(this.Token[translateHash].placeholder).placeholder = textFormatted(this.Token[translateHash][lang]);
27
+ s(this.Token[translateHash].placeholder).placeholder = this.Options[translateHash]?.disableTextFormat
28
+ ? this.Token[translateHash][lang]
29
+ : textFormatted(this.Token[translateHash][lang]);
22
30
  }
23
31
  });
24
32
  for (const keyEvent of Object.keys(this.Event)) this.Event[keyEvent]();
25
33
  },
26
- Render: function (keyLang, placeholder) {
34
+ Render: function (keyLang, placeholder, options = { disableTextFormat: false }) {
27
35
  if (!(keyLang in this.Data)) {
28
36
  // TODO: add translate package or library for this case
29
37
  logger.warn('translate key lang does not exist: ', keyLang);
30
- return textFormatted(keyLang);
38
+ return options.disableTextFormat ? keyLang : textFormatted(keyLang);
31
39
  }
32
40
  if (placeholder) this.Data[keyLang].placeholder = placeholder;
33
41
  keyLang = this.Data[keyLang];
34
42
  const translateHash = getId(this.Token, 'trans');
43
+ this.Options[translateHash] = options;
35
44
  this.Token[translateHash] = newInstance(keyLang);
36
45
  if ('placeholder' in keyLang) {
37
- if (s('html').lang in keyLang) return textFormatted(keyLang[s('html').lang]);
38
- return textFormatted(keyLang['en']);
46
+ if (s('html').lang in keyLang)
47
+ return options.disableTextFormat ? keyLang[s('html').lang] : textFormatted(keyLang[s('html').lang]);
48
+ return options.disableTextFormat ? keyLang['en'] : textFormatted(keyLang['en']);
39
49
  }
40
50
  if (s('html').lang in keyLang)
41
- return html`<span class="${translateHash}">${textFormatted(keyLang[s('html').lang])}</span>`;
42
- return html`<span class="${translateHash}">${textFormatted(keyLang['en'])}</span>`;
51
+ return html`<span class="${translateHash}"
52
+ >${options.disableTextFormat ? keyLang[s('html').lang] : textFormatted(keyLang[s('html').lang])}</span
53
+ >`;
54
+ return html`<span class="${translateHash}"
55
+ >${options.disableTextFormat ? keyLang['en'] : textFormatted(keyLang['en'])}</span
56
+ >`;
43
57
  },
44
58
  renderLang: function (language) {
45
59
  localStorage.setItem('lang', language);
@@ -474,6 +488,30 @@ const TranslateCore = {
474
488
  Translate.Data['friday'] = { es: 'Viernes', en: 'Friday' };
475
489
  Translate.Data['saturday'] = { es: 'Sábado', en: 'Saturday' };
476
490
  Translate.Data['sunday'] = { es: 'Domingo', en: 'Sunday' };
491
+
492
+ Translate.Data['description'] = { es: 'Descripción', en: 'Description' };
493
+ Translate.Data['daysOfWeek'] = { es: 'Días de la semana', en: 'Days of the week' };
494
+ Translate.Data['startTime'] = { es: 'Hora de inicio', en: 'Start time' };
495
+ Translate.Data['endTime'] = { es: 'Hora de finalizacion', en: 'End time' };
496
+ Translate.Data['appointment-scheduled'] = {
497
+ en: 'Your appointment has been scheduled',
498
+ es: 'Tu cita ha sido programada',
499
+ };
500
+ Translate.Data['info'] = { es: 'Información', en: 'Info' };
501
+ Translate.Data['complete-name'] = { es: 'Nombre completo', en: 'Complete name' };
502
+ Translate.Data['identityDocument'] = { es: 'Rut', en: 'Identity document' };
503
+ Translate.Data['day'] = { es: 'Día', en: 'Day' };
504
+ Translate.Data['month'] = { es: 'Mes', en: 'Month' };
505
+ Translate.Data['year'] = { es: 'Año', en: 'Year' };
506
+ Translate.Data['phone'] = { es: 'Teléfono', en: 'Phone' };
507
+ Translate.Data['invalid-identity-document'] = {
508
+ en: 'Invalid identity document',
509
+ es: 'Documento de identidad inválido',
510
+ };
511
+ Translate.Data['expired-session'] = {
512
+ en: 'Your session has expired. Please log in again.',
513
+ es: 'Su sesión ha expirado. Por favor, inicie sesión de nuevo.',
514
+ };
477
515
  },
478
516
  };
479
517