@underpostnet/underpost 2.97.0 → 2.97.5

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 (78) hide show
  1. package/README.md +2 -2
  2. package/baremetal/commission-workflows.json +33 -3
  3. package/bin/deploy.js +1 -1
  4. package/cli.md +7 -2
  5. package/conf.js +3 -0
  6. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  7. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  8. package/package.json +1 -1
  9. package/packer/scripts/fuse-tar-root +3 -3
  10. package/scripts/disk-clean.sh +23 -23
  11. package/scripts/gpu-diag.sh +2 -2
  12. package/scripts/ip-info.sh +11 -11
  13. package/scripts/maas-upload-boot-resource.sh +1 -1
  14. package/scripts/nvim.sh +1 -1
  15. package/scripts/packer-setup.sh +13 -13
  16. package/scripts/rocky-setup.sh +2 -2
  17. package/scripts/rpmfusion-ffmpeg-setup.sh +4 -4
  18. package/scripts/ssl.sh +7 -7
  19. package/src/api/core/core.service.js +0 -5
  20. package/src/api/default/default.service.js +7 -5
  21. package/src/api/document/document.model.js +30 -1
  22. package/src/api/document/document.router.js +6 -0
  23. package/src/api/document/document.service.js +423 -51
  24. package/src/api/file/file.model.js +112 -4
  25. package/src/api/file/file.ref.json +42 -0
  26. package/src/api/file/file.service.js +380 -32
  27. package/src/api/user/user.model.js +38 -1
  28. package/src/api/user/user.router.js +96 -63
  29. package/src/api/user/user.service.js +81 -48
  30. package/src/cli/baremetal.js +689 -329
  31. package/src/cli/cluster.js +50 -52
  32. package/src/cli/db.js +424 -166
  33. package/src/cli/deploy.js +1 -1
  34. package/src/cli/index.js +12 -1
  35. package/src/cli/lxd.js +3 -3
  36. package/src/cli/repository.js +1 -1
  37. package/src/cli/run.js +2 -1
  38. package/src/cli/ssh.js +10 -10
  39. package/src/client/components/core/Account.js +327 -36
  40. package/src/client/components/core/AgGrid.js +3 -0
  41. package/src/client/components/core/Auth.js +9 -3
  42. package/src/client/components/core/Chat.js +2 -2
  43. package/src/client/components/core/Content.js +159 -78
  44. package/src/client/components/core/Css.js +16 -2
  45. package/src/client/components/core/CssCore.js +16 -12
  46. package/src/client/components/core/FileExplorer.js +115 -8
  47. package/src/client/components/core/Input.js +204 -11
  48. package/src/client/components/core/LogIn.js +42 -20
  49. package/src/client/components/core/Modal.js +257 -177
  50. package/src/client/components/core/Panel.js +324 -27
  51. package/src/client/components/core/PanelForm.js +280 -73
  52. package/src/client/components/core/PublicProfile.js +888 -0
  53. package/src/client/components/core/Router.js +117 -15
  54. package/src/client/components/core/SearchBox.js +1117 -0
  55. package/src/client/components/core/SignUp.js +26 -7
  56. package/src/client/components/core/SocketIo.js +6 -3
  57. package/src/client/components/core/Translate.js +98 -0
  58. package/src/client/components/core/Validator.js +15 -0
  59. package/src/client/components/core/windowGetDimensions.js +6 -6
  60. package/src/client/components/default/MenuDefault.js +59 -12
  61. package/src/client/components/default/RoutesDefault.js +1 -0
  62. package/src/client/services/core/core.service.js +163 -1
  63. package/src/client/services/default/default.management.js +451 -64
  64. package/src/client/services/default/default.service.js +13 -6
  65. package/src/client/services/document/document.service.js +23 -0
  66. package/src/client/services/file/file.service.js +43 -16
  67. package/src/client/services/user/user.service.js +13 -9
  68. package/src/db/DataBaseProvider.js +1 -1
  69. package/src/db/mongo/MongooseDB.js +1 -1
  70. package/src/index.js +1 -1
  71. package/src/mailer/MailerProvider.js +4 -4
  72. package/src/runtime/express/Express.js +2 -1
  73. package/src/runtime/lampp/Lampp.js +2 -2
  74. package/src/server/auth.js +3 -6
  75. package/src/server/data-query.js +449 -0
  76. package/src/server/dns.js +4 -4
  77. package/src/server/object-layer.js +0 -3
  78. package/src/ws/IoInterface.js +2 -2
