cyberia 3.0.2 → 3.1.3
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.production → .env.example} +20 -2
- package/.github/workflows/engine-cyberia.cd.yml +41 -10
- package/.github/workflows/engine-cyberia.ci.yml +53 -14
- package/.github/workflows/ghpkg.ci.yml +1 -1
- package/.github/workflows/gitlab.ci.yml +1 -1
- package/.github/workflows/hardhat.ci.yml +82 -0
- package/.github/workflows/npmpkg.ci.yml +37 -8
- package/.github/workflows/publish.ci.yml +5 -5
- package/.github/workflows/publish.cyberia.ci.yml +5 -5
- package/.github/workflows/pwa-microservices-template-page.cd.yml +3 -3
- package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
- package/.github/workflows/release.cd.yml +3 -2
- package/.vscode/extensions.json +9 -8
- package/.vscode/settings.json +3 -2
- package/CHANGELOG.md +533 -290
- package/CLI-HELP.md +79 -53
- package/WHITE-PAPER.md +1540 -0
- package/bin/build.js +16 -11
- package/bin/cyberia.js +959 -8
- package/bin/deploy.js +103 -270
- package/bin/file.js +2 -1
- package/bin/index.js +959 -8
- package/bin/vs.js +3 -3
- package/conf.js +277 -77
- package/deployment.yaml +218 -4
- package/hardhat/.env.example +31 -0
- package/hardhat/README.md +531 -0
- package/hardhat/WHITE-PAPER.md +1540 -0
- package/hardhat/contracts/ObjectLayerToken.sol +391 -0
- package/hardhat/deployments/.gitkeep +0 -0
- package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
- package/hardhat/hardhat.config.js +136 -0
- package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
- package/hardhat/networks/besu-object-layer.network.json +138 -0
- package/hardhat/package-lock.json +7628 -0
- package/hardhat/package.json +45 -0
- package/hardhat/scripts/deployObjectLayerToken.js +98 -0
- package/hardhat/test/ObjectLayerToken.js +590 -0
- package/jsdoc.dd-cyberia.json +59 -0
- package/jsdoc.json +20 -13
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +490 -0
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +261 -0
- package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +132 -0
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +52 -52
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -4
- package/manifests/pv-pvc-dd.yaml +1 -1
- package/package.json +60 -50
- package/proxy.yaml +128 -9
- package/pv-pvc.yaml +132 -0
- package/scripts/k3s-node-setup.sh +1 -1
- package/scripts/ports-ls.sh +2 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +3 -1
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +1 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +40 -7
- package/src/api/document/document.service.js +1 -1
- package/src/api/file/file.controller.js +3 -1
- package/src/api/file/file.service.js +28 -5
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +6 -2
- package/src/api/object-layer/object-layer.model.js +67 -21
- package/src/api/object-layer/object-layer.router.js +668 -42
- package/src/api/object-layer/object-layer.service.js +10 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +1 -2
- package/src/api/user/user.router.js +10 -5
- package/src/api/user/user.service.js +7 -7
- package/src/cli/baremetal.js +6 -10
- package/src/cli/cloud-init.js +0 -3
- package/src/cli/db.js +54 -71
- package/src/cli/deploy.js +64 -12
- package/src/cli/env.js +5 -5
- package/src/cli/fs.js +0 -2
- package/src/cli/image.js +0 -3
- package/src/cli/index.js +41 -13
- package/src/cli/monitor.js +5 -6
- package/src/cli/repository.js +329 -46
- package/src/cli/run.js +210 -122
- package/src/cli/secrets.js +1 -3
- package/src/cli/ssh.js +1 -1
- package/src/client/Itemledger.index.js +1 -959
- package/src/client/Underpost.index.js +36 -0
- package/src/client/components/core/AgGrid.js +20 -5
- package/src/client/components/core/Alert.js +2 -2
- package/src/client/components/core/Content.js +22 -3
- package/src/client/components/core/Docs.js +30 -6
- package/src/client/components/core/FileExplorer.js +71 -4
- package/src/client/components/core/Input.js +1 -1
- package/src/client/components/core/Modal.js +22 -6
- package/src/client/components/core/PublicProfile.js +3 -3
- package/src/client/components/core/RichText.js +1 -2
- package/src/client/components/core/Router.js +34 -1
- package/src/client/components/core/Worker.js +1 -1
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +63 -1
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +145 -119
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +64 -6
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +1 -0
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +44 -2
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +0 -1
- package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +64 -2
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +1 -0
- package/src/client/components/itemledger/CssItemledger.js +62 -0
- package/src/client/components/underpost/CommonUnderpost.js +29 -0
- package/src/client/components/underpost/CssUnderpost.js +281 -0
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
- package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
- package/src/client/components/underpost/ElementsUnderpost.js +38 -0
- package/src/client/components/underpost/LabGalleryUnderpost.js +82 -0
- package/src/client/components/underpost/LogInUnderpost.js +23 -0
- package/src/client/components/underpost/LogOutUnderpost.js +15 -0
- package/src/client/components/underpost/MenuUnderpost.js +691 -0
- package/src/client/components/underpost/RoutesUnderpost.js +47 -0
- package/src/client/components/underpost/SettingsUnderpost.js +16 -0
- package/src/client/components/underpost/SignUpUnderpost.js +9 -0
- package/src/client/components/underpost/SocketIoUnderpost.js +54 -0
- package/src/client/components/underpost/TranslateUnderpost.js +10 -0
- package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
- package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
- package/src/client/public/cryptokoyn/microdata.json +85 -0
- package/src/client/public/cryptokoyn/site.webmanifest +57 -0
- package/src/client/public/cryptokoyn/sitemap +3 -3
- package/src/client/public/default/sitemap +3 -3
- package/src/client/public/itemledger/browserconfig.xml +2 -2
- package/src/client/public/itemledger/manifest.webmanifest +4 -4
- package/src/client/public/itemledger/microdata.json +71 -0
- package/src/client/public/itemledger/sitemap +3 -3
- package/src/client/public/itemledger/yandex-browser-manifest.json +2 -2
- package/src/client/public/test/sitemap +3 -3
- package/src/client/services/object-layer/object-layer.management.js +23 -4
- package/src/client/ssr/body/404.js +15 -11
- package/src/client/ssr/body/500.js +15 -11
- package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +83 -0
- package/src/client/ssr/head/PwaItemledger.js +60 -0
- package/src/client/ssr/head/UnderpostScripts.js +6 -0
- package/src/client/ssr/offline/NoNetworkConnection.js +11 -10
- package/src/client/ssr/pages/Test.js +11 -10
- package/src/client.build.js +0 -3
- package/src/client.dev.js +0 -3
- package/src/db/DataBaseProvider.js +17 -2
- package/src/db/mariadb/MariaDB.js +14 -9
- package/src/db/mongo/MongooseDB.js +17 -1
- package/src/index.js +1 -1
- package/src/proxy.js +0 -3
- package/src/runtime/express/Express.js +15 -9
- package/src/runtime/lampp/Lampp.js +6 -13
- package/src/server/auth.js +12 -14
- package/src/server/backup.js +2 -3
- package/src/server/besu-genesis-generator.js +1630 -0
- package/src/server/client-build-docs.js +126 -17
- package/src/server/client-build-live.js +9 -18
- package/src/server/client-build.js +203 -75
- package/src/server/client-dev-server.js +14 -13
- package/src/server/conf.js +376 -164
- package/src/server/cron.js +2 -1
- package/src/server/dns.js +28 -12
- package/src/server/downloader.js +0 -2
- package/src/server/logger.js +27 -9
- package/src/server/object-layer.js +92 -16
- package/src/server/peer.js +0 -2
- package/src/server/process.js +1 -50
- package/src/server/proxy.js +4 -8
- package/src/server/runtime.js +5 -8
- package/src/server/semantic-layer-generator.js +1 -0
- package/src/server/ssr.js +0 -3
- package/src/server/start.js +19 -12
- package/src/server/tls.js +0 -2
- package/src/server.js +0 -4
- package/.env.development +0 -43
- package/.env.test +0 -43
- package/hardhat/contracts/CryptoKoyn.sol +0 -59
- package/hardhat/contracts/ItemLedger.sol +0 -73
- package/hardhat/contracts/Lock.sol +0 -34
- package/hardhat/hardhat.config.cjs +0 -45
- package/hardhat/ignition/modules/Lock.js +0 -18
- package/hardhat/networks/cryptokoyn-itemledger.network.json +0 -29
- package/hardhat/scripts/deployCryptokoyn.cjs +0 -25
- package/hardhat/scripts/deployItemledger.cjs +0 -25
- package/hardhat/test/Lock.js +0 -126
- package/hardhat/white-paper.md +0 -581
- package/white-paper.md +0 -581
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document search provider for the SearchBox component.
|
|
3
|
+
* Provides typeahead search functionality for documents with custom rendering,
|
|
4
|
+
* click handling, and theme-aware styling.
|
|
5
|
+
* @module src/client/components/underpost/DocumentSearchProvider.js
|
|
6
|
+
* @namespace DocumentSearchProviderClient
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { loggerFactory } from '../core/Logger.js';
|
|
10
|
+
import { DocumentService } from '../../services/document/document.service.js';
|
|
11
|
+
import { Translate } from '../core/Translate.js';
|
|
12
|
+
import { getProxyPath } from '../core/Router.js';
|
|
13
|
+
import { Css, ThemeEvents, darkTheme, subThemeManager, lightenHex, darkenHex } from '../core/Css.js';
|
|
14
|
+
import { s } from '../core/VanillaJs.js';
|
|
15
|
+
import { Modal } from '../core/Modal.js';
|
|
16
|
+
|
|
17
|
+
const logger = loggerFactory(import.meta);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Document Search Provider singleton object for SearchBox integration.
|
|
21
|
+
* Implements the SearchBox provider interface with document-specific search,
|
|
22
|
+
* rendering, and interaction logic.
|
|
23
|
+
* @memberof DocumentSearchProviderClient
|
|
24
|
+
*/
|
|
25
|
+
const DocumentSearchProvider = {
|
|
26
|
+
/**
|
|
27
|
+
* Unique identifier for this search provider.
|
|
28
|
+
* @type {string}
|
|
29
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
30
|
+
*/
|
|
31
|
+
id: 'document-search',
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Priority level for search result ordering (lower number = higher priority).
|
|
35
|
+
* Higher priority than default routes (50).
|
|
36
|
+
* @type {number}
|
|
37
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
38
|
+
*/
|
|
39
|
+
priority: 10,
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Searches documents using the high-query endpoint with optimized matching.
|
|
43
|
+
* Supports case-insensitive, multi-term, multi-field search for maximum results.
|
|
44
|
+
* Minimum query length: 1 character for maximum flexibility.
|
|
45
|
+
* Filters by idPanel tag to prevent out-of-panel context results.
|
|
46
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
47
|
+
* @param {string} query - The search query string.
|
|
48
|
+
* @param {object} context - Search context object containing RouterInstance and options.
|
|
49
|
+
* @param {object} [context.RouterInstance] - Router instance for navigation.
|
|
50
|
+
* @param {object} [context.options] - Additional search options.
|
|
51
|
+
* @param {string} [context.idPanel] - Panel ID to filter documents by tag.
|
|
52
|
+
* @returns {Promise<Array<object>>} Promise resolving to array of search result objects.
|
|
53
|
+
* @returns {Promise<Array<{id: string, type: string, title: string, tags: Array<string>, createdAt: string, data: object}>>}
|
|
54
|
+
*/
|
|
55
|
+
search: async (query, context) => {
|
|
56
|
+
// Minimum match requirement: allow 1 character for maximum results
|
|
57
|
+
if (!query || query.trim().length < 1) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const response = await DocumentService.high({
|
|
63
|
+
params: {
|
|
64
|
+
q: query.trim(),
|
|
65
|
+
idPanel: context.idPanel, // Filter by panel tag to prevent out-of-panel context results
|
|
66
|
+
limit: 7, // Increased limit for maximum results
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (response.status === 'success' && response.data && response.data.data) {
|
|
71
|
+
return response.data.data.map((doc) => ({
|
|
72
|
+
id: doc._id,
|
|
73
|
+
type: 'document',
|
|
74
|
+
title: doc.title || 'Untitled',
|
|
75
|
+
tags: doc.tags || [],
|
|
76
|
+
createdAt: doc.createdAt,
|
|
77
|
+
data: doc,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return [];
|
|
82
|
+
} catch (error) {
|
|
83
|
+
logger.error('Document search error:', error);
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Renders a custom result card for a document search result.
|
|
90
|
+
* Generates HTML with title, tags, date, and click handlers.
|
|
91
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
92
|
+
* @param {object} result - The search result object to render.
|
|
93
|
+
* @param {string} result.id - Document ID.
|
|
94
|
+
* @param {string} result.type - Result type (should be 'document').
|
|
95
|
+
* @param {string} result.title - Document title.
|
|
96
|
+
* @param {Array<string>} result.tags - Document tags array.
|
|
97
|
+
* @param {string} result.createdAt - Document creation date.
|
|
98
|
+
* @param {object} result.data - Full document data object.
|
|
99
|
+
* @param {number} index - The index of this result in the results array.
|
|
100
|
+
* @param {object} context - Render context object.
|
|
101
|
+
* @returns {string} HTML string for the search result card.
|
|
102
|
+
*/
|
|
103
|
+
renderResult: (result, index, context) => {
|
|
104
|
+
const title = result.title || 'Untitled';
|
|
105
|
+
const tags = result.tags || [];
|
|
106
|
+
const createdAt = result.createdAt ? new Date(result.createdAt).toLocaleDateString() : '';
|
|
107
|
+
|
|
108
|
+
// Check if document is public (from result.data.isPublic field)
|
|
109
|
+
const isPublic = result.data && result.data.isPublic === true;
|
|
110
|
+
|
|
111
|
+
// Visibility icon: globe for public, padlock for private
|
|
112
|
+
const visibilityIcon = isPublic
|
|
113
|
+
? '<i class="fas fa-globe" title="Public document"></i>'
|
|
114
|
+
: '<i class="fas fa-lock" title="Private document"></i>';
|
|
115
|
+
|
|
116
|
+
// Build tags display with data attributes for click handling
|
|
117
|
+
const tagsHtml = tags
|
|
118
|
+
.filter((tag) => tag !== 'public')
|
|
119
|
+
.slice(0, 3)
|
|
120
|
+
.map((tag) => `<span class="document-search-tag" data-tag-value="${tag}">${tag}</span>`)
|
|
121
|
+
.join('');
|
|
122
|
+
|
|
123
|
+
// Attach tag handlers after rendering
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
DocumentSearchProvider.attachTagHandlers();
|
|
126
|
+
}, 50);
|
|
127
|
+
|
|
128
|
+
return html`
|
|
129
|
+
<div
|
|
130
|
+
class="search-result-item search-result-document"
|
|
131
|
+
data-result-id="${result.id}"
|
|
132
|
+
data-result-type="document"
|
|
133
|
+
data-result-index="${index}"
|
|
134
|
+
data-provider-id="document-search"
|
|
135
|
+
>
|
|
136
|
+
<div class="search-result-icon">
|
|
137
|
+
<i class="fas fa-file-alt"></i>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="search-result-content">
|
|
140
|
+
<div class="search-result-title-row">
|
|
141
|
+
<span class="search-result-visibility-icon">${visibilityIcon}</span>
|
|
142
|
+
<span class="search-result-title">${title}</span>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="search-result-meta">
|
|
145
|
+
${createdAt ? `<span class="search-result-date">${createdAt}</span>` : ''}
|
|
146
|
+
${tagsHtml ? `<div class="search-result-tags">${tagsHtml}</div>` : ''}
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
`;
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Attaches click event handlers to tag elements in search results.
|
|
155
|
+
* When a tag is clicked, it populates the search box with the tag value
|
|
156
|
+
* and triggers a new search for that tag.
|
|
157
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
158
|
+
* @returns {void}
|
|
159
|
+
*/
|
|
160
|
+
attachTagHandlers: () => {
|
|
161
|
+
setTimeout(() => {
|
|
162
|
+
const tagElements = document.querySelectorAll('.document-search-tag');
|
|
163
|
+
tagElements.forEach((tagEl) => {
|
|
164
|
+
tagEl.onclick = (e) => {
|
|
165
|
+
e.stopPropagation();
|
|
166
|
+
e.preventDefault();
|
|
167
|
+
|
|
168
|
+
const tagValue = tagEl.getAttribute('data-tag-value') || tagEl.textContent.trim();
|
|
169
|
+
|
|
170
|
+
// Open search bar if closed
|
|
171
|
+
if (
|
|
172
|
+
!s('.main-body-btn-ui-bar-custom-open').classList.contains('hide') ||
|
|
173
|
+
!s(`.main-body-btn-ui-open`).classList.contains('hide')
|
|
174
|
+
)
|
|
175
|
+
s('.main-body-btn-bar-custom').click();
|
|
176
|
+
|
|
177
|
+
// Find and populate search box
|
|
178
|
+
const searchBox = s('.top-bar-search-box');
|
|
179
|
+
if (searchBox) {
|
|
180
|
+
searchBox.value = tagValue;
|
|
181
|
+
searchBox.focus();
|
|
182
|
+
|
|
183
|
+
// Trigger input event to start search
|
|
184
|
+
const inputEvent = new Event('input', { bubbles: true });
|
|
185
|
+
searchBox.dispatchEvent(inputEvent);
|
|
186
|
+
|
|
187
|
+
logger.info(`Document search tag clicked: ${tagValue}`);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}, 50);
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Handles click events on document search results.
|
|
196
|
+
* Loads the selected document into the Underpost panel using SPA navigation.
|
|
197
|
+
* Prevents duplicate history entries if already viewing the same document.
|
|
198
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
199
|
+
* @param {object} result - The search result object that was clicked.
|
|
200
|
+
* @param {string} result.id - Document ID to load.
|
|
201
|
+
* @param {string} result.title - Document title for logging.
|
|
202
|
+
* @param {object} context - Click context object with navigation helpers.
|
|
203
|
+
* @param {object} [context.RouterInstance] - Router instance for SPA navigation.
|
|
204
|
+
* @param {string} [context.currentRoute] - Current route name (e.g., 'home').
|
|
205
|
+
* @param {Function} [context.updatePanel] - Function to update the panel with new document.
|
|
206
|
+
* @returns {void}
|
|
207
|
+
*/
|
|
208
|
+
onClick: async (result, context) => {
|
|
209
|
+
if (!result || !result.id) {
|
|
210
|
+
logger.warn('Invalid document result');
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
logger.info(`Document clicked: ${result.id} - ${result.title}`);
|
|
215
|
+
|
|
216
|
+
// Close any open modal views (like Settings, Account, etc.) before navigating
|
|
217
|
+
// This ensures we return to home view when clicking a search result
|
|
218
|
+
await Modal.onHomeRouterEvent();
|
|
219
|
+
|
|
220
|
+
// Check if we're already on this document to prevent duplicate history
|
|
221
|
+
const currentUrl = new URL(window.location.href);
|
|
222
|
+
const currentCid = currentUrl.searchParams.get('cid');
|
|
223
|
+
|
|
224
|
+
// Only update URL and history if cid is different
|
|
225
|
+
if (currentCid !== result.id) {
|
|
226
|
+
// SPA Navigation: Update panel without page reload
|
|
227
|
+
const path = getProxyPath();
|
|
228
|
+
const queryPath = `?cid=${result.id}`;
|
|
229
|
+
|
|
230
|
+
// Update browser history without reload
|
|
231
|
+
window.history.pushState({}, '', `${path}${queryPath}`);
|
|
232
|
+
|
|
233
|
+
// Trigger PanelForm update with the document CID
|
|
234
|
+
if (context.updatePanel) context.updatePanel(result.id);
|
|
235
|
+
} else {
|
|
236
|
+
logger.info('Already on this document, not creating duplicate history');
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Generates CSS styles for document search results with theme support.
|
|
242
|
+
* Uses subThemeManager colors for consistent theming across light and dark modes.
|
|
243
|
+
* Dynamically calculates colors based on current theme and subtheme settings.
|
|
244
|
+
* @memberof DocumentSearchProviderClient.DocumentSearchProvider
|
|
245
|
+
* @returns {string} CSS string containing all styles for document search results.
|
|
246
|
+
*/
|
|
247
|
+
getStyles: () => {
|
|
248
|
+
// Get theme color from subThemeManager
|
|
249
|
+
const themeColor = darkTheme ? subThemeManager.darkColor : subThemeManager.lightColor;
|
|
250
|
+
const hasThemeColor = themeColor && themeColor !== null;
|
|
251
|
+
|
|
252
|
+
// Calculate theme-based colors
|
|
253
|
+
let borderColor, bgColor, hoverBg, hoverBorder, iconColor, textColor;
|
|
254
|
+
let tagBg, tagColor, tagHoverBg, activeBg, activeBorder;
|
|
255
|
+
|
|
256
|
+
if (darkTheme) {
|
|
257
|
+
// Dark theme styling
|
|
258
|
+
if (hasThemeColor) {
|
|
259
|
+
borderColor = darkenHex(themeColor, 0.75);
|
|
260
|
+
bgColor = darkenHex(themeColor, 0.85);
|
|
261
|
+
hoverBg = darkenHex(themeColor, 0.75);
|
|
262
|
+
hoverBorder = lightenHex(themeColor, 0.4);
|
|
263
|
+
iconColor = lightenHex(themeColor, 0.5);
|
|
264
|
+
textColor = lightenHex(themeColor, 0.8);
|
|
265
|
+
tagBg = darkenHex(themeColor, 0.6);
|
|
266
|
+
tagColor = lightenHex(themeColor, 0.7);
|
|
267
|
+
tagHoverBg = darkenHex(themeColor, 0.5);
|
|
268
|
+
activeBg = darkenHex(themeColor, 0.7);
|
|
269
|
+
activeBorder = lightenHex(themeColor, 0.3);
|
|
270
|
+
} else {
|
|
271
|
+
borderColor = '#444';
|
|
272
|
+
bgColor = '#2a2a2a';
|
|
273
|
+
hoverBg = '#333';
|
|
274
|
+
hoverBorder = '#0d6efd';
|
|
275
|
+
iconColor = '#aaa';
|
|
276
|
+
textColor = '#e0e0e0';
|
|
277
|
+
tagBg = '#4a4a4a';
|
|
278
|
+
tagColor = '#ffffff';
|
|
279
|
+
tagHoverBg = '#5a5a5a';
|
|
280
|
+
activeBg = '#333';
|
|
281
|
+
activeBorder = '#555';
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
// Light theme styling
|
|
285
|
+
if (hasThemeColor) {
|
|
286
|
+
borderColor = lightenHex(themeColor, 0.75);
|
|
287
|
+
bgColor = lightenHex(themeColor, 0.92);
|
|
288
|
+
hoverBg = lightenHex(themeColor, 0.85);
|
|
289
|
+
hoverBorder = lightenHex(themeColor, 0.5);
|
|
290
|
+
iconColor = darkenHex(themeColor, 0.3);
|
|
291
|
+
textColor = darkenHex(themeColor, 0.6);
|
|
292
|
+
tagBg = lightenHex(themeColor, 0.7);
|
|
293
|
+
tagColor = darkenHex(themeColor, 0.5);
|
|
294
|
+
tagHoverBg = lightenHex(themeColor, 0.6);
|
|
295
|
+
activeBg = lightenHex(themeColor, 0.85);
|
|
296
|
+
activeBorder = lightenHex(themeColor, 0.5);
|
|
297
|
+
} else {
|
|
298
|
+
borderColor = '#ddd';
|
|
299
|
+
bgColor = '#f9f9f9';
|
|
300
|
+
hoverBg = '#efefef';
|
|
301
|
+
hoverBorder = '#007bff';
|
|
302
|
+
iconColor = '#666';
|
|
303
|
+
textColor = '#333';
|
|
304
|
+
tagBg = '#a2a2a2';
|
|
305
|
+
tagColor = '#ffffff';
|
|
306
|
+
tagHoverBg = '#8a8a8a';
|
|
307
|
+
activeBg = '#e8e8e8';
|
|
308
|
+
activeBorder = '#999';
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return css`
|
|
313
|
+
/* Unified with Panel card styles - theme consistent */
|
|
314
|
+
.search-result-document {
|
|
315
|
+
padding: 8px;
|
|
316
|
+
margin: 2px 0;
|
|
317
|
+
border-radius: 4px;
|
|
318
|
+
cursor: pointer;
|
|
319
|
+
transition: all 0.2s ease;
|
|
320
|
+
display: flex;
|
|
321
|
+
align-items: flex-start;
|
|
322
|
+
gap: 10px;
|
|
323
|
+
border: 1px solid ${borderColor};
|
|
324
|
+
background: ${bgColor};
|
|
325
|
+
text-align: left;
|
|
326
|
+
position: relative;
|
|
327
|
+
box-sizing: border-box;
|
|
328
|
+
width: 100%;
|
|
329
|
+
max-width: 100%;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.search-result-document:hover {
|
|
333
|
+
background: ${hoverBg};
|
|
334
|
+
border-color: ${hoverBorder};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.search-result-document .search-result-icon {
|
|
338
|
+
font-size: 18px;
|
|
339
|
+
color: ${iconColor};
|
|
340
|
+
padding-top: 2px;
|
|
341
|
+
min-width: 20px;
|
|
342
|
+
display: flex;
|
|
343
|
+
align-items: center;
|
|
344
|
+
justify-content: center;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.search-result-document .search-result-content {
|
|
348
|
+
flex: 1;
|
|
349
|
+
min-width: 0;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.search-result-document .search-result-title {
|
|
353
|
+
font-weight: 500;
|
|
354
|
+
font-size: 14px;
|
|
355
|
+
color: ${textColor};
|
|
356
|
+
margin-bottom: 4px;
|
|
357
|
+
overflow: hidden;
|
|
358
|
+
text-overflow: ellipsis;
|
|
359
|
+
white-space: nowrap;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.search-result-document .search-result-meta {
|
|
363
|
+
display: flex;
|
|
364
|
+
align-items: center;
|
|
365
|
+
gap: 8px;
|
|
366
|
+
flex-wrap: wrap;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.search-result-document .search-result-date {
|
|
370
|
+
font-size: 11px;
|
|
371
|
+
color: ${darkTheme ? '#999' : '#888'};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.search-result-document .search-result-tags {
|
|
375
|
+
display: flex;
|
|
376
|
+
gap: 4px;
|
|
377
|
+
flex-wrap: wrap;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.document-search-tag {
|
|
381
|
+
font-size: 10px;
|
|
382
|
+
padding: 2px 6px;
|
|
383
|
+
border-radius: 3px;
|
|
384
|
+
background: ${tagBg};
|
|
385
|
+
color: ${tagColor};
|
|
386
|
+
font-weight: 500;
|
|
387
|
+
cursor: pointer;
|
|
388
|
+
transition: all 0.2s ease;
|
|
389
|
+
margin: 3px;
|
|
390
|
+
display: inline-block;
|
|
391
|
+
border: 1px solid
|
|
392
|
+
${hasThemeColor ? (darkTheme ? lightenHex(themeColor, 0.3) : lightenHex(themeColor, 0.6)) : 'transparent'};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.document-search-tag:hover {
|
|
396
|
+
background: ${tagHoverBg};
|
|
397
|
+
transform: scale(1.05);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.document-search-tag:active {
|
|
401
|
+
transform: scale(0.98);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.search-result-title-row {
|
|
405
|
+
display: flex;
|
|
406
|
+
align-items: center;
|
|
407
|
+
gap: 6px;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.search-result-visibility-icon {
|
|
411
|
+
display: inline-flex;
|
|
412
|
+
align-items: center;
|
|
413
|
+
font-size: 12px;
|
|
414
|
+
opacity: 0.7;
|
|
415
|
+
transition: opacity 0.2s ease;
|
|
416
|
+
flex-shrink: 0;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.search-result-visibility-icon .fa-globe,
|
|
420
|
+
.search-result-visibility-icon .fa-lock {
|
|
421
|
+
color: ${darkTheme ? '#999' : '#666'};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.search-result-document:hover .search-result-visibility-icon {
|
|
425
|
+
opacity: 1;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.search-result-title-row .search-result-title {
|
|
429
|
+
margin-bottom: 0;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.search-result-document.active-search-result,
|
|
433
|
+
.search-result-document.main-btn-menu-active {
|
|
434
|
+
background: ${activeBg};
|
|
435
|
+
border-color: ${activeBorder};
|
|
436
|
+
box-shadow: 0 0 0 1px ${activeBorder}66;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/* Active document tags have stronger accent */
|
|
440
|
+
.search-result-document.active-search-result .document-search-tag {
|
|
441
|
+
background: ${hasThemeColor ? (darkTheme ? darkenHex(themeColor, 0.5) : lightenHex(themeColor, 0.65)) : tagBg};
|
|
442
|
+
border-color: ${activeBorder};
|
|
443
|
+
}
|
|
444
|
+
`;
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
export { DocumentSearchProvider };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { loggerFactory } from '../core/Logger.js';
|
|
2
|
+
import { BaseElement } from './CommonUnderpost.js';
|
|
3
|
+
|
|
4
|
+
const logger = loggerFactory(import.meta);
|
|
5
|
+
|
|
6
|
+
const ElementsUnderpost = {
|
|
7
|
+
Data: BaseElement(),
|
|
8
|
+
Interval: {},
|
|
9
|
+
LocalDataScope: {},
|
|
10
|
+
Init: function (options = { type: 'user', id: 'main', element: {} }) {
|
|
11
|
+
const { type, id, element } = options;
|
|
12
|
+
this.Data[type][id] = {
|
|
13
|
+
...BaseElement()[type].main,
|
|
14
|
+
...this.Data[type][id],
|
|
15
|
+
...element,
|
|
16
|
+
};
|
|
17
|
+
if (!this.Interval[type]) this.Interval[type] = {};
|
|
18
|
+
if (!this.Interval[type][id]) this.Interval[type][id] = {};
|
|
19
|
+
if (!this.LocalDataScope[type]) this.LocalDataScope[type] = {};
|
|
20
|
+
if (!this.LocalDataScope[type][id])
|
|
21
|
+
this.LocalDataScope[type][id] = {
|
|
22
|
+
path: [],
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
removeAll: function () {
|
|
26
|
+
for (const type of Object.keys(this.Data)) {
|
|
27
|
+
for (const id of Object.keys(this.Data[type])) {
|
|
28
|
+
if (this.Interval[type] && this.Interval[type][id]) {
|
|
29
|
+
for (const interval of Object.keys(this.Interval[type][id])) clearInterval(this.Interval[type][id][interval]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
this.Interval = {};
|
|
34
|
+
this.Data = BaseElement();
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { ElementsUnderpost };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { BtnIcon } from '../core/BtnIcon.js';
|
|
2
|
+
import { getId } from '../core/CommonJs.js';
|
|
3
|
+
import { Css, Themes } from '../core/Css.js';
|
|
4
|
+
import { Modal, renderViewTitle } from '../core/Modal.js';
|
|
5
|
+
import { listenQueryPathInstance, setQueryPath } from '../core/Router.js';
|
|
6
|
+
import { s } from '../core/VanillaJs.js';
|
|
7
|
+
|
|
8
|
+
const LabGalleryUnderpost = {
|
|
9
|
+
Tokens: {},
|
|
10
|
+
View: [
|
|
11
|
+
{ title: '3D PLOT DEMO', path: '3dplotdemo' },
|
|
12
|
+
{ title: 'PATH FINDING', path: 'pathfinding' },
|
|
13
|
+
{ title: 'SURVIVAL BALL GAME', path: 'survival' },
|
|
14
|
+
{ title: 'INFINITE LEVELS LABYRYNTH', path: 'laberinto' },
|
|
15
|
+
{ title: 'VIRTUAL ROLL DICE', path: 'dice' },
|
|
16
|
+
{ title: 'BOT VIRTUAL WORLD', path: 'bots' },
|
|
17
|
+
{ title: 'CELLULAR AUTOMATA SIMULATOR', path: 'life' },
|
|
18
|
+
{ title: 'VANILLAJS SNAKE', path: 'snake' },
|
|
19
|
+
],
|
|
20
|
+
Render: async function () {
|
|
21
|
+
const id = getId(this.Tokens, 'lab-gallery-');
|
|
22
|
+
let render = '';
|
|
23
|
+
let i = -1;
|
|
24
|
+
for (const view of this.View) {
|
|
25
|
+
i++;
|
|
26
|
+
const viewLabId = `${id}-${i}`;
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
s(`.btn-${viewLabId}`).onclick = async () => {
|
|
29
|
+
const ModalId = `modal-${viewLabId}`;
|
|
30
|
+
const { barConfig } = await Themes[Css.currentTheme]();
|
|
31
|
+
setQueryPath({ path: 'lab-gallery', queryPath: view.path });
|
|
32
|
+
await Modal.Render({
|
|
33
|
+
barConfig,
|
|
34
|
+
title: renderViewTitle({
|
|
35
|
+
icon: html`<i class="fa-solid fa-photo-film"></i>`,
|
|
36
|
+
text: view.title,
|
|
37
|
+
}),
|
|
38
|
+
id: ModalId,
|
|
39
|
+
html: async () => {
|
|
40
|
+
const url = `https://underpost.net/${view.path}`;
|
|
41
|
+
return html` <iframe class="wfa iframe-gallery" src="${url}"> </iframe> `;
|
|
42
|
+
},
|
|
43
|
+
maximize: true,
|
|
44
|
+
mode: 'view',
|
|
45
|
+
slideMenu: 'modal-menu',
|
|
46
|
+
query: true,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
render += html`
|
|
51
|
+
<style>
|
|
52
|
+
.iframe-gallery {
|
|
53
|
+
border: none;
|
|
54
|
+
min-height: 400px;
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
57
|
+
<div class="in">
|
|
58
|
+
${await BtnIcon.Render({
|
|
59
|
+
class: `wfa btn-lab-gallery btn-${viewLabId}`,
|
|
60
|
+
label: html`<i class="fa-solid fa-arrow-up-right-from-square"></i>    ${view.title}`,
|
|
61
|
+
})}
|
|
62
|
+
</div>
|
|
63
|
+
<div class="in iframe-${viewLabId} hide"></div>
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
listenQueryPathInstance({
|
|
67
|
+
id,
|
|
68
|
+
routeId: 'lab-gallery',
|
|
69
|
+
event: (path) => {
|
|
70
|
+
const indexView = this.View.findIndex((view) => view.path === path);
|
|
71
|
+
if (indexView > -1) {
|
|
72
|
+
const viewLabId = `${id}-${indexView}`;
|
|
73
|
+
if (s(`.btn-${viewLabId}`)) s(`.btn-${viewLabId}`).click();
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return render;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export { LabGalleryUnderpost };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Auth } from '../core/Auth.js';
|
|
2
|
+
import { LogIn } from '../core/LogIn.js';
|
|
3
|
+
import { ElementsUnderpost } from './ElementsUnderpost.js';
|
|
4
|
+
import { PanelForm } from '../core/PanelForm.js';
|
|
5
|
+
import { RouterReady } from '../core/Router.js';
|
|
6
|
+
import { s } from '../core/VanillaJs.js';
|
|
7
|
+
import { commonUserGuard } from '../core/CommonJs.js';
|
|
8
|
+
|
|
9
|
+
const LogInUnderpost = async function () {
|
|
10
|
+
LogIn.Event['LogInUnderpost'] = async (options) => {
|
|
11
|
+
const { token, user } = options;
|
|
12
|
+
|
|
13
|
+
ElementsUnderpost.Data.user.main.model.user = user;
|
|
14
|
+
|
|
15
|
+
await RouterReady;
|
|
16
|
+
await PanelForm.Data['underpost-panel'].updatePanel();
|
|
17
|
+
if (s(`.main-btn-cloud`) && commonUserGuard(user.role)) s(`.main-btn-cloud`).classList.remove('hide');
|
|
18
|
+
};
|
|
19
|
+
const { user } = await Auth.sessionIn();
|
|
20
|
+
ElementsUnderpost.Data.user.main.model.user = user;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { LogInUnderpost };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LogOut } from '../core/LogOut.js';
|
|
2
|
+
import { ElementsUnderpost } from './ElementsUnderpost.js';
|
|
3
|
+
import { PanelForm } from '../core/PanelForm.js';
|
|
4
|
+
import { s } from '../core/VanillaJs.js';
|
|
5
|
+
|
|
6
|
+
const LogOutUnderpost = async function () {
|
|
7
|
+
LogOut.Event['LogOutUnderpost'] = async (result = { user: { _id: '' } }) => {
|
|
8
|
+
ElementsUnderpost.Data.user.main.model.user = result.user;
|
|
9
|
+
|
|
10
|
+
PanelForm.Data['underpost-panel'].updatePanel();
|
|
11
|
+
if (s(`.main-btn-cloud`)) s(`.main-btn-cloud`).classList.add('hide');
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { LogOutUnderpost };
|