underpost 2.7.7 → 2.7.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.
Files changed (39) hide show
  1. package/.github/workflows/ghpkg.yml +75 -0
  2. package/.github/workflows/publish.yml +21 -3
  3. package/.github/workflows/pwa-microservices-template.test.yml +30 -0
  4. package/bin/deploy.js +13 -2
  5. package/bin/index.js +1 -1
  6. package/docker-compose.yml +1 -1
  7. package/package.json +1 -1
  8. package/src/client/components/core/Css.js +0 -222
  9. package/src/client/components/core/Docs.js +1 -1
  10. package/src/client/components/core/Translate.js +6 -2
  11. package/src/client/components/core/Worker.js +14 -4
  12. package/src/client/services/default/default.management.js +118 -120
  13. package/src/client/ssr/Render.js +224 -3
  14. package/src/client/ssr/common/Alert.js +75 -0
  15. package/src/client/ssr/common/SsrCore.js +91 -0
  16. package/src/client/ssr/common/Translate.js +26 -0
  17. package/src/client/ssr/common/Worker.js +28 -0
  18. package/src/client/ssr/{body-components → components/body}/CacheControl.js +1 -1
  19. package/src/client/ssr/{body-components → components/body}/DefaultSplashScreen.js +15 -4
  20. package/src/client/ssr/offline/default.index.js +31 -0
  21. package/src/client/ssr/pages/404.js +12 -0
  22. package/src/client/ssr/pages/500.js +12 -0
  23. package/src/client/sw/default.sw.js +11 -9
  24. package/src/mailer/EmailRender.js +1 -1
  25. package/src/server/client-build-live.js +6 -0
  26. package/src/server/client-build.js +95 -25
  27. package/src/server/client-formatted.js +11 -1
  28. package/src/server/client-icons.js +1 -1
  29. package/src/server/conf.js +9 -7
  30. package/src/server/runtime.js +24 -7
  31. package/.github/workflows/test.yml +0 -80
  32. package/src/client/ssr/head-components/Microdata.js +0 -11
  33. package/src/client/ssr/head-components/Production.js +0 -1
  34. package/src/client/ssr/head-components/Seo.js +0 -14
  35. /package/src/client/ssr/{email-components → components/email}/DefaultRecoverEmail.js +0 -0
  36. /package/src/client/ssr/{email-components → components/email}/DefaultVerifyEmail.js +0 -0
  37. /package/src/client/ssr/{head-components → components/head}/Css.js +0 -0
  38. /package/src/client/ssr/{head-components → components/head}/DefaultScripts.js +0 -0
  39. /package/src/client/ssr/{head-components → components/head}/PwaDefault.js +0 -0
@@ -4,6 +4,7 @@ import { getId, timer } from '../../components/core/CommonJs.js';
4
4
  import { darkTheme } from '../../components/core/Css.js';
5
5
  import { EventsUI } from '../../components/core/EventsUI.js';
6
6
  import { loggerFactory } from '../../components/core/Logger.js';
7
+ import { Modal } from '../../components/core/Modal.js';
7
8
  import { NotificationManager } from '../../components/core/NotificationManager.js';
8
9
  import { Translate } from '../../components/core/Translate.js';
9
10
  import { s } from '../../components/core/VanillaJs.js';