@@ -2,8 +2,8 @@ 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';
5
- import { darkTheme, ThemeEvents } from './Css.js';
6
- import { append, copyData, getDataFromInputFile, htmls, s } from './VanillaJs.js';
5
+ import { darkTheme, ThemeEvents, subThemeManager, lightenHex, darkenHex } from './Css.js';
6
+ import { append, copyData, getDataFromInputFile, htmls, s, sa } from './VanillaJs.js';
7
7
  import { BtnIcon } from './BtnIcon.js';
8
8
  import { Translate } from './Translate.js';
9
9
  import { DropDown } from './DropDown.js';
@@ -16,6 +16,9 @@ import { Badge } from './Badge.js';
16
16
  import { Content } from './Content.js';
17
17
  import { DocumentService } from '../../services/document/document.service.js';
18
18
  import { NotificationManager } from './NotificationManager.js';
19
+ import { getApiBaseUrl } from '../../services/core/core.service.js';
20
+ import { getProxyPath, setQueryPath, navigateToProfile } from './Router.js';
21
+ import { PublicProfile } from './PublicProfile.js';
19
22
 
20
23
  const logger = loggerFactory(import.meta);
21
24
 
@@ -35,6 +38,7 @@ const Panel = {
35
38
  share: {
36
39
  copyLink: false,
37
40
  },
41
+ showCreatorProfile: false,
38
42
  },
39
43
  ) {
40
44
  const idPanel = options?.idPanel ? options.idPanel : getId(this.Tokens, `${idPanel}-`);
@@ -195,7 +199,7 @@ const Panel = {
195
199
 
196
200
  // Clear previous form values then populate with the current item's data
197
201
  Input.cleanValues(formData);
198
- Input.setValues(formData, obj, foundOrigin, foundFiles);
202
+ await Input.setValues(formData, obj, foundOrigin, foundFiles);
199
203
  if (options.on.initEdit) await options.on.initEdit({ data: obj });
200
204
  });
