@zolomedia/bifrost-client 1.7.74
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/L1_Foundation/L1_Foundation.js +13 -0
- package/L1_Foundation/bootstrap/bootstrap.js +11 -0
- package/L1_Foundation/bootstrap/bootstrap_hooks.js +123 -0
- package/L1_Foundation/bootstrap/bootstrap_index.js +15 -0
- package/L1_Foundation/bootstrap/bootstrap_logger.js +135 -0
- package/L1_Foundation/bootstrap/cdn_loader.js +217 -0
- package/L1_Foundation/bootstrap/module_registry.js +102 -0
- package/L1_Foundation/bootstrap/prism_loader.js +164 -0
- package/L1_Foundation/config/client_config.js +110 -0
- package/L1_Foundation/config/config.js +7 -0
- package/L1_Foundation/connection/connection.js +8 -0
- package/L1_Foundation/connection/websocket_connection.js +122 -0
- package/L1_Foundation/constants/bifrost_constants.js +284 -0
- package/L1_Foundation/constants/constants.js +7 -0
- package/L1_Foundation/logger/logger.js +10 -0
- package/L2_Handling/L2_Handling.js +15 -0
- package/L2_Handling/cache/cache.js +22 -0
- package/L2_Handling/cache/cache_constants.js +69 -0
- package/L2_Handling/cache/orchestration/cache_manager.js +299 -0
- package/L2_Handling/cache/orchestration/cache_orchestrator.js +260 -0
- package/L2_Handling/cache/orchestration/orchestration.js +12 -0
- package/L2_Handling/cache/storage/session_manager.js +289 -0
- package/L2_Handling/cache/storage/storage.js +10 -0
- package/L2_Handling/cache/storage/storage_manager.js +590 -0
- package/L2_Handling/display/composite/composite.js +13 -0
- package/L2_Handling/display/composite/dashboard_renderer.js +221 -0
- package/L2_Handling/display/composite/swiper_renderer.js +564 -0
- package/L2_Handling/display/composite/terminal_renderer.js +922 -0
- package/L2_Handling/display/composite/wizard_conditional_renderer.js +274 -0
- package/L2_Handling/display/display.js +30 -0
- package/L2_Handling/display/feedback/feedback.js +11 -0
- package/L2_Handling/display/feedback/progressbar_renderer.js +418 -0
- package/L2_Handling/display/feedback/spinner_renderer.js +246 -0
- package/L2_Handling/display/inputs/button_renderer.js +634 -0
- package/L2_Handling/display/inputs/form_renderer.js +583 -0
- package/L2_Handling/display/inputs/input_renderer.js +658 -0
- package/L2_Handling/display/inputs/inputs.js +12 -0
- package/L2_Handling/display/navigation/menu_renderer.js +206 -0
- package/L2_Handling/display/navigation/navigation.js +11 -0
- package/L2_Handling/display/navigation/navigation_renderer.js +703 -0
- package/L2_Handling/display/orchestration/orchestration.js +11 -0
- package/L2_Handling/display/orchestration/renderer.js +430 -0
- package/L2_Handling/display/orchestration/zdisplay_orchestrator.js +1759 -0
- package/L2_Handling/display/outputs/alert_renderer.js +161 -0
- package/L2_Handling/display/outputs/audio_renderer.js +94 -0
- package/L2_Handling/display/outputs/card_renderer.js +229 -0
- package/L2_Handling/display/outputs/code_renderer.js +66 -0
- package/L2_Handling/display/outputs/dl_renderer.js +131 -0
- package/L2_Handling/display/outputs/header_renderer.js +162 -0
- package/L2_Handling/display/outputs/icon_renderer.js +107 -0
- package/L2_Handling/display/outputs/image_renderer.js +145 -0
- package/L2_Handling/display/outputs/list_renderer.js +190 -0
- package/L2_Handling/display/outputs/outputs.js +19 -0
- package/L2_Handling/display/outputs/table_renderer.js +765 -0
- package/L2_Handling/display/outputs/text_renderer.js +818 -0
- package/L2_Handling/display/outputs/typography_renderer.js +293 -0
- package/L2_Handling/display/outputs/video_renderer.js +116 -0
- package/L2_Handling/display/primitives/document_structure_primitives.js +319 -0
- package/L2_Handling/display/primitives/form_primitives.js +526 -0
- package/L2_Handling/display/primitives/generic_containers.js +109 -0
- package/L2_Handling/display/primitives/interactive_primitives.js +305 -0
- package/L2_Handling/display/primitives/link_primitives.js +552 -0
- package/L2_Handling/display/primitives/lists_primitives.js +262 -0
- package/L2_Handling/display/primitives/media_primitives.js +383 -0
- package/L2_Handling/display/primitives/primitives.js +19 -0
- package/L2_Handling/display/primitives/semantic_element_primitive.js +226 -0
- package/L2_Handling/display/primitives/table_primitives.js +528 -0
- package/L2_Handling/display/primitives/typography_primitives.js +175 -0
- package/L2_Handling/display/specialized/input_request_renderer.js +467 -0
- package/L2_Handling/display/specialized/specialized.js +10 -0
- package/L2_Handling/hooks/hooks.js +9 -0
- package/L2_Handling/hooks/menu_integration.js +57 -0
- package/L2_Handling/hooks/widget_hook_manager.js +292 -0
- package/L2_Handling/message/message.js +8 -0
- package/L2_Handling/message/message_handler.js +701 -0
- package/L2_Handling/navigation/navigation.js +8 -0
- package/L2_Handling/navigation/navigation_manager.js +403 -0
- package/L2_Handling/zhooks/features/cache_live.js +287 -0
- package/L2_Handling/zhooks/features/crumbs_live.js +292 -0
- package/L2_Handling/zhooks/zhooks_manager.js +65 -0
- package/L2_Handling/zvaf/zvaf.js +8 -0
- package/L2_Handling/zvaf/zvaf_manager.js +334 -0
- package/L3_Abstraction/L3_Abstraction.js +12 -0
- package/L3_Abstraction/orchestrator/container_unwrapper.js +101 -0
- package/L3_Abstraction/orchestrator/group_renderer.js +698 -0
- package/L3_Abstraction/orchestrator/input_event_handler.js +797 -0
- package/L3_Abstraction/orchestrator/metadata_processor.js +249 -0
- package/L3_Abstraction/orchestrator/navbar_builder.js +201 -0
- package/L3_Abstraction/orchestrator/orchestrator.js +13 -0
- package/L3_Abstraction/orchestrator/wizard_gate_handler.js +360 -0
- package/L3_Abstraction/renderer/renderer.js +1 -0
- package/L3_Abstraction/session/session.js +1 -0
- package/L4_Orchestration/L4_Orchestration.js +11 -0
- package/L4_Orchestration/client/client.js +1 -0
- package/L4_Orchestration/facade/facade.js +9 -0
- package/L4_Orchestration/facade/manager_registry.js +118 -0
- package/L4_Orchestration/facade/renderer_registry.js +274 -0
- package/L4_Orchestration/lifecycle/asset_loader.js +255 -0
- package/L4_Orchestration/lifecycle/initializer.js +135 -0
- package/L4_Orchestration/lifecycle/lifecycle.js +8 -0
- package/L4_Orchestration/rendering/facade.js +94 -0
- package/L4_Orchestration/rendering/rendering.js +7 -0
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/bifrost_client.js +204 -0
- package/bifrost_core.js +1686 -0
- package/docs/ARCHITECTURE.md +111 -0
- package/docs/PROTOCOL.md +106 -0
- package/docs/RENDERERS.md +101 -0
- package/docs/SECURITY.md +92 -0
- package/package.json +24 -0
- package/syntax/prism-zconfig.js +41 -0
- package/syntax/prism-zenv.js +69 -0
- package/syntax/prism-zolo-theme.css +288 -0
- package/syntax/prism-zolo.js +380 -0
- package/syntax/prism-zschema.js +38 -0
- package/syntax/prism-zspark.js +25 -0
- package/syntax/prism-zui.js +68 -0
- package/zSys/accessibility/accessibility.js +10 -0
- package/zSys/accessibility/emoji_accessibility.js +173 -0
- package/zSys/dom/block_utils.js +122 -0
- package/zSys/dom/container_utils.js +370 -0
- package/zSys/dom/dom.js +13 -0
- package/zSys/dom/dom_utils.js +328 -0
- package/zSys/dom/encoding_utils.js +117 -0
- package/zSys/dom/style_utils.js +71 -0
- package/zSys/errors/error_display.js +299 -0
- package/zSys/errors/errors.js +10 -0
- package/zSys/theme/color_utils.js +274 -0
- package/zSys/theme/dark_mode_utils.js +272 -0
- package/zSys/theme/size_utils.js +256 -0
- package/zSys/theme/spacing_utils.js +405 -0
- package/zSys/theme/theme.js +14 -0
- package/zSys/theme/zbase.css +1735 -0
- package/zSys/theme/zbase_inject.js +161 -0
- package/zSys/theme/ztheme_utils.js +305 -0
- package/zSys/validation/error_boundary.js +201 -0
- package/zSys/validation/validation.js +11 -0
- package/zSys/validation/validation_utils.js +238 -0
- package/zSys/zSys.js +14 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MenuRenderer - Handles menu rendering and interaction in Bifrost mode
|
|
3
|
+
*
|
|
4
|
+
* This module provides:
|
|
5
|
+
* - Menu HTML rendering with zTheme classes
|
|
6
|
+
* - Click event handlers for menu options
|
|
7
|
+
* - Keyboard navigation support
|
|
8
|
+
* - WebSocket communication for menu selection
|
|
9
|
+
*
|
|
10
|
+
* Integrates with:
|
|
11
|
+
* - zDisplay (via zdisplay_orchestrator.js)
|
|
12
|
+
* - BifrostClient (for WebSocket messaging)
|
|
13
|
+
* - zTheme (for consistent styling)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export class MenuRenderer {
|
|
17
|
+
constructor(logger, client) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
this.logger = logger;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Render menu from backend menu event (full-page menu)
|
|
24
|
+
* @param {Object} message - Menu event data from backend
|
|
25
|
+
*/
|
|
26
|
+
renderMenu(message) {
|
|
27
|
+
this.logger.log('[MenuRenderer] Rendering menu', message);
|
|
28
|
+
|
|
29
|
+
const { menu_key, options, title, breadcrumbs, requestId } = message;
|
|
30
|
+
|
|
31
|
+
// Store requestId so selection handler can echo it back to backend
|
|
32
|
+
this._currentRequestId = requestId || null;
|
|
33
|
+
// Normalise menu key — backend may send title+options without menu_key
|
|
34
|
+
const resolvedMenuKey = menu_key || title || 'Menu';
|
|
35
|
+
|
|
36
|
+
const contentElement = this.client._zVaFElement;
|
|
37
|
+
if (!contentElement) {
|
|
38
|
+
this.logger.error('[MenuRenderer] [ERROR] zVaF element not found');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
contentElement.innerHTML = '';
|
|
43
|
+
|
|
44
|
+
if (breadcrumbs && Object.keys(breadcrumbs).length > 0) {
|
|
45
|
+
this._renderBreadcrumbs(breadcrumbs, contentElement);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const menuHtml = this._createMenuHTML(resolvedMenuKey, options, title || null);
|
|
49
|
+
contentElement.innerHTML += menuHtml;
|
|
50
|
+
|
|
51
|
+
this._attachMenuHandlers(resolvedMenuKey, options);
|
|
52
|
+
this.logger.log('[MenuRenderer] Menu rendered successfully');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Render menu inline (within a specific container, e.g., dashboard panel)
|
|
57
|
+
* @param {Object} menuData - Menu data { menu_key, options, title, allow_back }
|
|
58
|
+
* @param {HTMLElement} container - Container element to render menu into
|
|
59
|
+
*/
|
|
60
|
+
renderMenuInline(menuData, container) {
|
|
61
|
+
this.logger.log('[MenuRenderer] Rendering inline menu', menuData);
|
|
62
|
+
|
|
63
|
+
const { menu_key, options, title, _allow_back, requestId } = menuData;
|
|
64
|
+
|
|
65
|
+
// Store requestId for selection echo
|
|
66
|
+
this._currentRequestId = requestId || null;
|
|
67
|
+
|
|
68
|
+
// Create menu HTML
|
|
69
|
+
const menuHtml = this._createMenuHTML(menu_key || 'Menu', options, title);
|
|
70
|
+
|
|
71
|
+
// Insert into container
|
|
72
|
+
const tempDiv = document.createElement('div');
|
|
73
|
+
tempDiv.innerHTML = menuHtml;
|
|
74
|
+
const menuElement = tempDiv.firstElementChild;
|
|
75
|
+
|
|
76
|
+
if (menuElement && container) {
|
|
77
|
+
container.appendChild(menuElement);
|
|
78
|
+
|
|
79
|
+
// Attach event handlers
|
|
80
|
+
this._attachMenuHandlers(menu_key || 'Menu', options, menuElement);
|
|
81
|
+
|
|
82
|
+
this.logger.log('[MenuRenderer] Inline menu rendered successfully');
|
|
83
|
+
} else {
|
|
84
|
+
this.logger.error('[MenuRenderer] [ERROR] Failed to render inline menu');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create menu HTML with zTheme classes
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
_createMenuHTML(menuKey, options, customTitle = null) {
|
|
93
|
+
const menuTitle = customTitle || menuKey.replace(/[*~]/g, '').trim() || 'Menu';
|
|
94
|
+
|
|
95
|
+
return `
|
|
96
|
+
<div class="zMenu-container zCard zp-4 zmy-4" data-menu="${this._escapeHtml(menuKey)}">
|
|
97
|
+
<h2 class="zCard-title zmb-4">${this._escapeHtml(menuTitle)}</h2>
|
|
98
|
+
<div class="zMenu-options">
|
|
99
|
+
${options.map((opt, idx) => this._createOptionHTML(opt, idx)).join('')}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Create HTML for a single menu option
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
_createOptionHTML(option, index) {
|
|
110
|
+
const label = option.label || option.key || option;
|
|
111
|
+
const key = option.key || option;
|
|
112
|
+
|
|
113
|
+
return `
|
|
114
|
+
<div class="zMenu-option zmb-2" data-key="${this._escapeHtml(key)}">
|
|
115
|
+
<button class="zBtn zBtn-outline-primary w-100 text-start zp-3" data-index="${index}">
|
|
116
|
+
<span class="zBadge zBadge-secondary me-2">${index + 1}</span>
|
|
117
|
+
${this._escapeHtml(label.replace(/[*~^$]/g, ''))}
|
|
118
|
+
</button>
|
|
119
|
+
</div>
|
|
120
|
+
`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Render breadcrumbs
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
_renderBreadcrumbs(breadcrumbs, container) {
|
|
128
|
+
const breadcrumbsHtml = `
|
|
129
|
+
<nav aria-label="breadcrumb" class="zmb-3">
|
|
130
|
+
<ol class="breadcrumb">
|
|
131
|
+
${Object.entries(breadcrumbs).map(([_scope, trail]) => `
|
|
132
|
+
<li class="breadcrumb-item active">${this._escapeHtml(trail)}</li>
|
|
133
|
+
`).join('')}
|
|
134
|
+
</ol>
|
|
135
|
+
</nav>
|
|
136
|
+
`;
|
|
137
|
+
container.innerHTML = breadcrumbsHtml;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Attach click and keyboard handlers to menu options
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
_attachMenuHandlers(menuKey, options, containerElement = null) {
|
|
145
|
+
// If container is provided, scope query to it; otherwise use document
|
|
146
|
+
const root = containerElement || document;
|
|
147
|
+
const optionButtons = root.querySelectorAll('.zMenu-option button');
|
|
148
|
+
|
|
149
|
+
optionButtons.forEach((button, _idx) => {
|
|
150
|
+
button.addEventListener('click', () => {
|
|
151
|
+
const optionDiv = button.closest('.zMenu-option');
|
|
152
|
+
const selectedKey = optionDiv.dataset.key;
|
|
153
|
+
|
|
154
|
+
this.logger.log('[MenuRenderer] Menu selection:', selectedKey);
|
|
155
|
+
this.logger.log('[MenuRenderer] Menu selection', { menu: menuKey, selected: selectedKey });
|
|
156
|
+
|
|
157
|
+
// Visual feedback
|
|
158
|
+
button.classList.add('active');
|
|
159
|
+
button.disabled = true;
|
|
160
|
+
|
|
161
|
+
// Send selection to backend
|
|
162
|
+
this._sendMenuSelection(menuKey, selectedKey);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Keyboard navigation (0-9 for options)
|
|
167
|
+
const keydownHandler = (e) => {
|
|
168
|
+
const num = parseInt(e.key);
|
|
169
|
+
if (!isNaN(num) && num < optionButtons.length) {
|
|
170
|
+
optionButtons[num].click();
|
|
171
|
+
// Remove handler after selection
|
|
172
|
+
document.removeEventListener('keydown', keydownHandler);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
document.addEventListener('keydown', keydownHandler);
|
|
177
|
+
this.logger.log('[MenuRenderer] Keyboard navigation enabled (0-9)');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Send menu selection to backend via WebSocket
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
_sendMenuSelection(menuKey, selected) {
|
|
185
|
+
const message = {
|
|
186
|
+
event: 'menu_selection',
|
|
187
|
+
menu_key: menuKey,
|
|
188
|
+
selected: selected,
|
|
189
|
+
requestId: this._currentRequestId || undefined,
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
this.logger.log('[MenuRenderer] Sending menu selection to backend:', message);
|
|
193
|
+
this.client.send(message);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Escape HTML to prevent XSS
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
_escapeHtml(text) {
|
|
201
|
+
const div = document.createElement('div');
|
|
202
|
+
div.textContent = text;
|
|
203
|
+
return div.innerHTML;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation Rendering Module Barrel Export
|
|
3
|
+
*
|
|
4
|
+
* Navigation components (menus, breadcrumbs, navigation bars).
|
|
5
|
+
*
|
|
6
|
+
* @module rendering/navigation
|
|
7
|
+
* @layer 3 (Navigation Rendering)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './menu_renderer.js';
|
|
11
|
+
export * from './navigation_renderer.js';
|