@underpostnet/underpost 2.97.0 → 2.97.1
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/README.md +2 -2
- package/baremetal/commission-workflows.json +33 -3
- package/bin/deploy.js +1 -1
- package/cli.md +5 -2
- package/conf.js +1 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/packer/scripts/fuse-tar-root +3 -3
- package/scripts/disk-clean.sh +23 -23
- package/scripts/gpu-diag.sh +2 -2
- package/scripts/ip-info.sh +11 -11
- package/scripts/maas-upload-boot-resource.sh +1 -1
- package/scripts/nvim.sh +1 -1
- package/scripts/packer-setup.sh +13 -13
- package/scripts/rocky-setup.sh +2 -2
- package/scripts/rpmfusion-ffmpeg-setup.sh +4 -4
- package/scripts/ssl.sh +7 -7
- package/src/api/document/document.model.js +30 -1
- package/src/api/document/document.router.js +1 -0
- package/src/api/document/document.service.js +339 -25
- package/src/cli/baremetal.js +689 -329
- package/src/cli/cluster.js +50 -52
- package/src/cli/deploy.js +1 -1
- package/src/cli/index.js +4 -1
- package/src/cli/lxd.js +3 -3
- package/src/cli/run.js +1 -1
- package/src/client/components/core/Css.js +16 -2
- package/src/client/components/core/Modal.js +125 -159
- package/src/client/components/core/Panel.js +276 -17
- package/src/client/components/core/PanelForm.js +24 -2
- package/src/client/components/core/SearchBox.js +801 -0
- package/src/client/services/document/document.service.js +23 -0
- package/src/index.js +1 -1
- package/src/server/dns.js +4 -4
|
@@ -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,7 @@ 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';
|
|
19
20
|
|
|
20
21
|
const logger = loggerFactory(import.meta);
|
|
21
22
|
|
|
@@ -35,6 +36,7 @@ const Panel = {
|
|
|
35
36
|
share: {
|
|
36
37
|
copyLink: false,
|
|
37
38
|
},
|
|
39
|
+
showCreatorProfile: false,
|
|
38
40
|
},
|
|
39
41
|
) {
|
|
40
42
|
const idPanel = options?.idPanel ? options.idPanel : getId(this.Tokens, `${idPanel}-`);
|
|
@@ -206,8 +208,49 @@ const Panel = {
|
|
|
206
208
|
e.preventDefault();
|
|
207
209
|
// if (options.onClick) await options.onClick({ payload });
|
|
208
210
|
};
|
|
211
|
+
|
|
212
|
+
// Add theme change handler for creator profile header
|
|
213
|
+
if (options.showCreatorProfile && obj.userInfo) {
|
|
214
|
+
const updateCreatorProfileTheme = () => {
|
|
215
|
+
const profileHeader = s(`.creator-profile-header-${id}`);
|
|
216
|
+
if (profileHeader) {
|
|
217
|
+
profileHeader.style.borderBottom = `1px solid ${darkTheme ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.08)'}`;
|
|
218
|
+
profileHeader.style.background = `${darkTheme ? 'rgba(255,255,255,0.02)' : 'rgba(0,0,0,0.02)'}`;
|
|
219
|
+
|
|
220
|
+
// Update avatar border if it's an image
|
|
221
|
+
const avatarImg = profileHeader.querySelector('.creator-avatar');
|
|
222
|
+
if (avatarImg && avatarImg.tagName === 'IMG') {
|
|
223
|
+
avatarImg.style.border = `2px solid ${darkTheme ? 'rgba(102, 126, 234, 0.5)' : 'rgba(102, 126, 234, 0.3)'}`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Update username color
|
|
227
|
+
const username = profileHeader.querySelector('.creator-username');
|
|
228
|
+
if (username) {
|
|
229
|
+
username.style.color = `${darkTheme ? 'rgba(255,255,255,0.9)' : 'rgba(0,0,0,0.85)'}`;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Update "Creator" label color
|
|
233
|
+
const creatorLabel = username?.nextElementSibling;
|
|
234
|
+
if (creatorLabel) {
|
|
235
|
+
creatorLabel.style.color = `${darkTheme ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.45)'}`;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Register theme change handler
|
|
241
|
+
const profileThemeHandlerId = `${id}-creator-profile-theme`;
|
|
242
|
+
ThemeEvents[profileThemeHandlerId] = updateCreatorProfileTheme;
|
|
243
|
+
}
|
|
209
244
|
});
|
|
210
245
|
if (s(`.${idPanel}-${id}`)) s(`.${idPanel}-${id}`).remove();
|
|
246
|
+
|
|
247
|
+
// Check if document is public (from obj.isPublic field)
|
|
248
|
+
const isPublic = obj.isPublic === true;
|
|
249
|
+
// Visibility icon: globe for public, padlock for private
|
|
250
|
+
const visibilityIcon = isPublic
|
|
251
|
+
? '<i class="fas fa-globe" title="Public document"></i>'
|
|
252
|
+
: '<i class="fas fa-lock" title="Private document"></i>';
|
|
253
|
+
|
|
211
254
|
return html` <div class="in box-shadow ${idPanel} ${idPanel}-${id}" style="position: relative;">
|
|
212
255
|
<div class="fl ${idPanel}-tools session-fl-log-in ${obj.tools ? '' : 'hide'}">
|
|
213
256
|
${await BtnIcon.Render({
|
|
@@ -234,6 +277,51 @@ const Panel = {
|
|
|
234
277
|
})}
|
|
235
278
|
</div>
|
|
236
279
|
<div class="in container-${idPanel}-${id}">
|
|
280
|
+
<div class="panel-visibility-icon">${visibilityIcon}</div>
|
|
281
|
+
${options.showCreatorProfile && obj.userInfo
|
|
282
|
+
? html`<div
|
|
283
|
+
class="creator-profile-header creator-profile-header-${id}"
|
|
284
|
+
style="padding: 10px 12px; margin-bottom: 10px; border-bottom: 1px solid ${darkTheme
|
|
285
|
+
? 'rgba(255,255,255,0.1)'
|
|
286
|
+
: 'rgba(0,0,0,0.08)'}; display: flex; align-items: center; gap: 10px; background: ${darkTheme
|
|
287
|
+
? 'rgba(255,255,255,0.02)'
|
|
288
|
+
: 'rgba(0,0,0,0.02)'}; border-radius: 4px 4px 0 0;"
|
|
289
|
+
>
|
|
290
|
+
${obj.userInfo.profileImageId && obj.userInfo.profileImageId._id
|
|
291
|
+
? html`<img
|
|
292
|
+
class="creator-avatar"
|
|
293
|
+
src="${getApiBaseUrl({ id: obj.userInfo.profileImageId._id, endpoint: 'file/blob' })}"
|
|
294
|
+
alt="${obj.userInfo.username || obj.userInfo.email}"
|
|
295
|
+
style="width: 36px; height: 36px; border-radius: 50%; object-fit: cover; border: 2px solid ${darkTheme
|
|
296
|
+
? 'rgba(102, 126, 234, 0.5)'
|
|
297
|
+
: 'rgba(102, 126, 234, 0.3)'}; flex-shrink: 0; box-shadow: 0 2px 8px rgba(0,0,0,0.15);"
|
|
298
|
+
title="${obj.userInfo.email || obj.userInfo.username}"
|
|
299
|
+
/>`
|
|
300
|
+
: html`<div
|
|
301
|
+
class="creator-avatar"
|
|
302
|
+
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);"
|
|
303
|
+
title="${obj.userInfo.email || obj.userInfo.username}"
|
|
304
|
+
>
|
|
305
|
+
${(obj.userInfo.username || obj.userInfo.email || 'U').charAt(0).toUpperCase()}
|
|
306
|
+
</div>`}
|
|
307
|
+
<div style="display: flex; flex-direction: column; min-width: 0; flex: 1;">
|
|
308
|
+
<span
|
|
309
|
+
class="creator-username"
|
|
310
|
+
style="font-size: 14px; font-weight: 600; color: ${darkTheme
|
|
311
|
+
? 'rgba(255,255,255,0.9)'
|
|
312
|
+
: 'rgba(0,0,0,0.85)'}; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
|
|
313
|
+
>
|
|
314
|
+
${obj.userInfo.username || obj.userInfo.email || 'Unknown'}
|
|
315
|
+
</span>
|
|
316
|
+
<span
|
|
317
|
+
style="font-size: 11px; color: ${darkTheme
|
|
318
|
+
? 'rgba(255,255,255,0.5)'
|
|
319
|
+
: 'rgba(0,0,0,0.45)'}; line-height: 1.3; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 500;"
|
|
320
|
+
>Creator</span
|
|
321
|
+
>
|
|
322
|
+
</div>
|
|
323
|
+
</div>`
|
|
324
|
+
: ''}
|
|
237
325
|
<div class="in ${idPanel}-head">
|
|
238
326
|
<div class="in ${idPanel}-title">
|
|
239
327
|
${options.titleIcon}
|
|
@@ -263,18 +351,79 @@ const Panel = {
|
|
|
263
351
|
}
|
|
264
352
|
|
|
265
353
|
if (formData.find((f) => f.model === infoKey && f.panel && f.panel.type === 'tags')) {
|
|
266
|
-
|
|
354
|
+
// Function to render tags with current theme
|
|
355
|
+
const renderTags = async () => {
|
|
267
356
|
let tagRender = html``;
|
|
268
357
|
for (const tag of obj[infoKey]) {
|
|
358
|
+
// Use subThemeManager colors for consistent theming
|
|
359
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
360
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
361
|
+
|
|
362
|
+
let tagBg, tagColor;
|
|
363
|
+
if (darkTheme) {
|
|
364
|
+
tagBg = hasThemeColor ? darkenHex(themeColor, 0.6) : '#4a4a4a';
|
|
365
|
+
tagColor = hasThemeColor ? lightenHex(themeColor, 0.7) : '#ffffff';
|
|
366
|
+
} else {
|
|
367
|
+
tagBg = hasThemeColor ? lightenHex(themeColor, 0.7) : '#a2a2a2';
|
|
368
|
+
tagColor = hasThemeColor ? darkenHex(themeColor, 0.5) : '#ffffff';
|
|
369
|
+
}
|
|
370
|
+
|
|
269
371
|
tagRender += await Badge.Render({
|
|
270
372
|
text: tag,
|
|
271
|
-
style: { color:
|
|
272
|
-
classList: 'inl',
|
|
273
|
-
style: {
|
|
373
|
+
style: { color: tagColor },
|
|
374
|
+
classList: 'inl panel-tag-clickable',
|
|
375
|
+
style: {
|
|
376
|
+
margin: '3px',
|
|
377
|
+
background: tagBg,
|
|
378
|
+
color: tagColor,
|
|
379
|
+
cursor: 'pointer',
|
|
380
|
+
transition: 'all 0.2s ease',
|
|
381
|
+
},
|
|
274
382
|
});
|
|
275
383
|
}
|
|
276
|
-
if (s(`.tag-render-${id}`))
|
|
277
|
-
|
|
384
|
+
if (s(`.tag-render-${id}`)) {
|
|
385
|
+
htmls(`.tag-render-${id}`, tagRender);
|
|
386
|
+
|
|
387
|
+
// Add click handlers to tags for search integration
|
|
388
|
+
setTimeout(() => {
|
|
389
|
+
const tagElements = sa(`.tag-render-${id} .panel-tag-clickable`);
|
|
390
|
+
tagElements.forEach((tagEl) => {
|
|
391
|
+
tagEl.onclick = (e) => {
|
|
392
|
+
e.stopPropagation();
|
|
393
|
+
const tagText = tagEl.textContent.trim();
|
|
394
|
+
|
|
395
|
+
// Open search bar if closed
|
|
396
|
+
if (
|
|
397
|
+
!s('.main-body-btn-ui-bar-custom-open').classList.contains('hide') ||
|
|
398
|
+
!s(`.main-body-btn-ui-open`).classList.contains('hide')
|
|
399
|
+
)
|
|
400
|
+
s('.main-body-btn-bar-custom').click();
|
|
401
|
+
|
|
402
|
+
// Find and populate search box if it exists
|
|
403
|
+
const searchBox = s('.top-bar-search-box');
|
|
404
|
+
if (searchBox) {
|
|
405
|
+
searchBox.value = tagText;
|
|
406
|
+
searchBox.focus();
|
|
407
|
+
|
|
408
|
+
// Trigger input event to start search
|
|
409
|
+
const inputEvent = new Event('input', { bubbles: true });
|
|
410
|
+
searchBox.dispatchEvent(inputEvent);
|
|
411
|
+
|
|
412
|
+
logger.info(`Tag clicked: ${tagText} - search triggered`);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
});
|
|
416
|
+
}, 100);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
// Initial render
|
|
421
|
+
setTimeout(renderTags);
|
|
422
|
+
|
|
423
|
+
// Add theme change handler for this tag set
|
|
424
|
+
const tagThemeHandlerId = `${id}-tags-${infoKey}-theme`;
|
|
425
|
+
ThemeEvents[tagThemeHandlerId] = renderTags;
|
|
426
|
+
|
|
278
427
|
return html``;
|
|
279
428
|
}
|
|
280
429
|
{
|
|
@@ -662,6 +811,29 @@ const Panel = {
|
|
|
662
811
|
? getDarkStyles(idPanel, scrollClassContainer)
|
|
663
812
|
: getLightStyles(idPanel, scrollClassContainer);
|
|
664
813
|
}
|
|
814
|
+
|
|
815
|
+
// Update tag hover styles
|
|
816
|
+
const tagStyleElement = s(`.${idPanel}-tag-styles`);
|
|
817
|
+
if (tagStyleElement) {
|
|
818
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
819
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
820
|
+
let hoverBg;
|
|
821
|
+
if (darkTheme) {
|
|
822
|
+
hoverBg = hasThemeColor ? darkenHex(themeColor, 0.5) : '#5a5a5a';
|
|
823
|
+
} else {
|
|
824
|
+
hoverBg = hasThemeColor ? lightenHex(themeColor, 0.6) : '#8a8a8a';
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
tagStyleElement.textContent = css`
|
|
828
|
+
.panel-tag-clickable:hover {
|
|
829
|
+
background: ${hoverBg} !important;
|
|
830
|
+
transform: scale(1.05);
|
|
831
|
+
}
|
|
832
|
+
.panel-tag-clickable:active {
|
|
833
|
+
transform: scale(0.98);
|
|
834
|
+
}
|
|
835
|
+
`;
|
|
836
|
+
}
|
|
665
837
|
};
|
|
666
838
|
|
|
667
839
|
// Add theme change listener
|
|
@@ -680,15 +852,39 @@ const Panel = {
|
|
|
680
852
|
width: 100%;
|
|
681
853
|
}
|
|
682
854
|
.${idPanel}-title {
|
|
683
|
-
color:
|
|
855
|
+
color: ${(() => {
|
|
856
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
857
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
858
|
+
if (hasThemeColor) {
|
|
859
|
+
return darkTheme ? lightenHex(themeColor, 0.3) : darkenHex(themeColor, 0.2);
|
|
860
|
+
} else {
|
|
861
|
+
return darkTheme ? '#8a85ff' : 'rgba(109, 104, 255, 1)';
|
|
862
|
+
}
|
|
863
|
+
})()};
|
|
684
864
|
font-size: 24px;
|
|
685
865
|
padding: 5px;
|
|
686
866
|
}
|
|
687
867
|
.a-title-${idPanel} {
|
|
688
|
-
color:
|
|
868
|
+
color: ${(() => {
|
|
869
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
870
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
871
|
+
if (hasThemeColor) {
|
|
872
|
+
return darkTheme ? lightenHex(themeColor, 0.3) : darkenHex(themeColor, 0.2);
|
|
873
|
+
} else {
|
|
874
|
+
return darkTheme ? '#8a85ff' : 'rgba(109, 104, 255, 1)';
|
|
875
|
+
}
|
|
876
|
+
})()};
|
|
689
877
|
}
|
|
690
878
|
.a-title-${idPanel}:hover {
|
|
691
|
-
color:
|
|
879
|
+
color: ${(() => {
|
|
880
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
881
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
882
|
+
if (hasThemeColor) {
|
|
883
|
+
return darkTheme ? lightenHex(themeColor, 0.5) : lightenHex(themeColor, 0.3);
|
|
884
|
+
} else {
|
|
885
|
+
return darkTheme ? '#ffb74d' : '#e89f4c';
|
|
886
|
+
}
|
|
887
|
+
})()};
|
|
692
888
|
}
|
|
693
889
|
.${idPanel}-row {
|
|
694
890
|
padding: 5px;
|
|
@@ -705,6 +901,7 @@ const Panel = {
|
|
|
705
901
|
margin-left: 10px;
|
|
706
902
|
top: -7px;
|
|
707
903
|
}
|
|
904
|
+
|
|
708
905
|
.${idPanel}-row-key {
|
|
709
906
|
}
|
|
710
907
|
.${idPanel}-row-value {
|
|
@@ -765,6 +962,23 @@ const Panel = {
|
|
|
765
962
|
}
|
|
766
963
|
</style>
|
|
767
964
|
<style class="${idPanel}-styles"></style>
|
|
965
|
+
<style class="${idPanel}-tag-styles">
|
|
966
|
+
.panel-tag-clickable:hover {
|
|
967
|
+
background: ${(() => {
|
|
968
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
969
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
970
|
+
if (darkTheme) {
|
|
971
|
+
return hasThemeColor ? darkenHex(themeColor, 0.5) : '#5a5a5a';
|
|
972
|
+
} else {
|
|
973
|
+
return hasThemeColor ? lightenHex(themeColor, 0.6) : '#8a8a8a';
|
|
974
|
+
}
|
|
975
|
+
})()} !important;
|
|
976
|
+
transform: scale(1.05);
|
|
977
|
+
}
|
|
978
|
+
.panel-tag-clickable:active {
|
|
979
|
+
transform: scale(0.98);
|
|
980
|
+
}
|
|
981
|
+
</style>
|
|
768
982
|
<div class="${idPanel}-container">
|
|
769
983
|
<div class="in modal ${idPanel}-form-container ${options.formContainerClass ? options.formContainerClass : ''}">
|
|
770
984
|
<div class="in ${idPanel}-form-header">
|
|
@@ -856,6 +1070,19 @@ function getBaseStyles(idPanel, scrollClassContainer) {
|
|
|
856
1070
|
.${idPanel}-dropdown {
|
|
857
1071
|
min-height: 100px;
|
|
858
1072
|
}
|
|
1073
|
+
.panel-visibility-icon {
|
|
1074
|
+
position: absolute;
|
|
1075
|
+
top: 34px;
|
|
1076
|
+
left: 0px;
|
|
1077
|
+
font-size: 14px;
|
|
1078
|
+
opacity: 0.7;
|
|
1079
|
+
transition: opacity 0.2s ease;
|
|
1080
|
+
pointer-events: none;
|
|
1081
|
+
z-index: 10;
|
|
1082
|
+
}
|
|
1083
|
+
.${idPanel}:hover .panel-visibility-icon {
|
|
1084
|
+
opacity: 1;
|
|
1085
|
+
}
|
|
859
1086
|
`;
|
|
860
1087
|
}
|
|
861
1088
|
|
|
@@ -872,15 +1099,27 @@ function getLightStyles(idPanel, scrollClassContainer) {
|
|
|
872
1099
|
background: #ffffff;
|
|
873
1100
|
}
|
|
874
1101
|
.${idPanel}-title {
|
|
875
|
-
color:
|
|
1102
|
+
color: ${(() => {
|
|
1103
|
+
const themeColor = subThemeManager.lightColor;
|
|
1104
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1105
|
+
return hasThemeColor ? darkenHex(themeColor, 0.2) : 'rgba(109, 104, 255, 1)';
|
|
1106
|
+
})()};
|
|
876
1107
|
font-size: 24px;
|
|
877
1108
|
padding: 5px;
|
|
878
1109
|
}
|
|
879
1110
|
.a-title-${idPanel} {
|
|
880
|
-
color:
|
|
1111
|
+
color: ${(() => {
|
|
1112
|
+
const themeColor = subThemeManager.lightColor;
|
|
1113
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1114
|
+
return hasThemeColor ? darkenHex(themeColor, 0.2) : 'rgba(109, 104, 255, 1)';
|
|
1115
|
+
})()};
|
|
881
1116
|
}
|
|
882
1117
|
.a-title-${idPanel}:hover {
|
|
883
|
-
color:
|
|
1118
|
+
color: ${(() => {
|
|
1119
|
+
const themeColor = subThemeManager.lightColor;
|
|
1120
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1121
|
+
return hasThemeColor ? lightenHex(themeColor, 0.3) : '#e89f4c';
|
|
1122
|
+
})()};
|
|
884
1123
|
}
|
|
885
1124
|
.${idPanel}-row-pin-value {
|
|
886
1125
|
font-size: 20px;
|
|
@@ -894,6 +1133,10 @@ function getLightStyles(idPanel, scrollClassContainer) {
|
|
|
894
1133
|
color: #000000 !important;
|
|
895
1134
|
font-size: 17px !important;
|
|
896
1135
|
}
|
|
1136
|
+
.panel-visibility-icon .fa-globe,
|
|
1137
|
+
.panel-visibility-icon .fa-lock {
|
|
1138
|
+
color: #666;
|
|
1139
|
+
}
|
|
897
1140
|
`;
|
|
898
1141
|
}
|
|
899
1142
|
|
|
@@ -910,15 +1153,27 @@ function getDarkStyles(idPanel, scrollClassContainer) {
|
|
|
910
1153
|
background: #3a3a3a;
|
|
911
1154
|
}
|
|
912
1155
|
.${idPanel}-title {
|
|
913
|
-
color:
|
|
1156
|
+
color: ${(() => {
|
|
1157
|
+
const themeColor = subThemeManager.darkColor;
|
|
1158
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1159
|
+
return hasThemeColor ? lightenHex(themeColor, 0.3) : '#8a85ff';
|
|
1160
|
+
})()};
|
|
914
1161
|
font-size: 24px;
|
|
915
1162
|
padding: 5px;
|
|
916
1163
|
}
|
|
917
1164
|
.a-title-${idPanel} {
|
|
918
|
-
color:
|
|
1165
|
+
color: ${(() => {
|
|
1166
|
+
const themeColor = subThemeManager.darkColor;
|
|
1167
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1168
|
+
return hasThemeColor ? lightenHex(themeColor, 0.3) : '#8a85ff';
|
|
1169
|
+
})()};
|
|
919
1170
|
}
|
|
920
1171
|
.a-title-${idPanel}:hover {
|
|
921
|
-
color:
|
|
1172
|
+
color: ${(() => {
|
|
1173
|
+
const themeColor = subThemeManager.darkColor;
|
|
1174
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
1175
|
+
return hasThemeColor ? lightenHex(themeColor, 0.5) : '#ffb74d';
|
|
1176
|
+
})()};
|
|
922
1177
|
}
|
|
923
1178
|
.${idPanel}-row-pin-value {
|
|
924
1179
|
font-size: 20px;
|
|
@@ -932,6 +1187,10 @@ function getDarkStyles(idPanel, scrollClassContainer) {
|
|
|
932
1187
|
color: #ffffff !important;
|
|
933
1188
|
font-size: 17px !important;
|
|
934
1189
|
}
|
|
1190
|
+
.panel-visibility-icon .fa-globe,
|
|
1191
|
+
.panel-visibility-icon .fa-lock {
|
|
1192
|
+
color: #999;
|
|
1193
|
+
}
|
|
935
1194
|
`;
|
|
936
1195
|
}
|
|
937
1196
|
|
|
@@ -6,7 +6,7 @@ import { NotificationManager } from './NotificationManager.js';
|
|
|
6
6
|
import { DocumentService } from '../../services/document/document.service.js';
|
|
7
7
|
import { FileService } from '../../services/file/file.service.js';
|
|
8
8
|
import { getSrcFromFileData } from './Input.js';
|
|
9
|
-
import { imageShimmer, renderCssAttr } from './Css.js';
|
|
9
|
+
import { imageShimmer, renderCssAttr, darkTheme, ThemeEvents, subThemeManager, lightenHex, darkenHex } 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';
|
|
@@ -30,11 +30,14 @@ const PanelForm = {
|
|
|
30
30
|
share: {
|
|
31
31
|
copyLink: false,
|
|
32
32
|
},
|
|
33
|
+
showCreatorProfile: false,
|
|
33
34
|
},
|
|
34
35
|
) {
|
|
35
36
|
const { idPanel, defaultUrlImage, Elements } = options;
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
// Authenticated users don't need 'public' tag - they see all their own posts
|
|
39
|
+
// Only include 'public' for unauthenticated users (handled by backend)
|
|
40
|
+
let prefixTags = [idPanel];
|
|
38
41
|
this.Data[idPanel] = {
|
|
39
42
|
originData: [],
|
|
40
43
|
data: [],
|
|
@@ -112,6 +115,7 @@ const PanelForm = {
|
|
|
112
115
|
route: options.route,
|
|
113
116
|
formContainerClass: 'session-in-log-in',
|
|
114
117
|
share: options.share,
|
|
118
|
+
showCreatorProfile: options.showCreatorProfile,
|
|
115
119
|
onClick: async function ({ payload }) {
|
|
116
120
|
if (options.route) {
|
|
117
121
|
setQueryPath({ path: options.route, queryPath: payload._id });
|
|
@@ -327,6 +331,9 @@ const PanelForm = {
|
|
|
327
331
|
const location = `${prefixTags.join('/')}`;
|
|
328
332
|
const blob = new Blob([data.mdFileId], { type: 'text/markdown' });
|
|
329
333
|
const md = new File([blob], mdFileName, { type: 'text/markdown' });
|
|
334
|
+
// Parse and normalize tags
|
|
335
|
+
// Note: 'public' tag is automatically extracted by the backend and converted to isPublic field
|
|
336
|
+
// It will be filtered from the tags array to keep visibility control separate from content tags
|
|
330
337
|
const tags = data.tags
|
|
331
338
|
? uniqueArray(
|
|
332
339
|
data.tags
|
|
@@ -397,6 +404,7 @@ const PanelForm = {
|
|
|
397
404
|
}
|
|
398
405
|
}
|
|
399
406
|
})();
|
|
407
|
+
// Backend will automatically extract 'public' from tags and set isPublic field
|
|
400
408
|
const body = {
|
|
401
409
|
location,
|
|
402
410
|
tags,
|
|
@@ -420,6 +428,9 @@ const PanelForm = {
|
|
|
420
428
|
_id: documentData._id,
|
|
421
429
|
id: documentData._id,
|
|
422
430
|
createdAt: documentData.createdAt,
|
|
431
|
+
// Use server response data - backend has already processed tags and isPublic
|
|
432
|
+
isPublic: documentData.isPublic || false,
|
|
433
|
+
tags: (documentData.tags || []).filter((t) => !prefixTags.includes(t)),
|
|
423
434
|
};
|
|
424
435
|
|
|
425
436
|
if (documentStatus === 'error') status = 'error';
|
|
@@ -560,13 +571,24 @@ const PanelForm = {
|
|
|
560
571
|
id: documentObject._id,
|
|
561
572
|
title: documentObject.title,
|
|
562
573
|
createdAt: documentObject.createdAt,
|
|
574
|
+
// Backend filters 'public' tag automatically - it's converted to isPublic field
|
|
563
575
|
tags: documentObject.tags.filter((t) => !prefixTags.includes(t)),
|
|
564
576
|
mdFileId: marked.parse(mdFileId),
|
|
565
577
|
userId: documentObject.userId._id,
|
|
578
|
+
userInfo:
|
|
579
|
+
documentObject.userId && typeof documentObject.userId === 'object'
|
|
580
|
+
? {
|
|
581
|
+
username: documentObject.userId.username,
|
|
582
|
+
email: documentObject.userId.email,
|
|
583
|
+
_id: documentObject.userId._id,
|
|
584
|
+
profileImageId: documentObject.userId.profileImageId,
|
|
585
|
+
}
|
|
586
|
+
: null,
|
|
566
587
|
fileId,
|
|
567
588
|
tools: Elements.Data.user.main.model.user._id === documentObject.userId._id,
|
|
568
589
|
_id: documentObject._id,
|
|
569
590
|
totalCopyShareLinkCount: documentObject.totalCopyShareLinkCount || 0,
|
|
591
|
+
isPublic: documentObject.isPublic || false,
|
|
570
592
|
});
|
|
571
593
|
} catch (fileError) {
|
|
572
594
|
logger.error('Error fetching files for document:', documentObject._id, fileError);
|