201
205
  s(`.a-${payload._id}`).onclick = async (e) => {
@@ -206,8 +210,75 @@ const Panel = {
206
210
  e.preventDefault();
207
211
  // if (options.onClick) await options.onClick({ payload });
208
212
  };
213
+
214
+ // Add theme change handler for creator profile header
215
+ if (options.showCreatorProfile && obj.userInfo) {
216
+ const updateCreatorProfileTheme = () => {
217
+ const profileHeader = s(`.creator-profile-header-${id}`);
218
+ if (profileHeader) {
219
+ profileHeader.style.borderBottom = `1px solid ${darkTheme ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)'}`;
220
+ profileHeader.style.background = `${darkTheme ? 'rgba(255,255,255,0.02)' : 'rgba(0,0,0,0.02)'}`;
221
+
222
+ // Update avatar border if it's an image
223
+ const avatarImg = profileHeader.querySelector('.creator-avatar');
224
+ if (avatarImg && avatarImg.tagName === 'IMG') {
225
+ avatarImg.style.border = `2px solid ${darkTheme ? 'rgba(102, 126, 234, 0.5)' : 'rgba(102, 126, 234, 0.3)'}`;
226
+ }
227
+
228
+ // Update username color
229
+ const username = profileHeader.querySelector('.creator-username');
230
+ if (username) {
231
+ username.style.color = `${darkTheme ? 'rgba(255,255,255,0.9)' : 'rgba(0,0,0,0.85)'}`;
232
+ }
233
+
234
+ // Update "Creator" label color
235
+ const creatorLabel = username?.nextElementSibling;
236
+ if (creatorLabel) {
237
+ creatorLabel.style.color = `${darkTheme ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.45)'}`;
238
+ }
239
+ }
240
+ };
241
+
242
+ // Register theme change handler
243
+ const profileThemeHandlerId = `${id}-creator-profile-theme`;
244
+ ThemeEvents[profileThemeHandlerId] = updateCreatorProfileTheme;
245
+
246
+ // Add click handlers for public profile links
247
+ setTimeout(() => {
248
+ const links = sa(`.creator-profile-link-${id}`);
249
+ links.forEach((link) => {
250
+ link.onclick = async (e) => {
251
+ e.preventDefault();
252
+ const username = link.getAttribute('data-id');
253
+ // Check if public profile modal is already open
254
+ const currentModal = s('.modal-public-profile');
255
+ if (currentModal) {
256
+ // Modal is already open, update the profile content dynamically
257
+ // Navigate to clean URL without intermediate ?cid= in history
258
+ navigateToProfile(username, { replace: false });
259
+ await PublicProfile.Update({
260
+ idModal: 'modal-public-profile',
261
+ user: { username },
262
+ });
263
+ } else {
264
+ // Modal is not open, navigate to clean URL and open modal
265
+ navigateToProfile(username, { replace: false });
266
+ if (s('.main-btn-public-profile')) s('.main-btn-public-profile').click();
267
+ }
268
+ };
269
+ });
270
+ });
271
+ }
209
272
  });
210
273
  if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
