underpost 2.8.877 → 2.8.881
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/.env.development +35 -3
- package/.env.production +40 -3
- package/.env.test +35 -3
- package/.github/workflows/release.cd.yml +3 -3
- package/README.md +48 -36
- package/bin/deploy.js +40 -0
- package/cli.md +89 -86
- package/conf.js +28 -3
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -2
- package/src/api/document/document.controller.js +66 -0
- package/src/api/document/document.model.js +51 -0
- package/src/api/document/document.router.js +24 -0
- package/src/api/document/document.service.js +125 -0
- package/src/api/file/file.controller.js +15 -1
- package/src/api/user/user.router.js +4 -3
- package/src/cli/deploy.js +1 -1
- package/src/cli/index.js +3 -0
- package/src/cli/repository.js +2 -2
- package/src/cli/run.js +29 -1
- package/src/client/Default.index.js +42 -1
- package/src/client/components/core/Account.js +8 -1
- package/src/client/components/core/AgGrid.js +18 -9
- package/src/client/components/core/BtnIcon.js +3 -2
- package/src/client/components/core/Content.js +13 -11
- package/src/client/components/core/CssCore.js +4 -0
- package/src/client/components/core/Docs.js +0 -3
- package/src/client/components/core/Input.js +34 -19
- package/src/client/components/core/Modal.js +29 -7
- package/src/client/components/core/ObjectLayerEngine.js +370 -0
- package/src/client/components/core/ObjectLayerEngineModal.js +1 -0
- package/src/client/components/core/Panel.js +7 -2
- package/src/client/components/core/PanelForm.js +187 -63
- package/src/client/components/core/VanillaJs.js +3 -0
- package/src/client/components/default/MenuDefault.js +94 -41
- package/src/client/components/default/RoutesDefault.js +2 -0
- package/src/client/services/default/default.management.js +1 -0
- package/src/client/services/document/document.service.js +97 -0
- package/src/client/services/file/file.service.js +2 -0
- package/src/client/services/user/user.service.js +1 -0
- package/src/client/ssr/Render.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +2 -0
- package/src/client/ssr/head/Seo.js +1 -0
- package/src/index.js +1 -1
- package/src/mailer/EmailRender.js +1 -1
- package/src/server/auth.js +4 -3
- package/src/server/client-build.js +2 -3
- package/src/server/client-formatted.js +40 -12
- package/src/server/conf.js +42 -3
- package/src/server/object-layer.js +196 -0
- package/src/server/runtime.js +18 -21
- package/src/server/ssr.js +52 -10
- package/src/server/valkey.js +89 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getCapVariableName, newInstance, random, range, uniqueArray } from './CommonJs.js';
|
|
1
|
+
import { getCapVariableName, newInstance, random, range, timer, uniqueArray } from './CommonJs.js';
|
|
2
2
|
import { marked } from 'marked';
|
|
3
|
-
import { getBlobFromUint8ArrayFile, getDataFromInputFile, getRawContentFile, htmls } from './VanillaJs.js';
|
|
3
|
+
import { append, getBlobFromUint8ArrayFile, getDataFromInputFile, getRawContentFile, htmls, s } from './VanillaJs.js';
|
|
4
4
|
import { Panel } from './Panel.js';
|
|
5
5
|
import { NotificationManager } from './NotificationManager.js';
|
|
6
6
|
import { DocumentService } from '../../services/document/document.service.js';
|
|
@@ -10,6 +10,11 @@ import { imageShimmer, renderCssAttr } from './Css.js';
|
|
|
10
10
|
import { Translate } from './Translate.js';
|
|
11
11
|
import { Modal } from './Modal.js';
|
|
12
12
|
import { closeModalRouteChangeEvents, listenQueryPathInstance, setQueryPath, getQueryParams } from './Router.js';
|
|
13
|
+
import { Scroll } from './Scroll.js';
|
|
14
|
+
import { LoadingAnimation } from './LoadingAnimation.js';
|
|
15
|
+
import { loggerFactory } from './Logger.js';
|
|
16
|
+
|
|
17
|
+
const logger = loggerFactory(import.meta, { trace: true });
|
|
13
18
|
|
|
14
19
|
const PanelForm = {
|
|
15
20
|
Data: {},
|
|
@@ -33,6 +38,10 @@ const PanelForm = {
|
|
|
33
38
|
originData: [],
|
|
34
39
|
data: [],
|
|
35
40
|
filesData: [],
|
|
41
|
+
skip: 0,
|
|
42
|
+
limit: 3, // Load 5 items per page
|
|
43
|
+
hasMore: true,
|
|
44
|
+
loading: false,
|
|
36
45
|
};
|
|
37
46
|
|
|
38
47
|
const formData = [
|
|
@@ -132,7 +141,7 @@ const PanelForm = {
|
|
|
132
141
|
`,
|
|
133
142
|
});
|
|
134
143
|
return await options.fileRender({
|
|
135
|
-
file: PanelForm.Data[idPanel].filesData.find((f) => f._id === options.data._id)
|
|
144
|
+
file: PanelForm.Data[idPanel].filesData.find((f) => f._id === options.data._id)?.fileId?.fileBlob,
|
|
136
145
|
style: {
|
|
137
146
|
overflow: 'auto',
|
|
138
147
|
width: '100%',
|
|
@@ -172,6 +181,15 @@ const PanelForm = {
|
|
|
172
181
|
}
|
|
173
182
|
return { status: 'error' };
|
|
174
183
|
},
|
|
184
|
+
initAdd: async function () {
|
|
185
|
+
s(`.modal-${options.route}`).scrollTo({ top: 0, behavior: 'smooth' });
|
|
186
|
+
},
|
|
187
|
+
initEdit: async function ({ data }) {
|
|
188
|
+
s(`.modal-${options.route}`).scrollTo({ top: 0, behavior: 'smooth' });
|
|
189
|
+
},
|
|
190
|
+
noResultFound: async function () {
|
|
191
|
+
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
192
|
+
},
|
|
175
193
|
add: async function ({ data, editId }) {
|
|
176
194
|
let mdFileId;
|
|
177
195
|
const mdFileName = `${getCapVariableName(data.title)}.md`;
|
|
@@ -312,67 +330,103 @@ const PanelForm = {
|
|
|
312
330
|
},
|
|
313
331
|
});
|
|
314
332
|
|
|
315
|
-
const getPanelData = async () => {
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
333
|
+
const getPanelData = async (isLoadMore = false) => {
|
|
334
|
+
const panelData = PanelForm.Data[idPanel];
|
|
335
|
+
try {
|
|
336
|
+
if (panelData.loading || !panelData.hasMore) return;
|
|
337
|
+
panelData.loading = true;
|
|
319
338
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
mdPlain = await getRawContentFile(getBlobFromUint8ArrayFile(file.data.data, file.mimetype));
|
|
342
|
-
mdFileId = newInstance(mdPlain);
|
|
343
|
-
}
|
|
344
|
-
if (documentObject.fileId) {
|
|
345
|
-
const {
|
|
346
|
-
data: [file],
|
|
347
|
-
status,
|
|
348
|
-
} = await FileService.get({ id: documentObject.fileId._id });
|
|
349
|
-
|
|
350
|
-
// const ext = file.name.split('.')[file.name.split('.').length - 1];
|
|
351
|
-
fileBlob = file;
|
|
352
|
-
filePlain = undefined;
|
|
353
|
-
fileId = getSrcFromFileData(file);
|
|
339
|
+
if (!isLoadMore) {
|
|
340
|
+
// Reset for a fresh load
|
|
341
|
+
panelData.skip = 0;
|
|
342
|
+
panelData.hasMore = true;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const result = await DocumentService.get({
|
|
346
|
+
params: {
|
|
347
|
+
tags: prefixTags.join(','),
|
|
348
|
+
...(getQueryParams().cid && { cid: getQueryParams().cid }),
|
|
349
|
+
skip: panelData.skip,
|
|
350
|
+
limit: panelData.limit,
|
|
351
|
+
},
|
|
352
|
+
id: 'public/',
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
if (result.status === 'success') {
|
|
356
|
+
if (!isLoadMore) {
|
|
357
|
+
panelData.originData = [];
|
|
358
|
+
panelData.filesData = [];
|
|
359
|
+
panelData.data = [];
|
|
354
360
|
}
|
|
355
361
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
mdFileId
|
|
360
|
-
|
|
361
|
-
|
|
362
|
+
panelData.originData.push(...newInstance(result.data));
|
|
363
|
+
|
|
364
|
+
for (const documentObject of result.data) {
|
|
365
|
+
let mdFileId, fileId;
|
|
366
|
+
let mdBlob, fileBlob;
|
|
367
|
+
let mdPlain, filePlain;
|
|
368
|
+
|
|
369
|
+
{
|
|
370
|
+
const {
|
|
371
|
+
data: [file],
|
|
372
|
+
} = await FileService.get({ id: documentObject.mdFileId });
|
|
373
|
+
|
|
374
|
+
// const ext = file.name.split('.')[file.name.split('.').length - 1];
|
|
375
|
+
mdBlob = file;
|
|
376
|
+
mdPlain = await getRawContentFile(getBlobFromUint8ArrayFile(file.data.data, file.mimetype));
|
|
377
|
+
mdFileId = newInstance(mdPlain);
|
|
378
|
+
}
|
|
379
|
+
if (documentObject.fileId) {
|
|
380
|
+
const {
|
|
381
|
+
data: [file],
|
|
382
|
+
} = await FileService.get({ id: documentObject.fileId._id });
|
|
383
|
+
|
|
384
|
+
// const ext = file.name.split('.')[file.name.split('.').length - 1];
|
|
385
|
+
fileBlob = file;
|
|
386
|
+
filePlain = undefined;
|
|
387
|
+
fileId = getSrcFromFileData(file);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
panelData.filesData.push({
|
|
391
|
+
id: documentObject._id,
|
|
392
|
+
_id: documentObject._id,
|
|
393
|
+
mdFileId: { mdBlob, mdPlain },
|
|
394
|
+
fileId: { fileBlob, filePlain },
|
|
395
|
+
});
|
|
362
396
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
397
|
+
panelData.data.push({
|
|
398
|
+
id: documentObject._id,
|
|
399
|
+
title: documentObject.title,
|
|
400
|
+
createdAt: documentObject.createdAt,
|
|
401
|
+
tags: documentObject.tags.filter((t) => !prefixTags.includes(t)),
|
|
402
|
+
mdFileId: marked.parse(mdFileId),
|
|
403
|
+
userId: documentObject.userId._id,
|
|
404
|
+
fileId,
|
|
405
|
+
tools: Elements.Data.user.main.model.user._id === documentObject.userId._id,
|
|
406
|
+
_id: documentObject._id,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
panelData.skip += result.data.length;
|
|
411
|
+
panelData.hasMore = result.data.length === panelData.limit;
|
|
412
|
+
if (result.data.length < panelData.limit) {
|
|
413
|
+
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
414
|
+
panelData.hasMore = false;
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
NotificationManager.Push({
|
|
418
|
+
html: result.message,
|
|
419
|
+
status: result.status,
|
|
373
420
|
});
|
|
421
|
+
panelData.hasMore = false;
|
|
374
422
|
}
|
|
423
|
+
} catch (error) {
|
|
424
|
+
logger.error(error);
|
|
375
425
|
}
|
|
426
|
+
|
|
427
|
+
await timer(250);
|
|
428
|
+
panelData.loading = false;
|
|
429
|
+
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
376
430
|
};
|
|
377
431
|
const renderSrrPanelData = async () =>
|
|
378
432
|
await panelRender({
|
|
@@ -421,7 +475,9 @@ const PanelForm = {
|
|
|
421
475
|
let lastCid;
|
|
422
476
|
let lastUserId;
|
|
423
477
|
closeModalRouteChangeEvents[idPanel] = () => {
|
|
424
|
-
|
|
478
|
+
setTimeout(() => {
|
|
479
|
+
this.Data[idPanel].updatePanel();
|
|
480
|
+
});
|
|
425
481
|
};
|
|
426
482
|
this.Data[idPanel].updatePanel = async () => {
|
|
427
483
|
const cid = getQueryParams().cid ? getQueryParams().cid : '';
|
|
@@ -429,12 +485,60 @@ const PanelForm = {
|
|
|
429
485
|
if (lastCid === cid && !forceUpdate) return;
|
|
430
486
|
lastUserId = newInstance(Elements.Data.user.main.model.user._id);
|
|
431
487
|
lastCid = cid;
|
|
432
|
-
|
|
488
|
+
|
|
489
|
+
if (cid) {
|
|
490
|
+
this.Data[idPanel] = {
|
|
491
|
+
...this.Data[idPanel],
|
|
492
|
+
originData: [],
|
|
493
|
+
data: [],
|
|
494
|
+
filesData: [],
|
|
495
|
+
skip: 0,
|
|
496
|
+
limit: 3, // Load 5 items per page
|
|
497
|
+
hasMore: true,
|
|
498
|
+
loading: false,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const containerSelector = `.${options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body'}`;
|
|
503
|
+
htmls(containerSelector, await renderSrrPanelData());
|
|
504
|
+
|
|
433
505
|
await getPanelData();
|
|
506
|
+
|
|
434
507
|
htmls(
|
|
435
|
-
|
|
436
|
-
|
|
508
|
+
containerSelector,
|
|
509
|
+
html`
|
|
510
|
+
<div class="in">${await panelRender({ data: this.Data[idPanel].data })}</div>
|
|
511
|
+
<div class="in panel-placeholder-bottom panel-placeholder-bottom-${idPanel}"></div>
|
|
512
|
+
`,
|
|
437
513
|
);
|
|
514
|
+
|
|
515
|
+
LoadingAnimation.spinner.play(`.panel-placeholder-bottom-${idPanel}`, 'dual-ring-mini');
|
|
516
|
+
|
|
517
|
+
const scrollContainerSelector = `.modal-${options.route}`;
|
|
518
|
+
|
|
519
|
+
if (cid) {
|
|
520
|
+
LoadingAnimation.spinner.stop(`.panel-placeholder-bottom-${idPanel}`);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
if (this.Data[idPanel].removeScrollEvent) {
|
|
524
|
+
this.Data[idPanel].removeScrollEvent();
|
|
525
|
+
}
|
|
526
|
+
const { removeEvent } = Scroll.setEvent(scrollContainerSelector, async (payload) => {
|
|
527
|
+
const panelData = PanelForm.Data[idPanel];
|
|
528
|
+
if (!panelData) return;
|
|
529
|
+
|
|
530
|
+
// Infinite scroll: load more items at bottom
|
|
531
|
+
if (payload.atBottom && panelData.hasMore && !panelData.loading) {
|
|
532
|
+
const oldDataCount = panelData.data.length;
|
|
533
|
+
await getPanelData(true); // isLoadMore = true
|
|
534
|
+
const newItems = panelData.data.slice(oldDataCount);
|
|
535
|
+
if (newItems.length > 0) {
|
|
536
|
+
for (const item of newItems) append(`.${idPanel}-render`, await Panel.Tokens[idPanel].renderPanel(item));
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
this.Data[idPanel].removeScrollEvent = removeEvent;
|
|
541
|
+
|
|
438
542
|
if (!firsUpdateEvent && options.firsUpdateEvent) {
|
|
439
543
|
firsUpdateEvent = true;
|
|
440
544
|
await options.firsUpdateEvent();
|
|
@@ -445,15 +549,35 @@ const PanelForm = {
|
|
|
445
549
|
id: options.parentIdModal ? 'html-' + options.parentIdModal : 'main-body',
|
|
446
550
|
routeId: options.route,
|
|
447
551
|
event: async (path) => {
|
|
448
|
-
|
|
552
|
+
PanelForm.Data[idPanel] = {
|
|
553
|
+
...PanelForm.Data[idPanel],
|
|
554
|
+
originData: [],
|
|
555
|
+
data: [],
|
|
556
|
+
filesData: [],
|
|
557
|
+
// skip: 0,
|
|
558
|
+
limit: 3, // Load 5 items per page
|
|
559
|
+
hasMore: true,
|
|
560
|
+
loading: false,
|
|
561
|
+
};
|
|
562
|
+
await PanelForm.Data[idPanel].updatePanel();
|
|
449
563
|
},
|
|
450
564
|
});
|
|
451
565
|
if (!options.parentIdModal)
|
|
452
566
|
Modal.Data['modal-menu'].onHome[idPanel] = async () => {
|
|
453
567
|
lastCid = undefined;
|
|
454
568
|
lastUserId = undefined;
|
|
569
|
+
PanelForm.Data[idPanel] = {
|
|
570
|
+
...PanelForm.Data[idPanel],
|
|
571
|
+
originData: [],
|
|
572
|
+
data: [],
|
|
573
|
+
filesData: [],
|
|
574
|
+
skip: 0,
|
|
575
|
+
limit: 3, // Load 5 items per page
|
|
576
|
+
hasMore: true,
|
|
577
|
+
loading: false,
|
|
578
|
+
};
|
|
455
579
|
setQueryPath({ path: options.route, queryPath: options.route === 'home' ? '?' : '' });
|
|
456
|
-
await
|
|
580
|
+
await PanelForm.Data[idPanel].updatePanel();
|
|
457
581
|
};
|
|
458
582
|
}
|
|
459
583
|
|
|
@@ -389,6 +389,8 @@ function hexToRgbA(hex) {
|
|
|
389
389
|
throw new Error('Invalid Hex');
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
const htmlStrSanitize = (str) => (str ? str.replace(/<\/?[^>]+(>|$)/g, '').trim() : '');
|
|
393
|
+
|
|
392
394
|
export {
|
|
393
395
|
s,
|
|
394
396
|
htmls,
|
|
@@ -416,4 +418,5 @@ export {
|
|
|
416
418
|
getDataFromInputFile,
|
|
417
419
|
getLang,
|
|
418
420
|
hexToRgbA,
|
|
421
|
+
htmlStrSanitize,
|
|
419
422
|
};
|
|
@@ -29,6 +29,8 @@ import { Recover } from '../core/Recover.js';
|
|
|
29
29
|
import { DefaultManagement } from '../../services/default/default.management.js';
|
|
30
30
|
import { Page500 } from '../core/500.js';
|
|
31
31
|
import { Page404 } from '../core/404.js';
|
|
32
|
+
import { PanelForm } from '../core/PanelForm.js';
|
|
33
|
+
import { Chat } from '../core/Chat.js';
|
|
32
34
|
|
|
33
35
|
const MenuDefault = {
|
|
34
36
|
Data: {},
|
|
@@ -160,6 +162,34 @@ const MenuDefault = {
|
|
|
160
162
|
handleContainerClass: 'handle-btn-container',
|
|
161
163
|
tooltipHtml: await Badge.Render(buildBadgeToolTipMenuOption('500')),
|
|
162
164
|
})}
|
|
165
|
+
${await BtnIcon.Render({
|
|
166
|
+
class: 'in wfa main-btn-menu main-btn-blog',
|
|
167
|
+
label: renderMenuLabel({
|
|
168
|
+
icon: html`<i class="fa-solid fa-file-invoice"></i>`,
|
|
169
|
+
text: html`<span class="menu-label-text">${Translate.Render('blog')}</span>`,
|
|
170
|
+
}),
|
|
171
|
+
attrs: `data-id="blog"`,
|
|
172
|
+
tabHref: `${getProxyPath()}blog`,
|
|
173
|
+
handleContainerClass: 'handle-btn-container',
|
|
174
|
+
tooltipHtml: await Badge.Render(buildBadgeToolTipMenuOption('blog')),
|
|
175
|
+
})}
|
|
176
|
+
${await BtnIcon.Render({
|
|
177
|
+
class: 'in wfa main-btn-menu main-btn-chat',
|
|
178
|
+
label: html`${renderMenuLabel({
|
|
179
|
+
icon: html`<i class="far fa-comments"></i>`,
|
|
180
|
+
text: html`<span class="menu-label-text">${Translate.Render('chat')}</span>`,
|
|
181
|
+
})}
|
|
182
|
+
${await Badge.Render({
|
|
183
|
+
id: 'main-btn-chat',
|
|
184
|
+
type: 'circle-red',
|
|
185
|
+
style: badgeNotificationMenuStyle,
|
|
186
|
+
classList: 'hide',
|
|
187
|
+
})}`,
|
|
188
|
+
attrs: `data-id="chat"`,
|
|
189
|
+
tabHref: `${getProxyPath()}chat`,
|
|
190
|
+
handleContainerClass: 'handle-btn-container',
|
|
191
|
+
tooltipHtml: await Badge.Render(buildBadgeToolTipMenuOption('chat')),
|
|
192
|
+
})}
|
|
163
193
|
</div>
|
|
164
194
|
`,
|
|
165
195
|
barConfig: newInstance(barConfig),
|
|
@@ -181,47 +211,7 @@ const MenuDefault = {
|
|
|
181
211
|
RouterInstance,
|
|
182
212
|
heightTopBar,
|
|
183
213
|
heightBottomBar,
|
|
184
|
-
htmlMainBody:
|
|
185
|
-
setTimeout(() => {
|
|
186
|
-
EventsUI.onClick('.get-started-button', (e) => {
|
|
187
|
-
e.preventDefault();
|
|
188
|
-
location.href = `https://www.nexodev.org/docs/?cid=src`;
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
return html`
|
|
192
|
-
<div class="landing-container">
|
|
193
|
-
<div class="content-wrapper">
|
|
194
|
-
<h1 class="animated-text">
|
|
195
|
-
<span class="greeting">Hello, World!</span>
|
|
196
|
-
<span class="subtitle">Welcome to Our Platform</span>
|
|
197
|
-
</h1>
|
|
198
|
-
|
|
199
|
-
<div class="features">
|
|
200
|
-
<div class="feature-card">
|
|
201
|
-
<i class="icon">🚀</i>
|
|
202
|
-
<h3>Fast & Reliable</h3>
|
|
203
|
-
<p>Lightning-fast performance with 99.9% uptime</p>
|
|
204
|
-
</div>
|
|
205
|
-
<div class="feature-card">
|
|
206
|
-
<i class="icon">🎨</i>
|
|
207
|
-
<h3>Beautiful UI</h3>
|
|
208
|
-
<p>Modern and intuitive user interface</p>
|
|
209
|
-
</div>
|
|
210
|
-
<div class="feature-card">
|
|
211
|
-
<i class="icon">⚡</i>
|
|
212
|
-
<h3>Powerful Features</h3>
|
|
213
|
-
<p>Everything you need in one place</p>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
|
|
217
|
-
<button class="cta-button get-started-button">
|
|
218
|
-
Get Started
|
|
219
|
-
<span class="button-icon">→</span>
|
|
220
|
-
</button>
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
`;
|
|
224
|
-
},
|
|
214
|
+
htmlMainBody: options.htmlMainBody,
|
|
225
215
|
});
|
|
226
216
|
|
|
227
217
|
ThemeEvents['main-theme-handler'] = () => {
|
|
@@ -626,6 +616,7 @@ const MenuDefault = {
|
|
|
626
616
|
RouterInstance,
|
|
627
617
|
heightTopBar,
|
|
628
618
|
heightBottomBar,
|
|
619
|
+
observer: true,
|
|
629
620
|
});
|
|
630
621
|
});
|
|
631
622
|
|
|
@@ -672,6 +663,68 @@ const MenuDefault = {
|
|
|
672
663
|
observer: true,
|
|
673
664
|
});
|
|
674
665
|
});
|
|
666
|
+
|
|
667
|
+
EventsUI.onClick(`.main-btn-blog`, async () => {
|
|
668
|
+
const { barConfig } = await Themes[Css.currentTheme]();
|
|
669
|
+
const idModal = 'modal-blog';
|
|
670
|
+
const routeModal = 'blog';
|
|
671
|
+
const idEvent = `form-panel-${idModal}`;
|
|
672
|
+
await Modal.Render({
|
|
673
|
+
id: idModal,
|
|
674
|
+
route: routeModal,
|
|
675
|
+
barConfig,
|
|
676
|
+
title: renderViewTitle({
|
|
677
|
+
icon: html`<i class="fa-solid fa-file-invoice"></i>`,
|
|
678
|
+
text: Translate.Render('blog'),
|
|
679
|
+
}),
|
|
680
|
+
observer: true,
|
|
681
|
+
html: async () => {
|
|
682
|
+
setTimeout(async () => {
|
|
683
|
+
await PanelForm.instance({
|
|
684
|
+
idPanel: 'default-blog',
|
|
685
|
+
heightTopBar,
|
|
686
|
+
heightBottomBar,
|
|
687
|
+
defaultUrlImage: `${getProxyPath()}android-chrome-96x96.png`,
|
|
688
|
+
Elements: ElementsDefault,
|
|
689
|
+
parentIdModal: idModal,
|
|
690
|
+
scrollClassContainer: `html-${idModal}`,
|
|
691
|
+
route: routeModal,
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
},
|
|
695
|
+
handleType: 'bar',
|
|
696
|
+
maximize: true,
|
|
697
|
+
mode: 'view',
|
|
698
|
+
slideMenu: 'modal-menu',
|
|
699
|
+
RouterInstance,
|
|
700
|
+
heightTopBar,
|
|
701
|
+
heightBottomBar,
|
|
702
|
+
barMode,
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
EventsUI.onClick(`.main-btn-chat`, async () => {
|
|
707
|
+
const { barConfig } = await Themes[Css.currentTheme]();
|
|
708
|
+
await Modal.Render({
|
|
709
|
+
id: 'modal-chat',
|
|
710
|
+
route: 'chat',
|
|
711
|
+
barConfig,
|
|
712
|
+
title: renderViewTitle({
|
|
713
|
+
icon: html` <i class="far fa-comments"></i>`,
|
|
714
|
+
text: Translate.Render('chat'),
|
|
715
|
+
}),
|
|
716
|
+
html: async () => await Chat.Render({ idModal: 'modal-chat' }),
|
|
717
|
+
handleType: 'bar',
|
|
718
|
+
maximize: true,
|
|
719
|
+
observer: true,
|
|
720
|
+
mode: 'view',
|
|
721
|
+
slideMenu: 'modal-menu',
|
|
722
|
+
RouterInstance,
|
|
723
|
+
heightTopBar,
|
|
724
|
+
heightBottomBar,
|
|
725
|
+
barMode,
|
|
726
|
+
});
|
|
727
|
+
});
|
|
675
728
|
},
|
|
676
729
|
};
|
|
677
730
|
|
|
@@ -27,6 +27,8 @@ const RoutesDefault = () => {
|
|
|
27
27
|
render: () => s(`.main-btn-account`).click(),
|
|
28
28
|
},
|
|
29
29
|
'/docs': { title: 'docs', render: () => s(`.main-btn-docs`).click() },
|
|
30
|
+
'/chat': { title: 'docs', render: () => s(`.main-btn-chat`).click() },
|
|
31
|
+
'/blog': { title: 'docs', render: () => s(`.main-btn-blog`).click() },
|
|
30
32
|
'/recover': { title: 'recover', render: () => s(`.main-btn-recover`).click() },
|
|
31
33
|
'/default-management': {
|
|
32
34
|
title: 'default-management',
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Auth } from '../../components/core/Auth.js';
|
|
2
|
+
import { loggerFactory } from '../../components/core/Logger.js';
|
|
3
|
+
import { getApiBaseUrl, headersFactory, payloadFactory } from '../core/core.service.js';
|
|
4
|
+
|
|
5
|
+
const logger = loggerFactory(import.meta);
|
|
6
|
+
|
|
7
|
+
logger.info('Load service');
|
|
8
|
+
|
|
9
|
+
const endpoint = 'document';
|
|
10
|
+
|
|
11
|
+
const DocumentService = {
|
|
12
|
+
post: (options = { id: '', body: {} }) =>
|
|
13
|
+
new Promise((resolve, reject) =>
|
|
14
|
+
fetch(getApiBaseUrl({ id: options.id, endpoint }), {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: headersFactory(),
|
|
17
|
+
credentials: 'include',
|
|
18
|
+
body: payloadFactory(options.body),
|
|
19
|
+
})
|
|
20
|
+
.then(async (res) => {
|
|
21
|
+
return await res.json();
|
|
22
|
+
})
|
|
23
|
+
.then((res) => {
|
|
24
|
+
logger.info(res);
|
|
25
|
+
return resolve(res);
|
|
26
|
+
})
|
|
27
|
+
.catch((error) => {
|
|
28
|
+
logger.error(error);
|
|
29
|
+
return reject(error);
|
|
30
|
+
}),
|
|
31
|
+
),
|
|
32
|
+
get: (options = { id: '' }) =>
|
|
33
|
+
new Promise((resolve, reject) => {
|
|
34
|
+
const url = new URL(getApiBaseUrl({ id: options.id, endpoint }));
|
|
35
|
+
if (options.params) {
|
|
36
|
+
Object.keys(options.params).forEach((key) => url.searchParams.append(key, options.params[key]));
|
|
37
|
+
}
|
|
38
|
+
fetch(url, {
|
|
39
|
+
method: 'GET',
|
|
40
|
+
headers: headersFactory(),
|
|
41
|
+
credentials: 'include',
|
|
42
|
+
})
|
|
43
|
+
.then(async (res) => {
|
|
44
|
+
return await res.json();
|
|
45
|
+
})
|
|
46
|
+
.then((res) => {
|
|
47
|
+
logger.info(res);
|
|
48
|
+
return resolve(res);
|
|
49
|
+
})
|
|
50
|
+
.catch((error) => {
|
|
51
|
+
logger.error(error);
|
|
52
|
+
return reject(error);
|
|
53
|
+
});
|
|
54
|
+
}),
|
|
55
|
+
delete: (options = { id: '', body: {} }) =>
|
|
56
|
+
new Promise((resolve, reject) =>
|
|
57
|
+
fetch(getApiBaseUrl({ id: options.id, endpoint }), {
|
|
58
|
+
method: 'DELETE',
|
|
59
|
+
headers: headersFactory(),
|
|
60
|
+
credentials: 'include',
|
|
61
|
+
body: payloadFactory(options.body),
|
|
62
|
+
})
|
|
63
|
+
.then(async (res) => {
|
|
64
|
+
return await res.json();
|
|
65
|
+
})
|
|
66
|
+
.then((res) => {
|
|
67
|
+
logger.info(res);
|
|
68
|
+
return resolve(res);
|
|
69
|
+
})
|
|
70
|
+
.catch((error) => {
|
|
71
|
+
logger.error(error);
|
|
72
|
+
return reject(error);
|
|
73
|
+
}),
|
|
74
|
+
),
|
|
75
|
+
put: (options = { id: '', body: {} }) =>
|
|
76
|
+
new Promise((resolve, reject) =>
|
|
77
|
+
fetch(getApiBaseUrl({ id: options.id, endpoint }), {
|
|
78
|
+
method: 'PUT',
|
|
79
|
+
headers: headersFactory(),
|
|
80
|
+
credentials: 'include',
|
|
81
|
+
body: payloadFactory(options.body),
|
|
82
|
+
})
|
|
83
|
+
.then(async (res) => {
|
|
84
|
+
return await res.json();
|
|
85
|
+
})
|
|
86
|
+
.then((res) => {
|
|
87
|
+
logger.info(res);
|
|
88
|
+
return resolve(res);
|
|
89
|
+
})
|
|
90
|
+
.catch((error) => {
|
|
91
|
+
logger.error(error);
|
|
92
|
+
return reject(error);
|
|
93
|
+
}),
|
|
94
|
+
),
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export { DocumentService };
|
|
@@ -33,6 +33,7 @@ const FileService = {
|
|
|
33
33
|
fetch(getApiBaseUrl({ id: options.id, endpoint }), {
|
|
34
34
|
method: 'GET',
|
|
35
35
|
headers: headersFactory(),
|
|
36
|
+
credentials: 'include',
|
|
36
37
|
})
|
|
37
38
|
.then(async (res) => {
|
|
38
39
|
return await res.json();
|
|
@@ -51,6 +52,7 @@ const FileService = {
|
|
|
51
52
|
fetch(getApiBaseUrl({ id: options.id, endpoint }), {
|
|
52
53
|
method: 'DELETE',
|
|
53
54
|
headers: headersFactory(),
|
|
55
|
+
credentials: 'include',
|
|
54
56
|
body: payloadFactory(options.body),
|
|
55
57
|
})
|
|
56
58
|
.then(async (res) => {
|
package/src/client/ssr/Render.js
CHANGED
|
@@ -5,7 +5,7 @@ SrrComponent = ({ title, ssrPath, buildId, ssrHeadComponents, ssrBodyComponents,
|
|
|
5
5
|
<title>${title}</title>
|
|
6
6
|
<link rel="icon" type="image/x-icon" href="${ssrPath}favicon.ico" />
|
|
7
7
|
<meta charset="UTF-8" />
|
|
8
|
-
<meta name="viewport" content="
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
9
|
<script>
|
|
10
10
|
window.renderPayload = ${renderApi.JSONweb(renderPayload)};
|
|
11
11
|
</script>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
SrrComponent = ({ ssrPath }) => html`
|
|
2
2
|
<script type="text/javascript" src="${ssrPath}dist/validator/validator.min.js"></script>
|
|
3
3
|
<script type="text/javascript" src="${ssrPath}dist/ag-grid-community/ag-grid-community.min.js"></script>
|
|
4
|
+
<script type="text/javascript" src="${ssrPath}dist/easymde/easymde.min.js"></script>
|
|
5
|
+
<link rel="stylesheet" href="${ssrPath}dist/easymde/easymde.min.css" />
|
|
4
6
|
`;
|
|
@@ -7,6 +7,7 @@ SrrComponent = ({ title, author, keywords, description, themeColor, ssrPath, can
|
|
|
7
7
|
<meta name="theme-color" content="${themeColor}" />
|
|
8
8
|
|
|
9
9
|
<meta property="og:title" content="${title}" />
|
|
10
|
+
<meta property="og:type" content="website" />
|
|
10
11
|
<meta property="og:description" content="${description}" />
|
|
11
12
|
<meta property="og:image" content="${thumbnail}" />
|
|
12
13
|
<meta property="og:url" content="${canonicalURL}" />
|