@underpostnet/underpost 2.8.0 → 2.8.4

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 (91) hide show
  1. package/.dockerignore +1 -0
  2. package/.github/workflows/ghpkg.yml +14 -11
  3. package/.github/workflows/pwa-microservices-template.page.yml +10 -3
  4. package/.vscode/extensions.json +17 -71
  5. package/.vscode/settings.json +12 -5
  6. package/AUTHORS.md +16 -5
  7. package/CHANGELOG.md +63 -3
  8. package/Dockerfile +41 -62
  9. package/README.md +1 -28
  10. package/bin/build.js +278 -0
  11. package/bin/db.js +2 -24
  12. package/bin/deploy.js +107 -71
  13. package/bin/file.js +33 -4
  14. package/bin/index.js +35 -54
  15. package/bin/ssl.js +19 -11
  16. package/bin/util.js +27 -89
  17. package/bin/vs.js +25 -2
  18. package/conf.js +32 -132
  19. package/docker-compose.yml +1 -1
  20. package/manifests/core/kustomization.yaml +11 -0
  21. package/manifests/core/underpost-engine-backup-access.yaml +16 -0
  22. package/manifests/core/underpost-engine-backup-pv-pvc.yaml +22 -0
  23. package/manifests/core/underpost-engine-headless-service.yaml +10 -0
  24. package/manifests/core/underpost-engine-mongodb-backup-cronjob.yaml +40 -0
  25. package/manifests/core/underpost-engine-mongodb-configmap.yaml +26 -0
  26. package/manifests/core/underpost-engine-pv-pvc.yaml +23 -0
  27. package/manifests/core/underpost-engine-statefulset.yaml +91 -0
  28. package/manifests/deployment/mongo-express.yaml +60 -0
  29. package/manifests/deployment/phpmyadmin.yaml +54 -0
  30. package/manifests/kind-config.yaml +12 -0
  31. package/manifests/letsencrypt-prod.yaml +15 -0
  32. package/manifests/mariadb/config.yaml +10 -0
  33. package/manifests/mariadb/kustomization.yaml +9 -0
  34. package/manifests/mariadb/pv.yaml +12 -0
  35. package/manifests/mariadb/pvc.yaml +10 -0
  36. package/manifests/mariadb/secret.yaml +8 -0
  37. package/manifests/mariadb/service.yaml +10 -0
  38. package/manifests/mariadb/statefulset.yaml +55 -0
  39. package/manifests/valkey/kustomization.yaml +7 -0
  40. package/manifests/valkey/underpost-engine-valkey-service.yaml +17 -0
  41. package/manifests/valkey/underpost-engine-valkey-statefulset.yaml +39 -0
  42. package/package.json +16 -35
  43. package/src/api/user/user.model.js +16 -3
  44. package/src/api/user/user.service.js +1 -1
  45. package/src/client/components/core/Account.js +4 -2
  46. package/src/client/components/core/Auth.js +2 -2
  47. package/src/client/components/core/CalendarCore.js +115 -49
  48. package/src/client/components/core/CommonJs.js +150 -19
  49. package/src/client/components/core/Css.js +1 -1
  50. package/src/client/components/core/CssCore.js +6 -0
  51. package/src/client/components/core/Docs.js +2 -1
  52. package/src/client/components/core/DropDown.js +5 -1
  53. package/src/client/components/core/Input.js +17 -3
  54. package/src/client/components/core/JoyStick.js +8 -5
  55. package/src/client/components/core/Modal.js +17 -11
  56. package/src/client/components/core/Panel.js +85 -25
  57. package/src/client/components/core/PanelForm.js +11 -19
  58. package/src/client/components/core/SignUp.js +4 -1
  59. package/src/client/components/core/Translate.js +57 -9
  60. package/src/client/components/core/Validator.js +9 -1
  61. package/src/client/public/default/plantuml/client-conf.svg +1 -1
  62. package/src/client/public/default/plantuml/server-conf.svg +1 -1
  63. package/src/client/public/default/plantuml/server-schema.svg +1 -1
  64. package/src/client/public/default/plantuml/ssr-conf.svg +1 -1
  65. package/src/client/public/default/plantuml/ssr-schema.svg +1 -1
  66. package/src/client/services/core/core.service.js +2 -0
  67. package/src/client/services/default/default.management.js +4 -2
  68. package/src/client/ssr/body/CacheControl.js +2 -1
  69. package/src/client/ssr/body/DefaultSplashScreen.js +3 -3
  70. package/src/client/ssr/offline/Maintenance.js +63 -0
  71. package/src/client/sw/default.sw.js +23 -3
  72. package/src/db/mongo/MongooseDB.js +13 -1
  73. package/src/index.js +15 -0
  74. package/src/runtime/lampp/Lampp.js +1 -13
  75. package/src/runtime/xampp/Xampp.js +0 -13
  76. package/src/server/auth.js +3 -3
  77. package/src/server/client-build.js +8 -17
  78. package/src/server/client-icons.js +1 -1
  79. package/src/server/conf.js +299 -32
  80. package/src/server/dns.js +2 -3
  81. package/src/server/logger.js +18 -11
  82. package/src/server/network.js +0 -36
  83. package/src/server/process.js +25 -2
  84. package/src/server/project.js +39 -0
  85. package/src/server/proxy.js +4 -26
  86. package/src/server/runtime.js +6 -7
  87. package/src/server/ssl.js +1 -1
  88. package/src/server/valkey.js +3 -0
  89. package/startup.cjs +12 -0
  90. package/src/server/prompt-optimizer.js +0 -28
  91. package/startup.js +0 -11