274
+
275
+ // Check if document is public (from obj.isPublic field)
276
+ const isPublic = obj.isPublic === true;
277
+ // Visibility icon: globe for public, padlock for private
278
+ const visibilityIcon = isPublic
279
+ ? '<i class="fas fa-globe" title="Public document"></i>'
280
+ : '<i class="fas fa-lock" title="Private document"></i>';
281
+
211
282
  return html` <div class="in box-shadow ${idPanel} ${idPanel}-${id}" style="position: relative;">
212
283
  <div class="fl ${idPanel}-tools session-fl-log-in ${obj.tools ? '' : 'hide'}">
213
284
  ${await BtnIcon.Render({
@@ -234,6 +305,60 @@ const Panel = {
234
305
  })}
235
306
  </div>
236
307
  <div class="in container-${idPanel}-${id}">
308
+ <div class="panel-visibility-icon">${visibilityIcon}</div>
309
+ ${options.showCreatorProfile && obj.userInfo
310
+ ? html`<div
311
+ class="creator-profile-header creator-profile-header-${id}"
312
+ style="padding: 10px 12px; margin-bottom: 10px; border-bottom: 1px solid ${darkTheme
313
+ ? 'rgba(255,255,255,0.1)'
314
+ : 'rgba(0,0,0,0.08)'}; display: flex; align-items: center; gap: 10px; background: ${darkTheme
315
+ ? 'rgba(255,255,255,0.02)'
316
+ : 'rgba(0,0,0,0.02)'}; border-radius: 4px 4px 0 0;"
317
+ >
318
+ <a
319
+ href="${getProxyPath()}u/${obj.userInfo.username}"
320
+ class="creator-profile-link-${id}"
321
+ data-id="${obj.userInfo.username}"
322
+ style="display: flex;"
323
+ >
324
+ ${obj.userInfo.profileImageId && obj.userInfo.profileImageId._id
325
+ ? html`<img
326
+ class="creator-avatar"
327
+ src="${getApiBaseUrl({ id: obj.userInfo.profileImageId._id, endpoint: 'file/blob' })}"
328
+ alt="${obj.userInfo.username}"
329
+ style="width: 36px; height: 36px; border-radius: 50%; object-fit: cover; border: 2px solid ${darkTheme
330
+ ? 'rgba(102, 126, 234, 0.5)'
331
+ : 'rgba(102, 126, 234, 0.3)'}; flex-shrink: 0; box-shadow: 0 2px 8px rgba(0,0,0,0.15);"
332
+ title="${obj.userInfo.username}"
333
+ />`
334
+ : html`<div
335
+ class="creator-avatar"
336
+ style="width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 16px; flex-shrink: 0; box-shadow: 0 2px 8px rgba(0,0,0,0.15);"
337
+ title="${obj.userInfo.username}"
338
+ >
339
+ ${(obj.userInfo.username || 'U').charAt(0).toUpperCase()}
340
+ </div>`}
341
+ </a>
342
+ <div style="display: flex; flex-direction: column; min-width: 0; flex: 1;">
343
+ <a
344
+ href="${getProxyPath()}u/${obj.userInfo.username}"
345
+ class="creator-username creator-profile-link-${id}"
346
+ data-id="${obj.userInfo.username}"
347
+ style="font-size: 14px; font-weight: 600; color: ${darkTheme
348
+ ? 'rgba(255,255,255,0.9)'
349
+ : 'rgba(0,0,0,0.85)'}; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
350
+ >
351
+ ${obj.userInfo.username || obj.userInfo.email || 'Unknown'}
352
+ </a>
353
+ <span
354
+ style="font-size: 11px; color: ${darkTheme
355
+ ? 'rgba(255,255,255,0.5)'
356
+ : 'rgba(0,0,0,0.45)'}; line-height: 1.3; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 500;"
357
+ >${obj.userInfo.briefDescription || 'Uploader'}</span
358
+ >
359
+ </div>
360
+ </div>`
361
+ : ''}
237
362
  <div class="in ${idPanel}-head">
238
363
  <div class="in ${idPanel}-title">
239
364
  ${options.titleIcon}
@@ -263,18 +388,79 @@ const Panel = {
263
388
  }
264
389
 
265
390
  if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'tags')) {
266
- setTimeout(async () => {
391
+ // Function to render tags with current theme
392
+ const renderTags = async () => {
267
393
  let tagRender = html``;
268
394
  for (const tag of obj[infoKey]) {
395
+ // Use subThemeManager colors for consistent theming
396
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
397
+ const hasThemeColor = themeColor && themeColor !== null;
398
+
399
+ let tagBg, tagColor;
400
+ if (darkTheme) {
401
+ tagBg = hasThemeColor ? darkenHex(themeColor, 0.6) : '#4a4a4a';
402
+ tagColor = hasThemeColor ? lightenHex(themeColor, 0.7) : '#ffffff';
403
+ } else {
404
+ tagBg = hasThemeColor ? lightenHex(themeColor, 0.7) : '#a2a2a2';
405
+ tagColor = hasThemeColor ? darkenHex(themeColor, 0.5) : '#ffffff';
406
+ }
407
+
269
408
  tagRender += await Badge.Render({
270
409
  text: tag,
271
- style: { color: 'white' },
272
- classList: 'inl',
273
- style: { margin: '3px', background: `#a2a2a2` },
410
+ style: { color: tagColor },
411
+ classList: 'inl panel-tag-clickable',
412
+ style: {
413
+ margin: '3px',
414
+ background: tagBg,
415
+ color: tagColor,
416
+ cursor: 'pointer',
417
+ transition: 'all 0.2s ease',
418
+ },
274
419
  });
275
420
  }
