|
23 | 23 | <script type="text/javascript" src="scripts/messages/messageList/uploadLog.widget.js"></script> |
24 | 24 | <script type="text/javascript" src="scripts/messages/messageList/messageList.widget.js"></script> |
25 | 25 | <script type="text/javascript" src="scripts/messages/doc/messageDoc.js"></script> |
| 26 | + <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> |
| 27 | + <script type="text/javascript" src="scripts/messages/entityFlow/intellicenterMappings.js"></script> |
| 28 | + <script type="text/javascript" src="scripts/messages/entityFlow/entityFlow.widget.js"></script> |
26 | 29 | <link rel="stylesheet" type="text/css" href="jquery-ui/jquery-ui.css" /> |
27 | 30 | <link rel="stylesheet" type="text/css" href="jquery-ui/jquery-ui.theme.css" /> |
28 | 31 | <link rel="stylesheet" type="text/css" href="font-awesome/css/all.css" /> |
29 | 32 | <link rel="stylesheet" type="text/css" href="themes/widgets.css" /> |
30 | 33 | <link rel="stylesheet" type="text/css" href="themes/controller.css" /> |
31 | 34 | <link rel="stylesheet" type="text/css" href="themes/vlist.css" /> |
32 | 35 | <link rel="stylesheet" type="text/css" href="themes/messageManager.css" /> |
| 36 | + <link rel="stylesheet" type="text/css" href="scripts/messages/entityFlow/entityFlow.css" /> |
33 | 37 | <!-- Blank stylesheet for message responses --> |
34 | 38 | <style id="responseStyles" type="text/css"> |
35 | 39 | </style> |
|
46 | 50 | <div class="picController picControlPanel control-panel" style="display:block;"></div> |
47 | 51 | </header> |
48 | 52 | <div class="messageContainer"> |
49 | | - <div class="sendQueueTopContainer"> |
| 53 | + <!-- Tab Navigation (Settings-style tabBar widget) --> |
| 54 | + <div class="mmgrTabHeader"> |
| 55 | + <div class="mmgrTabBar"></div> |
| 56 | + <div class="view-bar-actions"> |
| 57 | + <span class="view-bar-status" title="Replay load status"></span> |
| 58 | + <button type="button" class="view-bar-icon-btn view-bar-clear" title="Clear Messages"> |
| 59 | + <i class="fas fa-broom"></i> |
| 60 | + </button> |
| 61 | + <button type="button" class="view-bar-icon-btn view-bar-filter" title="Filter Display"> |
| 62 | + <i class="fas fa-filter"></i> |
| 63 | + </button> |
| 64 | + <button type="button" class="upload-btn view-bar-upload" title="Choose Files"> |
| 65 | + <i class="fas fa-folder-open"></i> Choose Files |
| 66 | + </button> |
| 67 | + <input id="universalReplayFileInput" type="file" accept=".json,.zip,.log" multiple style="display:none;" /> |
| 68 | + </div> |
| 69 | + </div> |
| 70 | + <!-- Message List View --> |
| 71 | + <div class="view-container active" data-view="messages"> |
| 72 | + <div class="messagesContentContainer"> |
| 73 | + <div class="picMessages picControlPanel control-panel" style="display:block;"></div> |
| 74 | + <div class="picMessageDetail picControlPanel control-panel" style="display:none;"></div> |
| 75 | + </div> |
| 76 | + </div> |
| 77 | + <!-- Send Queue View --> |
| 78 | + <div class="view-container" data-view="sendQueue"> |
50 | 79 | <div class="picSendMessageQueue picControlPanel control-panel" style="display:block;"></div> |
51 | 80 | </div> |
52 | | - <div class="messagesContentContainer"> |
53 | | - <div class="picMessages picControlPanel control-panel" style="display:block;"></div> |
54 | | - <div class="picMessageDetail picControlPanel control-panel" style="display:none;"></div> |
| 81 | + <!-- Entity Flow View --> |
| 82 | + <div class="view-container" data-view="entityFlow"> |
| 83 | + <div class="picEntityFlow picControlPanel control-panel" style="display:block;width:100%;"></div> |
55 | 84 | </div> |
56 | 85 | </div> |
57 | 86 | </div> |
|
69 | 98 | $('div.picMessages').messageList(); |
70 | 99 | $('div.picSendMessageQueue').sendMessageQueue(); |
71 | 100 | $('div.picMessageDetail').messageDetail(); |
| 101 | + $('div.picEntityFlow').entityFlow(); |
| 102 | + |
| 103 | + // Settings-style tab bar for view switching (matches config/settings tabs) |
| 104 | + var $mmTabBar = $('div.mmgrTabBar'); |
| 105 | + $mmTabBar.tabBar(); |
| 106 | + // Hide built-in tab contents panel; we drive our existing view containers below. |
| 107 | + $mmTabBar.find('div.picTabContents:first').hide(); |
| 108 | + |
| 109 | + // Add tabs |
| 110 | + $mmTabBar[0].addTab({ id: 'tabMessages', text: 'Message List' }); |
| 111 | + $mmTabBar[0].addTab({ id: 'tabSendQueue', text: 'Send Queue' }); |
| 112 | + $mmTabBar[0].addTab({ id: 'tabEntityFlow', text: 'Entity Flow' }); |
| 113 | + |
| 114 | + // Inject icons into tab labels |
| 115 | + $mmTabBar.find('div.picTab[data-tabid="tabMessages"] span.picTabText:first') |
| 116 | + .html('<i class="fas fa-list"></i>Message List'); |
| 117 | + $mmTabBar.find('div.picTab[data-tabid="tabSendQueue"] span.picTabText:first') |
| 118 | + .html('<i class="fas fa-paper-plane"></i>Send Queue'); |
| 119 | + $mmTabBar.find('div.picTab[data-tabid="tabEntityFlow"] span.picTabText:first') |
| 120 | + .html('<i class="fas fa-project-diagram"></i>Entity Flow'); |
| 121 | + |
| 122 | + // Move actions into the tab row (right aligned) |
| 123 | + var $tabsRow = $mmTabBar.find('div.picTabs:first'); |
| 124 | + $('<div class="mmgrTabSpacer"></div>').appendTo($tabsRow); |
| 125 | + $('.view-bar-actions').appendTo($tabsRow); |
| 126 | + |
| 127 | + // View switching on tab change |
| 128 | + $mmTabBar.on('tabchange', function (evt) { |
| 129 | + var viewName = 'messages'; |
| 130 | + switch (evt.newTab.id) { |
| 131 | + case 'tabSendQueue': |
| 132 | + viewName = 'sendQueue'; |
| 133 | + break; |
| 134 | + case 'tabEntityFlow': |
| 135 | + viewName = 'entityFlow'; |
| 136 | + break; |
| 137 | + case 'tabMessages': |
| 138 | + default: |
| 139 | + viewName = 'messages'; |
| 140 | + break; |
| 141 | + } |
| 142 | + $('.view-container').removeClass('active'); |
| 143 | + $('.view-container[data-view="' + viewName + '"]').addClass('active'); |
| 144 | + }); |
| 145 | + |
| 146 | + // Select initial tab (align with initial view-container.active) |
| 147 | + $mmTabBar[0].selectTabById('tabMessages'); |
| 148 | + |
| 149 | + // Universal fast replay loader (ZIP / .log / JSON) |
| 150 | + var $replayInput = $('#universalReplayFileInput'); |
| 151 | + var $replayBtn = $('.view-bar-upload'); |
| 152 | + var $replayStatus = $('.view-bar-status'); |
| 153 | + var $clearBtn = $('.view-bar-clear'); |
| 154 | + var $filterBtn = $('.view-bar-filter'); |
| 155 | + |
| 156 | + $replayBtn.on('click', function(e) { |
| 157 | + e.preventDefault(); |
| 158 | + $replayInput[0].click(); |
| 159 | + }); |
| 160 | + |
| 161 | + // Show status updates emitted from Entity Flow widget |
| 162 | + $('div.picEntityFlow').on('replayLoadStatus', function(e) { |
| 163 | + $replayStatus.text(e.text || ''); |
| 164 | + }); |
| 165 | + |
| 166 | + $replayInput.on('change', function(e) { |
| 167 | + var files = e.target.files; |
| 168 | + if (!files || files.length === 0) return; |
| 169 | + // Always clear & import via Entity Flow (it also populates Message List for shared navigation) |
| 170 | + var ef = $('div.picEntityFlow')[0]; |
| 171 | + if (ef && ef.importFiles) { |
| 172 | + ef.importFiles(files); |
| 173 | + } |
| 174 | + // Reset input so selecting same files again triggers change |
| 175 | + $replayInput.val(''); |
| 176 | + }); |
| 177 | + |
| 178 | + // Universal Clear (clears messages + entity flow state) |
| 179 | + $clearBtn.on('click', function(e) { |
| 180 | + e.preventDefault(); |
| 181 | + var ef = $('div.picEntityFlow')[0]; |
| 182 | + if (ef && ef.clearAll) ef.clearAll(); |
| 183 | + var ml = $('div.picMessages:first')[0]; |
| 184 | + if (ml && ml.clear) ml.clear(); |
| 185 | + $replayStatus.text(''); |
| 186 | + // Reset upload button text |
| 187 | + $replayBtn.html('<i class="fas fa-folder-open"></i> Choose Files'); |
| 188 | + $replayBtn.attr('title', 'Choose Files'); |
| 189 | + }); |
| 190 | + |
| 191 | + // Universal Filter dialog (operates on Message List) |
| 192 | + $filterBtn.on('click', function(e) { |
| 193 | + e.preventDefault(); |
| 194 | + var ml = $('div.picMessages:first')[0]; |
| 195 | + if (ml && ml.openFilterDialog) ml.openFilterDialog(); |
| 196 | + }); |
| 197 | + |
| 198 | + // When entity type changes, apply corresponding packet matchers as filters in Message List |
| 199 | + $('div.picEntityFlow').on('entityTypeChanged', function(e) { |
| 200 | + var ml = $('div.picMessages:first')[0]; |
| 201 | + if (ml && ml.applyPacketMatchers) { |
| 202 | + ml.applyPacketMatchers(e.matchers || []); |
| 203 | + } |
| 204 | + }); |
| 205 | + |
| 206 | + // Listen for navigation from entity flow to message list |
| 207 | + $('div.picEntityFlow').on('navigateToPacket', function(e) { |
| 208 | + // Switch to message list tab |
| 209 | + var tb = $('div.mmgrTabBar')[0]; |
| 210 | + if (tb && tb.selectTabById) tb.selectTabById('tabMessages'); |
| 211 | + |
| 212 | + // Scroll to the packet |
| 213 | + var messageList = $('div.picMessages')[0]; |
| 214 | + if (messageList && messageList.scrollToMessage) { |
| 215 | + setTimeout(function() { |
| 216 | + messageList.scrollToMessage(e.packetIndex); |
| 217 | + }, 100); |
| 218 | + } |
| 219 | + }); |
72 | 220 | }); |
73 | 221 | </script> |
74 | 222 | </body> |
|
0 commit comments