freshroute-server
Version:
Local development server for FreshRoute extension with API mocking and extended functionality
1 lines โข 15.4 kB
HTML
<html><head><meta charset="utf-8"><title>FreshRoute - Live Rule Testing Dashboard</title><style>*{box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;margin:0;padding:20px;background-color:#f5f5f5;font-size:14px}.container{max-width:95%;margin:0 auto;background:#fff;border-radius:8px;box-shadow:0 2px 10px rgba(0,0,0,.1);overflow:hidden}.header{background:linear-gradient(135deg,#ff6b35,#f79a3e);color:#fff;padding:30px}.header-content{display:flex;align-items:center;justify-content:space-between;max-width:100%}.header-left h1{margin:0 0 10px 0;font-size:24px;font-weight:300;display:flex;align-items:center;gap:12px}.header-logo{font-size:32px;display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;background:#fff;border-radius:12px;backdrop-filter:blur(10px);border:2px solid rgba(255,255,255,.2);transition:all .3s ease;padding:6px}.header-logo img{width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 2px 4px rgba(0, 0, 0, .1))}.header-left p{margin:0;opacity:.9;font-size:16px}.back-btn{background:rgba(255,255,255,.15);border:2px solid rgba(255,255,255,.3);color:#fff;padding:12px 20px;border-radius:8px;cursor:pointer;font-size:14px;font-weight:500;display:flex;align-items:center;gap:8px;transition:all .3s ease;backdrop-filter:blur(10px);text-decoration:none}.back-btn:hover{background:rgba(255,255,255,.25);border-color:rgba(255,255,255,.5);transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.2)}.network-recorder-btn{background:rgba(255,255,255,.15);border:2px solid rgba(255,255,255,.3);color:#fff;padding:12px 20px;border-radius:8px;cursor:pointer;font-size:14px;font-weight:500;display:flex;align-items:center;gap:8px;transition:all .3s ease;backdrop-filter:blur(10px);margin-right:15px}.network-recorder-btn:hover{background:rgba(255,255,255,.25);border-color:rgba(255,255,255,.5);transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.2)}.content{padding:30px}.monitoring-section{background:#fff;border-radius:12px;padding:20px;margin-bottom:30px;box-shadow:0 2px 8px rgba(0,0,0,.1)}.monitoring-section .section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:2px solid #e0e0e0}.monitoring-controls{display:flex;gap:10px;align-items:center;margin-bottom:15px}.monitoring-section .log-container{max-height:200px;font-size:11px}.testing-section{background:#fff;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.1);overflow:hidden}.testing-section .section-header{padding:20px 20px 0 20px;margin-bottom:0;border-bottom:none}.testing-tabs{display:flex;background:#f8f9fa;border-bottom:1px solid #e0e0e0}.tab-btn{background:0 0;border:none;padding:15px 25px;cursor:pointer;font-size:14px;font-weight:500;color:#666;border-bottom:3px solid transparent;transition:all .3s ease;position:relative}.tab-btn:hover{background:rgba(255,107,53,.1);color:#ff6b35}.tab-btn.active{background:#fff;color:#ff6b35;border-bottom-color:#ff6b35;font-weight:600}.tab-content{display:none;padding:25px}.tab-content.active{display:block}.tab-description{background:#f8f9fa;padding:15px;border-radius:8px;margin-bottom:20px;border-left:4px solid #ff6b35}.tab-description p{margin:0;color:#666;font-size:14px}.section{margin-bottom:30px}.section-header{display:flex;align-items:center;justify-content:between;margin-bottom:20px;padding-bottom:10px;border-bottom:2px solid #e0e0e0}.section-title{font-size:18px;font-weight:600;color:#2c5f41}.controls{display:flex;gap:10px;align-items:center;margin-bottom:20px}.btn{padding:8px 16px;border:none;border-radius:6px;cursor:pointer;font-size:14px;font-weight:500;transition:all .3s}.btn-primary{background:#00c896;color:#fff}.btn-primary:hover{background:#00b085;transform:translateY(-1px)}.btn-secondary{background:#6b7280;color:#fff}.btn-secondary:hover{background:#4b5563;transform:translateY(-1px)}.btn-danger{background:#f44336;color:#fff}.btn-danger:hover{background:#d32f2f;transform:translateY(-1px)}.monitoring-status{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:6px;font-size:13px;font-weight:500}.monitoring-status.active{background:#e8f5e8;color:#2e7d32}.monitoring-status.inactive{background:#ffebee;color:#c62828}.status-dot{width:8px;height:8px;border-radius:50%;background:currentColor}.log-container{background:#1e1e1e;border-radius:6px;padding:15px;max-height:400px;overflow-y:auto;font-family:Monaco,Consolas,monospace;font-size:12px}.log-entry{margin-bottom:8px;padding:6px 8px;border-radius:4px;border-left:3px solid}.log-entry.success{background:rgba(76,175,80,.1);border-left-color:#4caf50;color:#81c784}.log-entry.redirect{background:rgba(33,150,243,.1);border-left-color:#2196f3;color:#64b5f6}.log-entry.header{background:rgba(156,39,176,.1);border-left-color:#9c27b0;color:#ba68c8}.log-entry.error{background:rgba(244,67,54,.1);border-left-color:#f44336;color:#e57373}.log-timestamp{color:#888;margin-right:8px}.log-url{color:#fff;font-weight:500}.log-rule{color:#ffb74d;font-style:italic}.test-url-section{background:#f8f9fa;border:1px solid #e0e0e0;border-radius:8px;padding:20px;margin-bottom:20px}.url-input-group{display:flex;gap:10px;margin-bottom:15px}.url-input{flex:1;padding:12px 16px;border:1px solid #ddd;border-radius:6px;font-size:14px;font-family:Monaco,Consolas,monospace}.url-input:focus{outline:0;border-color:#ff6b35;box-shadow:0 0 0 3px rgba(255,107,53,.1)}.test-result{padding:15px;border-radius:6px;margin-top:10px;font-family:Monaco,Consolas,monospace;font-size:13px}.test-result.match{background:#e8f5e8;border:1px solid #c8e6c9;color:#2e7d32}.test-result.no-match{background:#fff3e0;border:1px solid #ffe0b2;color:#f57c00}.footer{text-align:center;padding:20px;background:#f8f9fa;border-top:1px solid #e0e0e0;color:#666;font-size:12px}@media (max-width:768px){.url-input-group{flex-direction:column}.monitoring-controls{flex-wrap:wrap;gap:8px}.monitoring-section .section-header{flex-direction:column;align-items:flex-start;gap:10px}.testing-tabs{flex-direction:column}.tab-btn{text-align:left;border-bottom:none;border-right:3px solid transparent}.tab-btn.active{border-bottom:none;border-right-color:#ff6b35}.content{padding:15px}.monitoring-section,.testing-section{margin-bottom:20px}}.url-testing{display:flex;gap:20px;align-items:flex-start}.url-input-section{flex:1}.test-result{margin-top:15px;padding:15px;border-radius:8px;font-family:Monaco,Menlo,monospace;font-size:14px;line-height:1.6}.test-result.match{background:linear-gradient(135deg,#d4edda 0,#c3e6cb 100%);border:2px solid #28a745;color:#155724}.test-result.no-match{background:linear-gradient(135deg,#f8d7da 0,#f5c6cb 100%);border:2px solid #dc3545;color:#721c24}.debugger-container{background:#fff;border-radius:12px;padding:25px;box-shadow:0 4px 20px rgba(0,0,0,.1)}.debugger-input{margin-bottom:25px}.debugger-controls{display:flex;gap:15px;align-items:center;margin-top:15px}.checkbox-label{display:flex;align-items:center;gap:8px;font-size:14px;color:#666;cursor:pointer}.checkbox-label input[type=checkbox]{margin:0}.debugger-results{min-height:400px}.debugger-placeholder{text-align:center;padding:60px 20px;color:#666}.placeholder-icon{font-size:48px;margin-bottom:20px}.placeholder-icon+h3{margin:0 0 15px 0;color:#333}.feature-list{list-style:none;padding:0;margin:25px 0 0 0;display:inline-block;text-align:left}.feature-list li{padding:8px 0;font-size:14px}.rule-debug-card{background:#f8f9fa;border:2px solid #e9ecef;border-radius:12px;margin-bottom:20px;overflow:hidden;transition:all .3s ease}.rule-debug-card.matching{border-color:#28a745;background:linear-gradient(135deg,#d4edda 0,#f8f9fa 100%)}.rule-debug-card.non-matching{border-color:#dc3545;background:linear-gradient(135deg,#f8d7da 0,#f8f9fa 100%)}.rule-debug-header{padding:20px;background:#fff;border-bottom:1px solid #e9ecef;cursor:pointer;transition:background-color .2s ease}.rule-debug-header:hover{background:#f8f9fa}.rule-debug-title{display:flex;justify-content:between;align-items:center;gap:15px}.rule-debug-expand{font-size:16px;transition:transform .2s ease;color:#666}.rule-debug-expand.expanded{transform:rotate(180deg)}.rule-info{flex:1}.rule-name{font-weight:600;font-size:16px;color:#333;margin-bottom:5px}.rule-type-badge{display:inline-block;padding:4px 12px;border-radius:20px;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.rule-type-badge.url-rewrite{background:#e3f2fd;color:#1976d2}.rule-type-badge.modify-headers{background:#f3e5f5;color:#7b1fa2}.match-status{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px}.match-status.success{color:#28a745}.match-status.failure{color:#dc3545}.rule-debug-content{padding:0 20px 20px 20px;display:none}.rule-debug-content.expanded{display:block}.debug-step{margin-bottom:20px;padding:15px;background:#fff;border-radius:8px;border-left:4px solid #007bff}.debug-step.success{border-left-color:#28a745}.debug-step.failure{border-left-color:#dc3545}.debug-step.info{border-left-color:#17a2b8}.step-title{font-weight:600;margin-bottom:10px;color:#333}.step-content{font-family:Monaco,Menlo,monospace;font-size:13px;line-height:1.5}.pattern-comparison{display:grid;grid-template-columns:1fr 1fr;gap:15px;margin:10px 0}.pattern-after,.pattern-before{padding:10px;border-radius:6px;font-family:Monaco,Menlo,monospace;font-size:12px}.pattern-before{background:#fff3cd;border:1px solid #ffeaa7}.pattern-after{background:#d1ecf1;border:1px solid #bee5eb}.regex-match-visual{background:#f8f9fa;border:1px solid #dee2e6;border-radius:6px;padding:15px;margin:10px 0}.url-parts{font-family:Monaco,Menlo,monospace;font-size:14px;line-height:1.8;word-break:break-all}.url-part{padding:2px 4px;border-radius:3px;margin:0 1px}.url-part.matched{background:#28a745;color:#fff}.url-part.captured{background:#007bff;color:#fff}.url-part.unmatched{background:#6c757d;color:#fff}.capture-groups{background:#e3f2fd;border:1px solid #bbdefb;border-radius:6px;padding:12px;margin:10px 0}.capture-group{display:inline-block;margin:2px 5px;padding:4px 8px;background:#1976d2;color:#fff;border-radius:4px;font-family:Monaco,Menlo,monospace;font-size:12px}.target-preview{background:#d4edda;border:1px solid #c3e6cb;border-radius:6px;padding:12px;margin:10px 0}.failure-reason{background:#f8d7da;border:1px solid #f5c6cb;border-radius:6px;padding:12px;margin:10px 0;color:#721c24}.variable-substitutions{background:#fff3cd;border:1px solid #ffeaa7;border-radius:6px;padding:12px;margin:10px 0}.variable-sub{font-family:Monaco,Menlo,monospace;font-size:12px;margin:5px 0}.variable-sub .var-name{color:#e83e8c;font-weight:700}.variable-sub .var-value{color:#28a745;font-weight:700}.form-group{margin-bottom:15px}.form-label{display:block;margin-bottom:5px;font-weight:600;color:#333}.form-input{width:100%;padding:12px 16px;border:1px solid #ddd;border-radius:6px;font-size:14px;font-family:Monaco,Consolas,monospace}.form-input:focus{outline:0;border-color:#ff6b35;box-shadow:0 0 0 3px rgba(255,107,53,.1)}.debug-summary{margin-bottom:25px;padding:20px;background:linear-gradient(135deg,#f8f9fa 0,#e9ecef 100%);border-radius:8px;border-left:4px solid #007bff}.debug-stats{display:flex;gap:20px;margin-top:10px}.debug-stats .stat{padding:8px 12px;background:#fff;border-radius:6px;font-size:14px;font-weight:600;border:1px solid #dee2e6}.debug-stats .stat.success{color:#28a745;background:#d4edda;border-color:#c3e6cb}.debug-stats .stat.failure{color:#dc3545;background:#f8d7da;border-color:#f5c6cb}.rule-debug-item{background:#f8f9fa;border-radius:8px;padding:15px;margin-bottom:15px;border:1px solid #dee2e6}.rule-debug-summary{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid #dee2e6}.rule-steps{margin-top:10px}.group-summary{font-size:12px;color:#666;margin-top:2px}</style></head><body><div class="container"><div class="header"><div class="header-content"><div class="header-left"><h1><span class="header-logo"><img src="icons/icon128.png" alt="FreshRoute Logo"> </span>Live Rule Testing Dashboard</h1><p>Monitor and test your rules in real-time</p></div><div class="header-right"><button class="network-recorder-btn" id="openNetworkRecorderBtn"><span>๐ฌ</span> <span>Network Recorder</span></button> <a href="options.html" class="back-btn"><span>โ</span> <span>Back to Rules</span></a></div></div></div><div class="content"><div class="monitoring-section"><div class="section-header"><div class="section-title">๐ Real-time Monitoring</div><div class="monitoring-status inactive" id="monitoringStatus"><div class="status-dot"></div><span>Monitoring Stopped</span></div></div><div class="monitoring-controls"><button class="btn btn-primary" id="startMonitoringBtn">Start Monitoring</button> <button class="btn btn-secondary" id="pauseMonitoringBtn" disabled="disabled">Pause</button> <button class="btn btn-danger" id="clearLogsBtn">Clear Logs</button></div><div class="log-container" id="liveLogContainer"><div class="log-entry"><span class="log-timestamp">[No activity yet]</span> <span class="log-url">Start monitoring to see live rule activity...</span></div></div></div><div class="testing-section"><div class="section-header"><div class="section-title">๐งช Rule Testing Tools</div></div><div class="testing-tabs"><button class="tab-btn active" data-tab="quick-test">โก Quick Test</button> <button class="tab-btn" data-tab="visual-debugger">๐ Visual Debugger</button></div><div class="tab-content active" id="quick-test"><div class="tab-description"><p>Test a URL against all your rules to see which ones match and what actions would be taken.</p></div><div class="test-url-section"><div class="url-input-group"><input class="url-input" id="testUrlInput" placeholder="Enter URL to test (e.g., http://localhost.freshservice-dev.com:3000/api/users)"> <button class="btn btn-primary" id="testUrlBtn">Test URL</button></div><div id="testResult"></div></div></div><div class="tab-content" id="visual-debugger"><div class="tab-description"><p>Step-by-step analysis of how URLs match against your rules with detailed pattern matching visualization.</p></div><div class="debugger-container"><div class="debugger-input"><div class="form-group"><label for="debugUrlInput" class="form-label">Test URL</label> <input id="debugUrlInput" class="form-input" placeholder="https://example.com/api/users"></div><div class="debugger-controls"><button id="runDebuggerBtn" class="btn btn-primary">๐ Debug Rules</button> <button id="clearDebuggerBtn" class="btn btn-secondary">Clear</button> <label class="checkbox-label"><input type="checkbox" id="showOnlyMatchingRules"> Show only matching rules</label></div></div><div id="debuggerResults" class="debugger-results"><div class="debugger-placeholder"><div class="placeholder-icon">๐ฏ</div><h3>Ready for Visual Debugging</h3><p>Enter a URL above and click "Debug Rules" to see step-by-step pattern matching</p><ul class="feature-list"><li>๐ Step-by-step rule evaluation</li><li>๐จ Visual regex pattern matching</li><li>๐ Variable substitution tracking</li><li>๐ Capture group visualization</li><li>โ Match failure explanations</li></ul></div></div></div></div></div></div><div class="footer">FreshRoute Dashboard v1.0.0 - Real-time rule monitoring and testing</div></div><script src="dashboard.js"></script></body></html>