276
- if (s(`.tag-render-${id}`)) htmls(`.tag-render-${id}`, tagRender);
277
- });
421
+ if (s(`.tag-render-${id}`)) {
422
+ htmls(`.tag-render-${id}`, tagRender);
423
+
424
+ // Add click handlers to tags for search integration
425
+ setTimeout(() => {
426
+ const tagElements = sa(`.tag-render-${id} .panel-tag-clickable`);
427
+ tagElements.forEach((tagEl) => {
428
+ tagEl.onclick = (e) => {
429
+ e.stopPropagation();
430
+ const tagText = tagEl.textContent.trim();
431
+
432
+ // Open search bar if closed
433
+ if (
434
+ !s('.main-body-btn-ui-bar-custom-open').classList.contains('hide') ||
435
+ !s(`.main-body-btn-ui-open`).classList.contains('hide')
436
+ )
437
+ s('.main-body-btn-bar-custom').click();
438
+
439
+ // Find and populate search box if it exists
440
+ const searchBox = s('.top-bar-search-box');
441
+ if (searchBox) {
442
+ searchBox.value = tagText;
443
+ searchBox.focus();
444
+
445
+ // Trigger input event to start search
446
+ const inputEvent = new Event('input', { bubbles: true });
447
+ searchBox.dispatchEvent(inputEvent);
448
+
449
+ logger.info(`Tag clicked: ${tagText} - search triggered`);
450
+ }
451
+ };
452
+ });
453
+ }, 100);
454
+ }
455
+ };
456
+
457
+ // Initial render
458
+ setTimeout(renderTags);
459
+
460
+ // Add theme change handler for this tag set
461
+ const tagThemeHandlerId = `${id}-tags-${infoKey}-theme`;
462
+ ThemeEvents[tagThemeHandlerId] = renderTags;
463
+
278
464
  return html``;
279
465
  }