@@ -73,35 +74,40 @@ const DefaultManagement = {
73
74
  this.tokens[cellRenderId] = {};
74
75
 
75
76
  this.eGui.innerHTML = html` ${await BtnIcon.Render({
76
- label: html`<div class="abs center btn-remove-${id}-${cellRenderId}-label">
77
- <i class="fas fa-times"></i>
78
- </div>
79
- <div class="abs center btn-remove-${id}-${cellRenderId}-loading hide">
80
- <div class="lds-dual-ring-mini"></div>
81
- </div>`,
77
+ label: html`<div class="abs center">
78
+ <i class="fas fa-times"></i>
79
+ </div> `,
82
80
  class: `in fll section-mp management-table-btn-mini management-table-btn-remove-${id}-${cellRenderId}`,
83
81
  })}`;
84
82
  setTimeout(() => {
85
- EventsUI.onClick(
86
- `.management-table-btn-remove-${id}-${cellRenderId}`,
87
- async () => {
88
- s(`.btn-remove-${id}-${cellRenderId}-label`).classList.add('hide');
89
- s(`.btn-remove-${id}-${cellRenderId}-loading`).classList.remove('hide');
90
-
91
- let result;
92
- if (params.data._id) result = await ServiceProvider.delete({ id: params.data._id });
93
- else result = { status: 'success' };
83
+ EventsUI.onClick(`.management-table-btn-remove-${id}-${cellRenderId}`, async () => {
84
+ const confirmResult = await Modal.RenderConfirm({
85
+ html: async () => {
86
+ return html`
87
+ <div class="in section-mp" style="text-align: center">
88
+ ${Translate.Render('confirm-delete-item')}
89
+ ${Object.keys(params.data).length > 0
90
+ ? html`<br />
91
+ "${params.data[Object.keys(params.data)[0]]}"`
92
+ : ''}
93
+ </div>
94
+ `;
95
+ },
96
+ id: `delete-${params.data._id}`,
97
+ });
98
+ if (confirmResult.status !== 'confirm') return;
99
+ let result;
100
+ if (params.data._id) result = await ServiceProvider.delete({ id: params.data._id });
101
+ else result = { status: 'success' };
94
102
 
95
- NotificationManager.Push({
96
- html: result.status === 'error' ? result.message : Translate.Render('item-success-delete'),
97
- status: result.status,
98
- });
99
- if (result.status === 'success') {
100
- AgGrid.grids[gridId].applyTransaction({ remove: [params.data] });
101
- }
102
- },
103
- { disableSpinner: true },
104
- );
103
+ NotificationManager.Push({
104
+ html: result.status === 'error' ? result.message : Translate.Render('item-success-delete'),
105
+ status: result.status,
106
+ });
107
+ if (result.status === 'success') {
108
+ AgGrid.grids[gridId].applyTransaction({ remove: [params.data] });
109
+ }
110
+ });
105
111
  });
106
112
  }
107
113
 