@@ -1,6 +1,8 @@
1
1
  import { AgGrid } from './AgGrid.js';
2
2
  import { BtnIcon } from './BtnIcon.js';
3
+ import { isValidDate } from './CommonJs.js';
3
4
  import { darkTheme } from './Css.js';
5
+ import { DropDown } from './DropDown.js';
4
6
  import { loggerFactory } from './Logger.js';
5
7
  import { RichText } from './RichText.js';
6
8
  import { ToggleSwitch } from './ToggleSwitch.js';
@@ -147,6 +149,10 @@ const Input = {
147
149
  htmls(`.file-name-render-${inputData.id}`, `${s(`.${inputData.id}`).fileNameInputExtDefaultContent}`);
148
150
  continue;
149
151
  break;
152
+ case 'dropdown-checkbox': {
153
+ s(`.dropdown-option-${inputData.id}-reset`).click();
154
+ break;
155
+ }
150
156
  case 'md':
151
157
  RichText.Tokens[inputData.id].easyMDE.value('');
152
158
  continue;
@@ -196,6 +202,12 @@ const Input = {
196
202
  RichText.Tokens[inputData.id].easyMDE.value(fileObj[inputData.model].mdPlain);
197
203
  continue;
198
204
  break;
205
+
206
+ case 'dropdown-checkbox': {
207
+ s(`.dropdown-option-${inputData.id}-reset`).click();
208
+ for (const opt of originObj[inputData.model]) s(`.dropdown-option-${inputData.id}-${opt}`).click();
209
+ break;
210
+ }
199
211
  case 'checkbox':
200
212
  case 'checkbox-on-off':
201
213
  if (
@@ -207,9 +219,11 @@ const Input = {
207
219
  break;
208
220
  case 'datetime-local':
209
221
  {
210
- const date = new Date(originObj[inputData.model]);
211
- date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
212
- s(`.${inputData.id}`).value = date.toISOString().slice(0, 16);
222
+ if (isValidDate(originObj[inputData.model])) {
223
+ const date = new Date(originObj[inputData.model]);
224
+ // date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
225
+ s(`.${inputData.id}`).value = date.toISOString().slice(0, 16);
226
+ } else s(`.${inputData.id}`).value = null;
213
227
  }
214
228
  continue;
215
229
  break;
@@ -24,13 +24,16 @@ const JoyStick = {
24
24
  z-index: 3;
25
25
  }
26
26
  .joy-img-background-${id} {
27
- width: 93%;
28
- height: 93%;
27
+ width: 50%;
28
+ height: 50%;
29
29
  opacity: 0.8;
30
+ transition: 0.1;
30
31
  }
31
- .dynamic-joystick-container-${id}:hover .joy-img-background-${id} {
32
- width: 97%;
33
- height: 97%;
32
+ .dynamic-joystick-container-${id}:hover {
33
+ }
34
+ .joy-img-background-${id}:hover {
35
+ width: 54%;
36
+ height: 54%;
34
37
  opacity: 1;
35
38
  }
36
39
  </style>
@@ -65,12 +65,6 @@ const Modal = {
65
65
  options.heightTopBar = options.heightTopBar + options.heightBottomBar;
66
66
  options.heightBottomBar = 0;
67
67
  }
68
- const setCenterRestore = () => {
69
- const ResponsiveData = Responsive.getResponsiveData();
70
- top = `${ResponsiveData.height / 2 - height / 2}px`;
71
- left = `${ResponsiveData.width / 2 - width / 2}px`;
72
- };
73
- setCenterRestore();
74
68
  let transition = `opacity 0.3s, box-shadow 0.3s, bottom 0.3s`;
75
69
  const originSlideMenuWidth = 320;
76
70
  const collapseSlideMenuWidth = 50;
@@ -91,6 +85,12 @@ const Modal = {
91
85
  onBarUiClose: {},
92
86
  query: options.query ? `${window.location.search}` : undefined,
93
87
  };
88
+ const setCenterRestore = () => {
89
+ const ResponsiveData = Responsive.getResponsiveData();
90
+ top = `${ResponsiveData.height / 2 - height / 2}px`;
91
+ left = `${ResponsiveData.width / 2 - width / 2}px`;
92
+ };
93
+ if (idModal !== 'main-body') setCenterRestore();
94
94
  if (options && 'mode' in options) {
95
95
  this.Data[idModal][options.mode] = {};
96
96
  switch (options.mode) {
@@ -265,6 +265,7 @@ const Modal = {
265
265
  <i class="fas fa-caret-up main-body-btn-ui-close"></i>
266
266
  </div>
267
267
  </div>
268
+ <div class="main-body-btn-container-custom"></div>
268
269
  </div>
269
270
  `,
270
271
  );
@@ -402,6 +403,11 @@ const Modal = {
402
403
  })}
403
404
  </div>
404
405
  </div>
406
+ ${options?.slideMenuTopBarFix
407
+ ? html`<div class="abs modal slide-menu-top-bar-fix" style="height: ${options.heightTopBar}px">
408
+ ${await options.slideMenuTopBarFix()}
409
+ </div>`
410
+ : ''}
405
411
  </div>`,
406
412
  );
407
413
  EventsUI.onClick(`.action-btn-profile-log-in`, () => {
@@ -536,12 +542,12 @@ const Modal = {
536
542
  if (routerId) {
537
543
  if (
538
544
  s(`.main-btn-${routerId}`) &&
539
- (routerId.toLocaleLowerCase().match(s(`.${id}`).value.toLocaleLowerCase()) ||
545
+ (routerId.toLowerCase().match(s(`.${id}`).value.toLowerCase()) ||
540
546
  (Translate.Data[routerId] &&
541
547
  Object.keys(Translate.Data[routerId]).filter((keyLang) =>
542
548
  Translate.Data[routerId][keyLang]
543
- .toLocaleLowerCase()
544
- .match(s(`.${id}`).value.toLocaleLowerCase()),
549
+ .toLowerCase()
550
+ .match(s(`.${id}`).value.toLowerCase()),
545
551
  ).length > 0))
546
552
  ) {
547
553
  const fontAwesomeIcon = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => {
@@ -1690,7 +1696,7 @@ const Modal = {
1690
1696
  const htmlRender = html`
1691
1697
  <br />
1692
1698
  <div class="in section-mp" style="font-size: 40px; text-align: center">
1693
- <i class="fas fa-question-circle"></i>
1699
+ ${options.icon ? options.icon : html` <i class="fas fa-question-circle"></i>`}
1694
1700
  </div>
1695
1701
  ${await options.html()}
1696
1702
  <div class="in section-mp">
@@ -1701,7 +1707,7 @@ const Modal = {
1701
1707
  style: `margin: auto`,
1702
1708
  })}
1703
1709
  </div>
1704
- <div class="in section-mp">
1710
+ <div class="in section-mp ${options.disableBtnCancel ? 'hide' : ''}">
1705
1711
  ${await BtnIcon.Render({
1706
1712
  class: `in section-mp form-button btn-cancel-${id}`,
1707
1713
  label: Translate.Render('cancel'),
@@ -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';
@@ -51,8 +51,6 @@ const Panel = {
51
51
  <i style="font-size: 25px" class="fa-solid fa-cloud"></i>
52
52
  </div>`;
53
53
 
54
- let editId;
55
-
56
54
  const openPanelForm = () => {
57
55
  s(`.${idPanel}-form-body`).classList.remove('hide');
58
56
  s(`.btn-${idPanel}-add`).classList.add('hide');
@@ -72,11 +70,12 @@ const Panel = {
72
70
  };
73
71
 
74
72
  const renderPanel = async (payload) => {
75
- const obj = payload;
73
+ const obj = newInstance(payload);
76
74
  if ('_id' in obj) obj.id = obj._id;
77
75
  const { id } = obj;
78
76
 
79
77
  setTimeout(async () => {
78
+ if (!s(`.${idPanel}`)) return;
80
79
  LoadingAnimation.spinner.play(`.${idPanel}-img-spinner-${id}`, 'dual-ring');
81
80
  if (options && options.callBackPanelRender)
82
81
  await options.callBackPanelRender({
@@ -97,8 +96,8 @@ const Panel = {
97
96
  });
98
97
  EventsUI.onClick(`.${idPanel}-btn-edit-${id}`, async () => {
99
98
  logger.warn('edit', obj);
100
- if (obj._id) editId = obj._id;
101
- else if (obj.id) editId = obj.id;
99
+ if (obj._id) Panel.Tokens[idPanel].editId = obj._id;
100
+ else if (obj.id) Panel.Tokens[idPanel].editId = obj.id;
102
101
 
103
102
  s(`.btn-${idPanel}-label-edit`).classList.remove('hide');
104
103
  s(`.btn-${idPanel}-label-add`).classList.add('hide');
@@ -170,6 +169,10 @@ const Panel = {
170
169
  const valueIcon = formObjData?.panel?.icon?.value ? formObjData.panel.icon.value : '';
171
170
  const keyIcon = formObjData?.panel?.icon?.key ? formObjData.panel.icon.key : '';
172
171
 
172
+ if (formObjData && ['datetime-local'].includes(formObjData.inputType) && isValidDate(obj[infoKey])) {
173
+ obj[infoKey] = `${obj[infoKey]}`.replace('T', ' ').replace('.000Z', '');
174
+ }
175
+
173
176
  if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'tags')) {
174
177
  setTimeout(async () => {
175
178
  let tagRender = html``;
@@ -185,22 +188,50 @@ const Panel = {
185
188
  });
186
189
  return html``;
187
190
  }
191
+ {
192
+ const formDataObj = formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'list');
193
+ if (obj[infoKey] && obj[infoKey].length > 0 && formDataObj)
194
+ return html`<div class="in ${idPanel}-row">
195
+ <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
196
+ ${keyIcon} ${Translate.Render(infoKey)}:</span
197
+ >
198
+ <span class="${idPanel}-row-value"
199
+ >${valueIcon} ${obj[infoKey].map((k) => Translate.Render(k)).join(', ')}</span
200
+ >
201
+ </div> `;
202
+ }
188
203
 
189
- if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'info-row-pin'))
190
- return html`<div class="in ${idPanel}-row">
191
- <span class="${idPanel}-row-pin-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
192
- ${keyIcon} ${infoKey}:</span
193
- >
194
- <span class="${idPanel}-row-pin-value">${valueIcon} ${obj[infoKey]}</span>
195
- </div> `;
204
+ {
205
+ const formDataObj = formData.find(
206
+ (f) => f.model === infoKey && f.panel && f.panel.type === 'info-row-pin',
207
+ );
208
+ if (obj[infoKey] && formDataObj)
209
+ return html`<div class="in ${idPanel}-row">
210
+ <span class="${idPanel}-row-pin-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
211
+ ${keyIcon}
212
+ ${formDataObj.translateCode
213
+ ? Translate.Render(formDataObj.translateCode)
214
+ : Translate.Render(infoKey)}:</span
215
+ >
216
+ <span class="${idPanel}-row-pin-value">${valueIcon} ${obj[infoKey]}</span>
217
+ </div> `;
218
+ }
196
219
 
197
- if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'info-row'))
198
- return html`<div class="in ${idPanel}-row">
199
- <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
200
- ${keyIcon} ${infoKey}:</span
201
- >
202
- <span class="${idPanel}-row-value"> ${valueIcon} ${obj[infoKey]}</span>
203
- </div> `;
220
+ {
221
+ const formDataObj = formData.find(
222
+ (f) => f.model === infoKey && f.panel && f.panel.type === 'info-row',
223
+ );
224
+ if (obj[infoKey] && formDataObj)
225
+ return html`<div class="in ${idPanel}-row">
226
+ <span class="${idPanel}-row-key capitalize ${formObjData.label?.disabled ? 'hide' : ''}">
227
+ ${keyIcon}
228
+ ${formDataObj.translateCode
229
+ ? Translate.Render(formDataObj.translateCode)
230
+ : Translate.Render(infoKey)}:</span
231
+ >
232
+ <span class="${idPanel}-row-value"> ${valueIcon} ${obj[infoKey]}</span>
233
+ </div> `;
234
+ }
204
235
 
205
236
  return html``;
206
237
  })
@@ -223,6 +254,30 @@ const Panel = {
223
254
  for (const modelData of formData) {
224
255
  if (modelData.disableRender) continue;
225
256
  switch (modelData.inputType) {
257
+ case 'dropdown-checkbox': {
258
+ renderForm += html`<div class="in section-mp">
259
+ ${await DropDown.Render({
260
+ id: `${modelData.id}`,
261
+ label: html`${Translate.Render(modelData.model)}`,
262
+ type: 'checkbox',
263
+ value: modelData.dropdown.options[0],
264
+ resetOption: true,
265
+ containerClass: `${idPanel}-dropdown-checkbox`,
266
+ data: modelData.dropdown.options.map((dKey) => {
267
+ return {
268
+ value: dKey,
269
+ data: dKey,
270
+ checked: false,
271
+ display: html`${Translate.Render(dKey)}`,
272
+ onClick: function () {
273
+ logger.info('DropDown onClick', this.checked);
274
+ },
275
+ };
276
+ }),
277
+ })}
278
+ </div>`;
279
+ break;
280
+ }
226
281
  case 'dropdown':
227
282
  renderForm += html` <div class="in section-mp">
228
283
  ${await DropDown.Render({
@@ -417,21 +472,23 @@ const Panel = {
417
472
  obj.id = `${data.length}`;
418
473
  let documents;
419
474
  if (options && options.on && options.on.add) {
420
- const { status, data } = await options.on.add({ data: obj, editId });
475
+ const { status, data } = await options.on.add({ data: obj, editId: Panel.Tokens[idPanel].editId });
421
476
  if (status === 'error') return;
422
477
  documents = data;
423
478
  }
424
479
  s(`.btn-${idPanel}-clean`).click();
425
- if (editId && s(`.${idPanel}-${editId}`)) s(`.${idPanel}-${editId}`).remove();
480
+ if (Panel.Tokens[idPanel].editId && s(`.${idPanel}-${Panel.Tokens[idPanel].editId}`))
481
+ s(`.${idPanel}-${Panel.Tokens[idPanel].editId}`).remove();
426
482
  if (Array.isArray(documents)) {
427
483
  htmls(`.${idPanel}-render`, '');
428
484
  for (const doc of documents) {
429
485
  append(`.${idPanel}-render`, await renderPanel(doc));
430
486
  }
431
- } else htmls(`.${idPanel}-render`, await renderPanel(obj));
487
+ } else htmls(`.${idPanel}-render`, await renderPanel({ ...obj, ...documents }));
432
488
  Input.cleanValues(formData);
433
489
  s(`.btn-${idPanel}-close`).click();
434
490
  s(`.${scrollClassContainer}`).scrollTop = 0;
491
+ if (s(`.${scrollClassContainer}`)) s(`.${scrollClassContainer}`).style.overflow = 'auto';
435
492
  });
436
493
  s(`.btn-${idPanel}-clean`).onclick = () => {
437
494
  Input.cleanValues(formData);
@@ -457,13 +514,14 @@ const Panel = {
457
514
  s(`.btn-${idPanel}-add`).onclick = (e) => {
458
515
  e.preventDefault();
459
516
  // s(`.btn-${idPanel}-clean`).click();
460
- editId = undefined;
517
+ Panel.Tokens[idPanel].editId = undefined;
461
518
  s(`.btn-${idPanel}-label-add`).classList.remove('hide');
462
519
  s(`.btn-${idPanel}-label-edit`).classList.add('hide');
463
520
  s(`.${scrollClassContainer}`).scrollTop = 0;
464
521
 
465
522
  openPanelForm();
466
523
  };
524
+ if (s(`.${scrollClassContainer}`)) s(`.${scrollClassContainer}`).style.overflow = 'auto';
467
525
  });
468
526
 
469
527
  if (data.length > 0) for (const obj of data) render += await renderPanel(obj);
@@ -596,7 +654,9 @@ const Panel = {
596
654
  >
597
655
  <div class="in ${idPanel}-form-header">
598
656
  ${await BtnIcon.Render({
599
- class: `section-mp btn-custom btn-${idPanel}-add`,
657
+ class: `section-mp btn-custom btn-${idPanel}-add ${
658
+ options?.role?.add ? (!options.role.add() ? 'hide' : '') : ''
659
+ }`,
600
660
  label: html`<i class="fas fa-plus"></i> ${Translate.Render('add')}`,
601
661
  type: 'button',
602
662
  })}
@@ -90,16 +90,7 @@ const PanelForm = {
90
90
  },
91
91
  },
92
92
  ];
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
- >`;
93
+
103
94
  const titleIcon = html`<i class="fa-solid fa-quote-left"></i>`;
104
95
  const panelRender = async ({ data }) =>
105
96
  await Panel.Render({
@@ -271,7 +262,7 @@ const PanelForm = {
271
262
  fileId: file ? URL.createObjectURL(file) : undefined,
272
263
  _id: documentData._id,
273
264
  id: documentData._id,
274
- createdAt: dateFormat(documentData.createdAt),
265
+ createdAt: documentData.createdAt,
275
266
  };
276
267
 
277
268
  if (documentStatus === 'error') status = 'error';
@@ -376,7 +367,7 @@ const PanelForm = {
376
367
  PanelForm.Data[idPanel].data.push({
377
368
  id: documentObject._id,
378
369
  title: documentObject.title,
379
- createdAt: dateFormat(documentObject.createdAt),
370
+ createdAt: documentObject.createdAt,
380
371
  tags: documentObject.tags.filter((t) => !prefixTags.includes(t)),
381
372
  mdFileId: marked.parse(mdFileId),
382
373
  userId: documentObject.userId._id,
@@ -431,14 +422,9 @@ const PanelForm = {
431
422
  })),
432
423
  });
433
424
 
434
- let lastCid;
435
- let lasUserId;
436
425
  this.Data[idPanel].updatePanel = async () => {
437
426
  const cid = getQueryParams().cid ? getQueryParams().cid : '';
438
- if (lastCid === cid && lasUserId === Elements.Data.user.main.model.user._id) return;
439
427
  if (options.route === 'home') Modal.homeCid = newInstance(cid);
440
- lastCid = cid;
441
- lasUserId = newInstance(Elements.Data.user.main.model.user._id);
442
428
  htmls(`.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`, await renderSrrPanelData());
443
429
  await getPanelData();
444
430
  htmls(
@@ -451,12 +437,18 @@ const PanelForm = {
451
437
  id: options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body',
452
438
  routeId: options.route,
453
439
  event: async (path) => {
454
- await this.Data[idPanel].updatePanel();
440
+ if (!PanelForm.Data[idPanel].sessionIn) await this.Data[idPanel].updatePanel();
455
441
  },
456
442
  });
457
443
 
458
444
  // if (options.route === 'home') setTimeout(this.Data[idPanel].updatePanel);
459
- if (!Auth.getToken()) setTimeout(this.Data[idPanel].updatePanel);
445
+ setTimeout(() => {
446
+ if (
447
+ options.route !== 'home' &&
448
+ (!PanelForm.Data[idPanel].originData || PanelForm.Data[idPanel].originData.length === 0)
449
+ )
450
+ this.Data[idPanel].updatePanel();
451
+ });
460
452
 
461
453
  if (options.parentIdModal) {
462
454
  htmls(`.html-${options.parentIdModal}`, await renderSrrPanelData());
@@ -52,7 +52,10 @@ const SignUp = {
52
52
  : Translate.Render(`no-valid-register`),
53
53
  status: result.status,
54
54
  });
55
- if (result.status === 'success') await Auth.signUpToken(result);
55
+ if (result.status === 'success') {
56
+ await Auth.signUpToken(result);
57
+ s(`.btn-close-${options.idModal}`).click();
58
+ }
56
59
  });
57
60
  s(`.btn-sign-up-i-have-account`).onclick = () => {
58
61
  s(`.main-btn-log-in`).click();
@@ -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);
@@ -460,6 +474,40 @@ const TranslateCore = {
460
474
  es: 'Carga completada',
461
475
  };
462
476
  Translate.Data['play'] = { es: 'Jugar', en: 'Play' };
477
+ Translate.Data['pause'] = { es: 'Pausar', en: 'Pause' };
478
+ Translate.Data['stop'] = { es: 'Parar', en: 'Stop' };
479
+ Translate.Data['previous'] = { es: 'Anterior', en: 'Previous' };
480
+ Translate.Data['next'] = { es: 'Siguiente', en: 'Next' };
481
+ Translate.Data['buy'] = { es: 'comprar', en: 'Buy' };
482
+ Translate.Data['sell'] = { es: 'Vender', en: 'sell' };
483
+
484
+ Translate.Data['monday'] = { es: 'Lunes', en: 'Monday' };
485
+ Translate.Data['tuesday'] = { es: 'Martes', en: 'Tuesday' };
486
+ Translate.Data['wednesday'] = { es: 'Miércoles', en: 'Wednesday' };
487
+ Translate.Data['thursday'] = { es: 'Jueves', en: 'Thursday' };
488
+ Translate.Data['friday'] = { es: 'Viernes', en: 'Friday' };
489
+ Translate.Data['saturday'] = { es: 'Sábado', en: 'Saturday' };
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
+ };
463
511
  },
464
512
  };
465
513
 
@@ -1,4 +1,4 @@
1
- import { validatePassword } from './CommonJs.js';
1
+ import { isChileanIdentityDocument, validatePassword } from './CommonJs.js';
2
2
  import { renderStatus } from './Css.js';
3
3
  import { loggerFactory } from './Logger.js';
4
4
  import { textFormatted, Translate } from './Translate.js';
@@ -58,6 +58,14 @@ const Validator = {
58
58
  if (!validator.isLength(s(`.${validatorData.id}`).value, rule.options))
59
59
  errorMessage += this.renderErrorMessage(rule);
60
60
  break;
61
+
62
+ case 'isChileanIdentityDocument': {
63
+ if (!isChileanIdentityDocument(s(`.${validatorData.id}`).value)) {
64
+ errorMessage += this.renderErrorMessage(undefined, Translate.Render('invalid-identity-document'));
65
+ }
66
+
67
+ break;
68
+ }
61
69
  default:
62
70
  if (
63
71
  validator[rule.type] &&