280
466
  {
@@ -569,15 +755,16 @@ const Panel = {
569
755
  s(`.btn-${idPanel}-clean`).onclick = () => {
570
756
  Input.cleanValues(formData);
571
757
  };
572
- s(`.btn-${idPanel}-clean-file`).onclick = () => {
573
- // Clear file input specifically
574
- const fileFormData = formData.find((f) => f.inputType === 'file');
575
- if (fileFormData && s(`.${fileFormData.id}`)) {
576
- s(`.${fileFormData.id}`).value = '';
577
- s(`.${fileFormData.id}`).inputFiles = null;
578
- htmls(`.file-name-render-${fileFormData.id}`, `${fileNameInputExtDefaultContent}`);
579
- }
580
- };
758
+ if (s(`.btn-${idPanel}-clean-file`))
759
+ s(`.btn-${idPanel}-clean-file`).onclick = () => {
760
+ // Clear file input specifically
761
+ const fileFormData = formData.find((f) => f.inputType === 'file');
762
+ if (fileFormData && s(`.${fileFormData.id}`)) {
763
+ s(`.${fileFormData.id}`).value = '';
764
+ s(`.${fileFormData.id}`).inputFiles = null;
765
+ htmls(`.file-name-render-${fileFormData.id}`, `${fileNameInputExtDefaultContent}`);
766
+ }
767
+ };
581
768
  s(`.btn-${idPanel}-close`).onclick = (e) => {
582
769
  e.preventDefault();
583
770
  s(`.${idPanel}-form-body`).style.opacity = 0;
@@ -662,6 +849,29 @@ const Panel = {
662
849
  ? getDarkStyles(idPanel, scrollClassContainer)
663
850
  : getLightStyles(idPanel, scrollClassContainer);
664
851
  }
852
+
853
+ // Update tag hover styles
854
+ const tagStyleElement = s(`.${idPanel}-tag-styles`);
855
+ if (tagStyleElement) {
856
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
857
+ const hasThemeColor = themeColor && themeColor !== null;
858
+ let hoverBg;
859
+ if (darkTheme) {
860
+ hoverBg = hasThemeColor ? darkenHex(themeColor, 0.5) : '#5a5a5a';
861
+ } else {
862
+ hoverBg = hasThemeColor ? lightenHex(themeColor, 0.6) : '#8a8a8a';
863
+ }
864
+
865
+ tagStyleElement.textContent = css`
866
+ .panel-tag-clickable:hover {
867
+ background: ${hoverBg} !important;
868
+ transform: scale(1.05);
869
+ }
870
+ .panel-tag-clickable:active {
871
+ transform: scale(0.98);
872
+ }
873
+ `;
874
+ }
665
875
  };
666
876
 
667
877
  // Add theme change listener
@@ -680,15 +890,39 @@ const Panel = {
680
890
  width: 100%;
681
891
  }
682
892
  .${idPanel}-title {
683
- color: rgba(109, 104, 255, 1);
893
+ color: ${(() => {
894
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
895
+ const hasThemeColor = themeColor && themeColor !== null;
896
+ if (hasThemeColor) {
897
+ return darkTheme ? lightenHex(themeColor, 0.3) : darkenHex(themeColor, 0.2);
898
+ } else {
899
+ return darkTheme ? '#8a85ff' : 'rgba(109, 104, 255, 1)';
900
+ }
901
+ })()};
684
902
  font-size: 24px;
685
903
  padding: 5px;
686
904
  }
687
905
  .a-title-${idPanel} {
688
- color: rgba(109, 104, 255, 1);
906
+ color: ${(() => {
907
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
908
+ const hasThemeColor = themeColor && themeColor !== null;
909
+ if (hasThemeColor) {
910
+ return darkTheme ? lightenHex(themeColor, 0.3) : darkenHex(themeColor, 0.2);
911
+ } else {
912
+ return darkTheme ? '#8a85ff' : 'rgba(109, 104, 255, 1)';
913
+ }
914
+ })()};
689
915
  }
690
916
  .a-title-${idPanel}:hover {
691
- color: #e89f4c;
917
+ color: ${(() => {
918
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
919
+ const hasThemeColor = themeColor && themeColor !== null;
920
+ if (hasThemeColor) {
921
+ return darkTheme ? lightenHex(themeColor, 0.5) : lightenHex(themeColor, 0.3);
922
+ } else {
923
+ return darkTheme ? '#ffb74d' : '#e89f4c';
924
+ }
925
+ })()};
692
926
  }
693
927
  .${idPanel}-row {
694
928
  padding: 5px;
@@ -705,6 +939,7 @@ const Panel = {
705
939
  margin-left: 10px;
706
940
  top: -7px;
707
941
  }
942
+
708
943
  .${idPanel}-row-key {
709
944
  }
710
945
  .${idPanel}-row-value {
@@ -765,6 +1000,23 @@ const Panel = {
765
1000
  }
766
1001
  </style>
767
1002
  <style class="${idPanel}-styles"></style>
1003
+ <style class="${idPanel}-tag-styles">
1004
+ .panel-tag-clickable:hover {
1005
+ background: ${(() => {
1006
+ const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
1007
+ const hasThemeColor = themeColor && themeColor !== null;
1008
+ if (darkTheme) {
1009
+ return hasThemeColor ? darkenHex(themeColor, 0.5) : '#5a5a5a';
1010
+ } else {
1011
+ return hasThemeColor ? lightenHex(themeColor, 0.6) : '#8a8a8a';
1012
+ }
1013
+ })()} !important;
1014
+ transform: scale(1.05);
1015
+ }
1016
+ .panel-tag-clickable:active {
1017
+ transform: scale(0.98);
1018
+ }
1019
+ </style>
768
1020
  <div class="${idPanel}-container">
769
1021
  <div class="in modal ${idPanel}-form-container ${options.formContainerClass ? options.formContainerClass : ''}">
770
1022
  <div class="in ${idPanel}-form-header">
@@ -856,6 +1108,19 @@ function getBaseStyles(idPanel, scrollClassContainer) {
856
1108
  .${idPanel}-dropdown {
857
1109
  min-height: 100px;
858
1110
  }
1111
+ .panel-visibility-icon {
1112
+ position: absolute;
1113
+ top: 34px;
1114
+ left: 0px;
1115
+ font-size: 14px;
1116
+ opacity: 0.7;
1117
+ transition: opacity 0.2s ease;
1118
+ pointer-events: none;
1119
+ z-index: 10;
1120
+ }
1121
+ .${idPanel}:hover .panel-visibility-icon {
1122
+ opacity: 1;
1123
+ }
859
1124
  `;
860
1125
  }
861
1126
 
@@ -872,15 +1137,27 @@ function getLightStyles(idPanel, scrollClassContainer) {
872
1137
  background: #ffffff;
873
1138
  }
874
1139
  .${idPanel}-title {
875
- color: rgba(109, 104, 255, 1);
1140
+ color: ${(() => {
1141
+ const themeColor = subThemeManager.lightColor;
1142
+ const hasThemeColor = themeColor && themeColor !== null;
1143
+ return hasThemeColor ? darkenHex(themeColor, 0.2) : 'rgba(109, 104, 255, 1)';
1144
+ })()};
876
1145
  font-size: 24px;
877
1146
  padding: 5px;
878
1147
  }
879
1148
  .a-title-${idPanel} {
880
- color: rgba(109, 104, 255, 1);
1149
+ color: ${(() => {
1150
+ const themeColor = subThemeManager.lightColor;
1151
+ const hasThemeColor = themeColor && themeColor !== null;
1152
+ return hasThemeColor ? darkenHex(themeColor, 0.2) : 'rgba(109, 104, 255, 1)';
1153
+ })()};
881
1154
  }
882
1155
  .a-title-${idPanel}:hover {
883
- color: #e89f4c;
1156
+ color: ${(() => {
1157
+ const themeColor = subThemeManager.lightColor;
1158
+ const hasThemeColor = themeColor && themeColor !== null;
1159
+ return hasThemeColor ? lightenHex(themeColor, 0.3) : '#e89f4c';
1160
+ })()};
884
1161
  }
885
1162
  .${idPanel}-row-pin-value {
886
1163
  font-size: 20px;
@@ -894,6 +1171,10 @@ function getLightStyles(idPanel, scrollClassContainer) {
894
1171
  color: #000000 !important;
895
1172
  font-size: 17px !important;
896
1173
  }
1174
+ .panel-visibility-icon .fa-globe,
1175
+ .panel-visibility-icon .fa-lock {
1176
+ color: #666;
1177
+ }
897
1178
  `;
898
1179
  }
899
1180
 
@@ -910,15 +1191,27 @@ function getDarkStyles(idPanel, scrollClassContainer) {
910
1191
  background: #3a3a3a;
911
1192
  }
912
1193
  .${idPanel}-title {
913
- color: #8a85ff;
1194
+ color: ${(() => {
1195
+ const themeColor = subThemeManager.darkColor;
1196
+ const hasThemeColor = themeColor && themeColor !== null;
1197
+ return hasThemeColor ? lightenHex(themeColor, 0.3) : '#8a85ff';
1198
+ })()};
914
1199
  font-size: 24px;
915
1200
  padding: 5px;
916
1201
  }
917
1202
  .a-title-${idPanel} {
918
- color: #8a85ff;
1203
+ color: ${(() => {
1204
+ const themeColor = subThemeManager.darkColor;
1205
+ const hasThemeColor = themeColor && themeColor !== null;
1206
+ return hasThemeColor ? lightenHex(themeColor, 0.3) : '#8a85ff';
1207
+ })()};
919
1208
  }
920
1209
  .a-title-${idPanel}:hover {
921
- color: #ffb74d;
1210
+ color: ${(() => {
1211
+ const themeColor = subThemeManager.darkColor;
1212
+ const hasThemeColor = themeColor && themeColor !== null;
1213
+ return hasThemeColor ? lightenHex(themeColor, 0.5) : '#ffb74d';
1214
+ })()};
922
1215
  }
923
1216
  .${idPanel}-row-pin-value {
924
1217
  font-size: 20px;
@@ -932,6 +1225,10 @@ function getDarkStyles(idPanel, scrollClassContainer) {
932
1225
  color: #ffffff !important;
933
1226
  font-size: 17px !important;
934
1227
  }
1228
+ .panel-visibility-icon .fa-globe,
1229
+ .panel-visibility-icon .fa-lock {
1230
+ color: #999;
1231
+ }
935
1232
  `;
936
1233
  }
937
1234