@@ -133,134 +139,126 @@ const DefaultManagement = {
133
139
  {
134
140
  const result = await ServiceProvider.get();
135
141
  if (result.status === 'success') {
136
- rowDataScope = result.data.reverse().map((row) => columnDefFormatter(row, columnDefs, options.customFormat));
142
+ rowDataScope = result.data.map((row) => columnDefFormatter(row, columnDefs, options.customFormat));
137
143
  AgGrid.grids[gridId].setGridOption('rowData', rowDataScope);
138
144
  }
139
145
  }
140
146
  s(`.management-table-btn-save-${id}`).onclick = () => {
141
147
  AgGrid.grids[gridId].stopEditing();
142
148
  };
143
- EventsUI.onClick(
144
- `.management-table-btn-add-${id}`,
145
- async () => {
146
- s(`.btn-add-${id}-label`).classList.add('hide');
147
- s(`.btn-add-${id}-loading`).classList.remove('hide');
148
- const rowObj = {};
149
- for (const def of columnDefs) {
150
- rowObj[def.field] = '';
151
- }
152
- // const result = await ServiceProvider.post({ body: rowObj });
153
- const result = {
154
- status: 'success',
155
- data: rowObj,
156
- };
157
- // NotificationManager.Push({
158
- // html: result.status === 'error' ? result.message : `${Translate.Render('success-create-item')}`,
159
- // status: result.status,
149
+ EventsUI.onClick(`.management-table-btn-add-${id}`, async () => {
150
+ const rowObj = {};
151
+ for (const def of columnDefs) {
152
+ rowObj[def.field] = '';
153
+ }
154
+ // const result = await ServiceProvider.post({ body: rowObj });
155
+ const result = {
156
+ status: 'success',
157
+ data: rowObj,
158
+ };
159
+ // NotificationManager.Push({
160
+ // html: result.status === 'error' ? result.message : `${Translate.Render('success-create-item')}`,
161
+ // status: result.status,
162
+ // });
163
+ if (result.status === 'success') {
164
+ AgGrid.grids[gridId].applyTransaction({
165
+ add: [columnDefFormatter(result.data, columnDefs, options.customFormat)],
166
+ addIndex: 0,
167
+ });
168
+ // AgGrid.grids[gridId].applyColumnState({
169
+ // state: [
170
+ // // { colId: 'country', sort: 'asc', sortIndex: 1 },
171
+ // { colId: 'updatedAt', sort: 'desc', sortIndex: 0 },
172
+ // ],
173
+ // defaultState: { sort: null },
160
174
  // });
161
- if (result.status === 'success') {
162
- AgGrid.grids[gridId].applyTransaction({
163
- add: [columnDefFormatter(result.data, columnDefs, options.customFormat)],
164
- addIndex: 0,
165
- });
166
- // AgGrid.grids[gridId].applyColumnState({
167
- // state: [
168
- // // { colId: 'country', sort: 'asc', sortIndex: 1 },
169
- // { colId: 'updatedAt', sort: 'desc', sortIndex: 0 },
170
- // ],
171
- // defaultState: { sort: null },
172
- // });
173
- } else {
174
- // AgGrid.grids[gridId].applyColumnState({
175
- // defaultState: { sort: null },
176
- // });
177
- }
175
+ } else {
176
+ // AgGrid.grids[gridId].applyColumnState({
177
+ // defaultState: { sort: null },
178
+ // });
179
+ }
178
180
 
179
- // https://www.ag-grid.com/javascript-data-grid/cell-editing-start-stop/
181
+ // https://www.ag-grid.com/javascript-data-grid/cell-editing-start-stop/
180
182
 
181
- const pinned = undefined;
182
- const key = undefined;
183
+ const pinned = undefined;
184
+ const key = undefined;
183
185
 
184
- // setFocusedCell = (
185
- // rowIndex: number,
186
- // colKey: string | Column,
187
- // rowPinned?: RowPinnedType
188
- // ) => void;
186
+ // setFocusedCell = (
187
+ // rowIndex: number,
188
+ // colKey: string | Column,
189
+ // rowPinned?: RowPinnedType
190
+ // ) => void;
189
191
 
190
- // type RowPinnedType =
191
- // 'top'
192
- // | 'bottom'
193
- // | null
194
- // | undefined
192
+ // type RowPinnedType =
193
+ // 'top'
194
+ // | 'bottom'
195
+ // | null
196
+ // | undefined
195
197
 
196
- AgGrid.grids[gridId].setFocusedCell(0, '0', pinned);
198
+ AgGrid.grids[gridId].setFocusedCell(0, '0', pinned);
197
199
 
198
- // interface StartEditingCellParams {
199
- // // The row index of the row to start editing
200
- // rowIndex: number;
201
- // // The column key of the row to start editing
202
- // colKey: string | Column;
203
- // // Set to `'top'` or `'bottom'` to start editing a pinned row
204
- // rowPinned?: RowPinnedType;
205
- // // The key to pass to the cell editor
206
- // key?: string;
207
- // }
208
- s(`.btn-add-${id}-loading`).classList.add('hide');
209
- s(`.btn-add-${id}-label`).classList.remove('hide');
200
+ // interface StartEditingCellParams {
201
+ // // The row index of the row to start editing
202
+ // rowIndex: number;
203
+ // // The column key of the row to start editing
204
+ // colKey: string | Column;
205
+ // // Set to `'top'` or `'bottom'` to start editing a pinned row
206
+ // rowPinned?: RowPinnedType;
207
+ // // The key to pass to the cell editor
208
+ // key?: string;
209
+ // }
210
210
 
211
- setTimeout(() => {
212
- AgGrid.grids[gridId].startEditingCell({
213
- rowIndex: 0,
214
- colKey: defaultColKeyFocus,
215
- rowPinned: pinned,
216
- key: key,
217
- });
211
+ setTimeout(() => {
212
+ AgGrid.grids[gridId].startEditingCell({
213
+ rowIndex: 0,
214
+ colKey: defaultColKeyFocus,
215
+ rowPinned: pinned,
216
+ key: key,
218
217
  });
219
- },
220
- { disableSpinner: true },
221
- );
222
- EventsUI.onClick(
223
- `.management-table-btn-clean-${id}`,
224
- async () => {
225
- s(`.btn-clean-${id}-label`).classList.add('hide');
226
- s(`.btn-clean-${id}-loading`).classList.remove('hide');
227
- const result = await ServiceProvider.delete();
228
- NotificationManager.Push({
229
- html: result.status === 'error' ? result.message : Translate.Render('success-delete-all-items'),
230
- status: result.status,
231
- });
232
- if (result.status === 'success') {
233
- AgGrid.grids[gridId].setGridOption('rowData', []);
234
- }
235
- s(`.btn-clean-${id}-loading`).classList.add('hide');
236
- s(`.btn-clean-${id}-label`).classList.remove('hide');
237
- },
238
- { disableSpinner: true },
239
- );
218
+ });
219
+ });
220
+ EventsUI.onClick(`.management-table-btn-clean-${id}`, async () => {
221
+ const confirmResult = await Modal.RenderConfirm({
222
+ html: async () => {
223
+ return html`
224
+ <div class="in section-mp" style="text-align: center;">
225
+ <strong>${Translate.Render('confirm-delete-all-data')}</strong>
226
+ </div>
227
+ `;
228
+ },
229
+ id: `clean-table-${id}`,
230
+ });
231
+ if (confirmResult.status === 'cancelled') return;
232
+ const result = await ServiceProvider.delete();
233
+ NotificationManager.Push({
234
+ html: result.status === 'error' ? result.message : Translate.Render('success-delete-all-items'),
235
+ status: result.status,
236
+ });
237
+ if (result.status === 'success') {
238
+ AgGrid.grids[gridId].setGridOption('rowData', []);
239
+ }
240
+ });
240
241
  }, 1);
241
242
  return html`<div class="fl">
242
243
  ${await BtnIcon.Render({
243
244
  class: `in fll section-mp management-table-btn-mini management-table-btn-add-${id} ${
244
245
  permissions.add ? '' : 'hide'
245
246
  }`,
246
- label: html`<div class="abs center btn-add-${id}-label"><i class="fa-solid fa-circle-plus"></i></div>
247
- <div class="abs center btn-add-${id}-loading hide"><div class="lds-dual-ring-mini"></div></div> `,
247
+ label: html`<div class="abs center btn-add-${id}-label"><i class="fa-solid fa-circle-plus"></i></div> `,
248
248
  type: 'button',
249
249
  })}
250
250
  ${await BtnIcon.Render({
251
251
  class: `in fll section-mp management-table-btn-mini management-table-btn-save-${id} ${
252
252
  permissions.add ? '' : 'hide'
253
253
  }`,
254
- label: html`<div class="abs center btn-save-${id}-label"><i class="fas fa-save"></i></div>
255
- <div class="abs center btn-save-${id}-loading hide"><div class="lds-dual-ring-mini"></div></div>`,
254
+ label: html`<div class="abs center btn-save-${id}-label"><i class="fas fa-save"></i></div> `,
256
255
  type: 'button',
257
256
  })}
258
257
  ${await BtnIcon.Render({
259
258
  class: `in fll section-mp management-table-btn-mini management-table-btn-clean-${id} ${
260
259
  permissions.remove ? '' : 'hide'
261
260
  }`,
262
- label: html`<div class="abs center btn-clean-${id}-label"><i class="fas fa-broom"></i></div>
263
- <div class="abs center btn-clean-${id}-loading hide"><div class="lds-dual-ring-mini"></div></div>`,
261
+ label: html`<div class="abs center btn-clean-${id}-label"><i class="fas fa-broom"></i></div> `,
264
262
  type: 'button',
265
263
  })}
266
264
  </div>
@@ -1,4 +1,4 @@
1
- Render = ({ title, ssrPath, buildId, ssrHeadComponents, ssrBodyComponents }) => html`
1
+ Render = ({ title, ssrPath, buildId, ssrHeadComponents, ssrBodyComponents, baseSsrLib }) => html`
2
2
  <!DOCTYPE html>
3
3
  <html dir="ltr" lang="en">
4
4
  <head>
@@ -9,8 +9,229 @@ Render = ({ title, ssrPath, buildId, ssrHeadComponents, ssrBodyComponents }) =>
9
9
  ${ssrHeadComponents}
10
10
  </head>
11
11
  <body>
12
- ${ssrBodyComponents}
13
- <script async type="module" src="./${buildId}.js"></script>
12
+ <style>
13
+ html {
14
+ scroll-behavior: smooth;
15
+ }
16
+
17
+ body {
18
+ /* overscroll-behavior: contain; */
19
+ /* box-sizing: border-box; */
20
+ padding: 0px;
21
+ margin: 0px;
22
+ }
23
+
24
+ .fl {
25
+ position: relative;
26
+ display: flow-root;
27
+ }
28
+
29
+ .abs,
30
+ .in {
31
+ display: block;
32
+ }
33
+
34
+ .fll {
35
+ float: left;
36
+ }
37
+
38
+ .flr {
39
+ float: right;
40
+ }
41
+
42
+ .abs {
43
+ position: absolute;
44
+ }
45
+
46
+ .in,
47
+ .inl {
48
+ position: relative;
49
+ }
50
+
51
+ .inl {
52
+ display: inline-table;
53
+ display: -webkit-inline-table;
54
+ display: -moz-inline-table;
55
+ display: -ms-inline-table;
56
+ display: -o-inline-table;
57
+ }
58
+
59
+ .fix {
60
+ position: fixed;
61
+ display: block;
62
+ }
63
+
64
+ .stq {
65
+ position: sticky;
66
+ /* require defined at least top, bottom, left o right */
67
+ }
68
+
69
+ .wfa {
70
+ width: available;
71
+ width: -webkit-available;
72
+ width: -moz-available;
73
+ width: -ms-available;
74
+ width: -o-available;
75
+
76
+ width: fill-available;
77
+ width: -webkit-fill-available;
78
+ width: -moz-fill-available;
79
+ width: -ms-fill-available;
80
+ width: -o-fill-available;
81
+ }
82
+
83
+ .wft {
84
+ width: fit-content;
85
+ width: -webkit-fit-content;
86
+ width: -moz-fit-content;
87
+ width: -ms-fit-content;
88
+ width: -o-fit-content;
89
+ }
90
+
91
+ .wfm {
92
+ width: max-content;
93
+ width: -webkit-max-content;
94
+ width: -moz-max-content;
95
+ width: -ms-max-content;
96
+ width: -o-max-content;
97
+ }
98
+
99
+ .negative-color {
100
+ filter: invert(1);
101
+ -webkit-filter: invert(1);
102
+ -moz-filter: invert(1);
103
+ -ms-filter: invert(1);
104
+ -o-filter: invert(1);
105
+ }
106
+
107
+ .no-drag {
108
+ user-drag: none;
109
+ -webkit-user-drag: none;
110
+ -moz-user-drag: none;
111
+ -ms-user-drag: none;
112
+ -o-user-drag: none;
113
+ user-select: none;
114
+ -webkit-user-select: none;
115
+ -moz-user-select: none;
116
+ -ms-user-select: none;
117
+ -o-user-select: none;
118
+ }
119
+
120
+ .center {
121
+ transform: translate(-50%, -50%);
122
+ top: 50%;
123
+ left: 50%;
124
+ width: 100%;
125
+ text-align: center;
126
+ }
127
+
128
+ input {
129
+ outline: none !important;
130
+ border: none;
131
+ padding-block: 0;
132
+ padding-inline: 0;
133
+ }
134
+ input::file-selector-button {
135
+ outline: none !important;
136
+ border: none;
137
+ }
138
+
139
+ .hide {
140
+ display: none !important;
141
+ }
142
+ /*
143
+
144
+ placeholder
145
+
146
+ */
147
+
148
+ ::placeholder {
149
+ color: black;
150
+ opacity: 1;
151
+ /* Firefox */
152
+ background: none;
153
+ }
154
+
155
+ :-ms-input-placeholder {
156
+ /* Internet Explorer 10-11 */
157
+ color: black;
158
+ background: none;
159
+ }
160
+
161
+ ::-ms-input-placeholder {
162
+ /* Microsoft Edge */
163
+ color: black;
164
+ background: none;
165
+ }
166
+
167
+ /*
168
+
169
+ selection
170
+
171
+ */
172
+
173
+ ::-moz-selection {
174
+ /* Code for Firefox */
175
+ color: black;
176
+ background: rgb(208, 208, 208);
177
+ }
178
+
179
+ ::selection {
180
+ color: black;
181
+ background: rgb(208, 208, 208);
182
+ }
183
+
184
+ .lowercase {
185
+ text-transform: lowercase;
186
+ }
187
+ .uppercase {
188
+ text-transform: uppercase;
189
+ }
190
+ .capitalize {
191
+ text-transform: capitalize;
192
+ }
193
+
194
+ .bold {
195
+ font-weight: bold;
196
+ }
197
+
198
+ .m {
199
+ font-family: monospace;
200
+ }
201
+
202
+ .gray {
203
+ filter: grayscale(1);
204
+ }
205
+ </style>
206
+ <div class="session">
207
+ <style>
208
+ .session-in-log-out {
209
+ display: block;
210
+ }
211
+ .session-inl-log-out {
212
+ display: inline-table;
213
+ }
214
+ .session-fl-log-out {
215
+ display: flow-root;
216
+ }
217
+ .session-in-log-in {
218
+ display: none;
219
+ }
220
+ .session-inl-log-in {
221
+ display: none;
222
+ }
223
+ .session-fl-log-in {
224
+ display: none;
225
+ }
226
+ </style>
227
+ </div>
228
+ <div class="theme"></div>
229
+ ${baseSsrLib
230
+ ? html`<script>
231
+ ${baseSsrLib};
232
+ </script>`
233
+ : ''}
234
+ ${ssrBodyComponents} ${buildId ? html`<script async type="module" src="./${buildId}.js"></script>` : ''}
14
235
  </body>
15
236
  </html>
16
237
  `;
@@ -0,0 +1,75 @@
1
+ const maintenance = async ({ Translate }) => {
2
+ const icon = html`<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 24 24">
3
+ <path
4
+ fill="none"
5
+ stroke="currentColor"
6
+ stroke-linecap="round"
7
+ stroke-linejoin="round"
8
+ stroke-width="2"
9
+ d="M3 7a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v2a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3zm9 13H6a3 3 0 0 1-3-3v-2a3 3 0 0 1 3-3h10.5m-.5 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0m2-3.5V16m0 4v1.5m3.032-5.25l-1.299.75m-3.463 2l-1.3.75m0-3.5l1.3.75m3.463 2l1.3.75M7 8v.01M7 16v.01"
10
+ />
11
+ </svg>`;
12
+ return html` <div class="abs center" style="top: 45%">
13
+ ${icon}
14
+ <br />
15
+ <br />${Translate('server-maintenance')}
16
+ </div>`;
17
+ };
18
+
19
+ const noInternet = async ({ Translate }) => {
20
+ const icon = html`<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 20 20">
21
+ <path
22
+ fill="currentColor"
23
+ d="M10 18q.128 0 .254-.004a5.5 5.5 0 0 1-.698-1.083c-.536-.207-1.098-.793-1.578-1.821A9.3 9.3 0 0 1 7.42 13.5h1.672q.096-.52.284-1h-2.17A15 15 0 0 1 7 10c0-.883.073-1.725.206-2.5h5.588c.092.541.156 1.115.186 1.713q.48-.138.992-.188a16 16 0 0 0-.165-1.525h2.733c.251.656.406 1.36.448 2.094q.543.276 1.008.66A8 8 0 1 0 10 18m0-15c.657 0 1.407.59 2.022 1.908c.217.466.406 1.002.559 1.592H7.419c.153-.59.342-1.126.56-1.592C8.592 3.59 9.342 3 10 3M7.072 4.485A10.5 10.5 0 0 0 6.389 6.5H3.936a7.02 7.02 0 0 1 3.778-3.118c-.241.33-.456.704-.642 1.103M6.192 7.5A16 16 0 0 0 6 10c0 .87.067 1.712.193 2.5H3.46A7 7 0 0 1 3 10c0-.88.163-1.724.46-2.5zm.197 6c.176.743.407 1.422.683 2.015c.186.399.401.773.642 1.103A7.02 7.02 0 0 1 3.936 13.5zm5.897-10.118A7.02 7.02 0 0 1 16.064 6.5H13.61a10.5 10.5 0 0 0-.683-2.015a6.6 6.6 0 0 0-.642-1.103M19 14.5a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0M14.5 12a.5.5 0 0 0-.5.5v2a.5.5 0 0 0 1 0v-2a.5.5 0 0 0-.5-.5m0 5.125a.625.625 0 1 0 0-1.25a.625.625 0 0 0 0 1.25"
24
+ />
25
+ </svg>`;
26
+ return html` <div class="abs center" style="top: 45%">
27
+ ${icon}
28
+ <br />
29
+ <br />${Translate('no-internet-connection')}
30
+ </div>`;
31
+ };
32
+
33
+ const e404 = async ({ Translate }) => {
34
+ const icon = html`
35
+ <svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 24 24">
36
+ <path
37
+ fill="currentColor"
38
+ d="M15.097 5.904A6.5 6.5 0 0 0 4 10.504l.001 1h-2v-1a8.5 8.5 0 1 1 15.176 5.258l5.344 5.345l-1.414 1.414l-5.344-5.345A8.48 8.48 0 0 1 10.5 19h-1v-2h1a6.5 6.5 0 0 0 4.596-11.096M1.672 13.257L4.5 16.086l2.829-2.829l1.414 1.415L5.915 17.5l2.828 2.828l-1.414 1.415L4.5 18.914l-2.828 2.829l-1.414-1.415L3.086 17.5L.258 14.672z"
39
+ />
40
+ </svg>
41
+ `;
42
+ return html` <div class="abs center" style="top: 45%">
43
+ ${icon}
44
+ <br />
45
+ <br />
46
+ <span class="bold">404</span>
47
+ <br />
48
+ <br />${Translate('page-not-found')} <br />
49
+ <br />
50
+ <a href="${location.origin}">${Translate('back')}</a>
51
+ </div>`;
52
+ };
53
+
54
+ const e500 = async ({ Translate }) => {
55
+ const icon = html`<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 20 20">
56
+ <path
57
+ fill="currentColor"
58
+ d="M6 2a2 2 0 0 0-2 2v5.207a5.5 5.5 0 0 1 1-.185V4a1 1 0 0 1 1-1h4v3.5A1.5 1.5 0 0 0 11.5 8H15v8a1 1 0 0 1-1 1h-3.6a5.5 5.5 0 0 1-.657 1H14a2 2 0 0 0 2-2V7.414a1.5 1.5 0 0 0-.44-1.06l-3.914-3.915A1.5 1.5 0 0 0 10.586 2zm8.793 5H11.5a.5.5 0 0 1-.5-.5V3.207zM10 14.5a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0M5.5 12a.5.5 0 0 0-.5.5v2a.5.5 0 0 0 1 0v-2a.5.5 0 0 0-.5-.5m0 5.125a.625.625 0 1 0 0-1.25a.625.625 0 0 0 0 1.25"
59
+ />
60
+ </svg>`;
61
+ return html` <div class="abs center" style="top: 45%">
62
+ ${icon}
63
+ <br />
64
+ <br />
65
+ <span class="bold">500</span>
66
+ <br />
67
+ <br />${Translate('page-broken')} <br />
68
+ <br />
69
+ <a href="${location.origin}">${Translate('back')}</a>
70
+ </div>`;
71
+ };
72
+
73
+ const Alert = { maintenance, noInternet, e404, e500 };
74
+
75
+ export { Alert, e404 };