@design.estate/dees-catalog 3.35.1 → 3.36.0

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.
@@ -101154,6 +101154,7 @@ var init_versions = __esm({
101154
101154
  CDN_VERSIONS = {
101155
101155
  xterm: "5.3.0",
101156
101156
  xtermAddonFit: "0.8.0",
101157
+ xtermAddonSearch: "0.13.0",
101157
101158
  highlightJs: "11.11.1",
101158
101159
  apexcharts: "5.3.6",
101159
101160
  tiptap: "2.23.0",
@@ -101173,12 +101174,14 @@ var init_DeesServiceLibLoader = __esm({
101173
101174
  // Cached library references
101174
101175
  xtermLib = null;
101175
101176
  xtermFitAddonLib = null;
101177
+ xtermSearchAddonLib = null;
101176
101178
  highlightJsLib = null;
101177
101179
  apexChartsLib = null;
101178
101180
  tiptapLib = null;
101179
101181
  // Loading promises to prevent duplicate concurrent loads
101180
101182
  xtermLoadingPromise = null;
101181
101183
  xtermFitAddonLoadingPromise = null;
101184
+ xtermSearchAddonLoadingPromise = null;
101182
101185
  highlightJsLoadingPromise = null;
101183
101186
  apexChartsLoadingPromise = null;
101184
101187
  tiptapLoadingPromise = null;
@@ -101242,6 +101245,30 @@ var init_DeesServiceLibLoader = __esm({
101242
101245
  })();
101243
101246
  return this.xtermFitAddonLoadingPromise;
101244
101247
  }
101248
+ /**
101249
+ * Load xterm-addon-search from CDN
101250
+ * @returns Promise resolving to SearchAddon class
101251
+ */
101252
+ async loadXtermSearchAddon() {
101253
+ if (this.xtermSearchAddonLib) {
101254
+ return this.xtermSearchAddonLib;
101255
+ }
101256
+ if (this.xtermSearchAddonLoadingPromise) {
101257
+ return this.xtermSearchAddonLoadingPromise;
101258
+ }
101259
+ this.xtermSearchAddonLoadingPromise = (async () => {
101260
+ const url = `${CDN_BASE}/xterm-addon-search@${CDN_VERSIONS.xtermAddonSearch}/+esm`;
101261
+ const module = await import(
101262
+ /* @vite-ignore */
101263
+ url
101264
+ );
101265
+ this.xtermSearchAddonLib = {
101266
+ SearchAddon: module.SearchAddon
101267
+ };
101268
+ return this.xtermSearchAddonLib;
101269
+ })();
101270
+ return this.xtermSearchAddonLoadingPromise;
101271
+ }
101245
101272
  /**
101246
101273
  * Inject xterm CSS styles into the document head
101247
101274
  */
@@ -101368,6 +101395,7 @@ var init_DeesServiceLibLoader = __esm({
101368
101395
  await Promise.all([
101369
101396
  this.loadXterm(),
101370
101397
  this.loadXtermFitAddon(),
101398
+ this.loadXtermSearchAddon(),
101371
101399
  this.loadHighlightJs(),
101372
101400
  this.loadApexCharts(),
101373
101401
  this.loadTiptap()
@@ -101382,6 +101410,8 @@ var init_DeesServiceLibLoader = __esm({
101382
101410
  return this.xtermLib !== null;
101383
101411
  case "xtermFitAddon":
101384
101412
  return this.xtermFitAddonLib !== null;
101413
+ case "xtermSearchAddon":
101414
+ return this.xtermSearchAddonLib !== null;
101385
101415
  case "highlightJs":
101386
101416
  return this.highlightJsLib !== null;
101387
101417
  case "apexCharts":
@@ -135051,8 +135081,10 @@ init_dist_ts26();
135051
135081
  var demoFunc33 = () => {
135052
135082
  return b2`
135053
135083
  <dees-demowrapper .runAfterRender=${async (elementArg) => {
135054
- const logElement = elementArg.querySelector("dees-chart-log");
135055
- let intervalId;
135084
+ const structuredLog = elementArg.querySelector("#structured-log");
135085
+ const rawLog = elementArg.querySelector("#raw-log");
135086
+ let structuredIntervalId;
135087
+ let rawIntervalId;
135056
135088
  const serverSources = ["Server", "Database", "API", "Auth", "Cache", "Queue", "WebSocket", "Scheduler"];
135057
135089
  const logTemplates = {
135058
135090
  debug: [
@@ -135091,6 +135123,20 @@ var demoFunc33 = () => {
135091
135123
  "Health check passed: all systems operational"
135092
135124
  ]
135093
135125
  };
135126
+ const dockerLogTemplates = [
135127
+ "\x1B[90m2024-01-15T10:23:45.123Z\x1B[0m \x1B[36mINFO\x1B[0m [nginx] GET /api/health 200 - 2ms",
135128
+ "\x1B[90m2024-01-15T10:23:45.456Z\x1B[0m \x1B[33mWARN\x1B[0m [redis] Connection pool running low: 3/10",
135129
+ "\x1B[90m2024-01-15T10:23:45.789Z\x1B[0m \x1B[31mERROR\x1B[0m [mongodb] Query timeout after 30000ms",
135130
+ "\x1B[90m2024-01-15T10:23:46.012Z\x1B[0m \x1B[36mINFO\x1B[0m [app] Processing batch job #{{jobId}}",
135131
+ "\x1B[90m2024-01-15T10:23:46.345Z\x1B[0m \x1B[32mOK\x1B[0m [health] All services healthy",
135132
+ "\x1B[90m2024-01-15T10:23:46.678Z\x1B[0m \x1B[36mINFO\x1B[0m [kafka] Message consumed from topic: events",
135133
+ "\x1B[90m2024-01-15T10:23:47.001Z\x1B[0m \x1B[35mDEBUG\x1B[0m [grpc] Request received: GetUser(id={{userId}})",
135134
+ "\x1B[90m2024-01-15T10:23:47.234Z\x1B[0m \x1B[31mERROR\x1B[0m [auth] Token validation failed: expired",
135135
+ "\x1B[90m2024-01-15T10:23:47.567Z\x1B[0m \x1B[33mWARN\x1B[0m [rate-limit] IP {{ip}} approaching rate limit",
135136
+ "\x1B[90m2024-01-15T10:23:47.890Z\x1B[0m \x1B[36mINFO\x1B[0m [websocket] Client connected: session={{session}}",
135137
+ // Multi-line log entry like stack traces
135138
+ "\x1B[31mError: Connection refused\x1B[0m\n at TcpConnection.connect (/app/node_modules/pg/lib/connection.js:12:15)\n at Pool.connect (/app/node_modules/pg/lib/pool.js:45:23)\n at async DatabaseService.query (/app/src/db/service.ts:89:12)"
135139
+ ];
135094
135140
  const generateRandomLog = () => {
135095
135141
  const levels = ["debug", "info", "warn", "error", "success"];
135096
135142
  const weights = [0.2, 0.5, 0.15, 0.1, 0.05];
@@ -135108,15 +135154,21 @@ var demoFunc33 = () => {
135108
135154
  const templates = logTemplates[level];
135109
135155
  const template = templates[Math.floor(Math.random() * templates.length)];
135110
135156
  const message2 = template.replace("{{module}}", ["express", "mongoose", "redis", "socket.io"][Math.floor(Math.random() * 4)]).replace("{{key}}", "user:" + Math.floor(Math.random() * 1e3)).replace("{{time}}", String(Math.floor(Math.random() * 500) + 50)).replace("{{headers}}", "Content-Type: application/json, Authorization: Bearer ...").replace("{{var}}", ["NODE_ENV", "DATABASE_URL", "API_KEY", "PORT"][Math.floor(Math.random() * 4)]).replace("{{method}}", ["GET", "POST", "PUT", "DELETE"][Math.floor(Math.random() * 4)]).replace("{{path}}", ["/api/users", "/api/auth/login", "/api/products", "/health"][Math.floor(Math.random() * 4)]).replace("{{userId}}", String(Math.floor(Math.random() * 1e4))).replace("{{jobId}}", "job_" + Math.random().toString(36).substring(2, 11)).replace("{{task}}", ["cleanup", "backup", "report-generation", "cache-refresh"][Math.floor(Math.random() * 4)]).replace("{{ip}}", `192.168.1.${Math.floor(Math.random() * 255)}`).replace("{{query}}", "SELECT * FROM users WHERE ...").replace("{{percent}}", String(Math.floor(Math.random() * 30) + 70)).replace("{{endpoint}}", "/api/v1/legacy").replace("{{days}}", String(Math.floor(Math.random() * 30) + 1)).replace("{{error}}", ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"][Math.floor(Math.random() * 3)]).replace("{{user}}", "user_" + Math.floor(Math.random() * 1e3)).replace("{{service}}", ["Redis", "MongoDB", "ElasticSearch"][Math.floor(Math.random() * 3)]).replace("{{port}}", String(3e3 + Math.floor(Math.random() * 10))).replace("{{size}}", String(Math.floor(Math.random() * 500) + 100));
135111
- logElement.addLog(level, message2, source);
135157
+ structuredLog.addLog(level, message2, source);
135158
+ };
135159
+ const generateDockerLog = () => {
135160
+ const template = dockerLogTemplates[Math.floor(Math.random() * dockerLogTemplates.length)];
135161
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
135162
+ const logLine = template.replace(/2024-01-15T10:23:\d{2}\.\d{3}Z/g, now2).replace("{{jobId}}", String(Math.floor(Math.random() * 1e4))).replace("{{userId}}", String(Math.floor(Math.random() * 1e4))).replace("{{ip}}", `192.168.1.${Math.floor(Math.random() * 255)}`).replace("{{session}}", Math.random().toString(36).substring(2, 11));
135163
+ rawLog.writelnRaw(logLine);
135112
135164
  };
135113
- const startSimulation = () => {
135114
- if (!intervalId) {
135165
+ const startStructuredSimulation = () => {
135166
+ if (!structuredIntervalId) {
135115
135167
  const scheduleNext = () => {
135116
135168
  generateRandomLog();
135117
135169
  const nextDelay = Math.random() * 2e3 + 500;
135118
- intervalId = window.setTimeout(() => {
135119
- if (intervalId) {
135170
+ structuredIntervalId = window.setTimeout(() => {
135171
+ if (structuredIntervalId) {
135120
135172
  scheduleNext();
135121
135173
  }
135122
135174
  }, nextDelay);
@@ -135124,57 +135176,131 @@ var demoFunc33 = () => {
135124
135176
  scheduleNext();
135125
135177
  }
135126
135178
  };
135127
- const stopSimulation = () => {
135128
- if (intervalId) {
135129
- window.clearTimeout(intervalId);
135130
- intervalId = null;
135179
+ const stopStructuredSimulation = () => {
135180
+ if (structuredIntervalId) {
135181
+ window.clearTimeout(structuredIntervalId);
135182
+ structuredIntervalId = null;
135183
+ }
135184
+ };
135185
+ const startRawSimulation = () => {
135186
+ if (!rawIntervalId) {
135187
+ const scheduleNext = () => {
135188
+ generateDockerLog();
135189
+ const nextDelay = Math.random() * 1e3 + 200;
135190
+ rawIntervalId = window.setTimeout(() => {
135191
+ if (rawIntervalId) {
135192
+ scheduleNext();
135193
+ }
135194
+ }, nextDelay);
135195
+ };
135196
+ scheduleNext();
135197
+ }
135198
+ };
135199
+ const stopRawSimulation = () => {
135200
+ if (rawIntervalId) {
135201
+ window.clearTimeout(rawIntervalId);
135202
+ rawIntervalId = null;
135131
135203
  }
135132
135204
  };
135133
135205
  const buttons = elementArg.querySelectorAll("dees-button");
135134
135206
  buttons.forEach((button) => {
135135
135207
  const text9 = button.textContent?.trim();
135136
- if (text9 === "Add Single Log") {
135137
- button.addEventListener("click", () => generateRandomLog());
135138
- } else if (text9 === "Start Simulation") {
135139
- button.addEventListener("click", () => startSimulation());
135140
- } else if (text9 === "Stop Simulation") {
135141
- button.addEventListener("click", () => stopSimulation());
135208
+ switch (text9) {
135209
+ case "Add Structured Log":
135210
+ button.addEventListener("click", () => generateRandomLog());
135211
+ break;
135212
+ case "Start Structured":
135213
+ button.addEventListener("click", () => startStructuredSimulation());
135214
+ break;
135215
+ case "Stop Structured":
135216
+ button.addEventListener("click", () => stopStructuredSimulation());
135217
+ break;
135218
+ case "Add Docker Log":
135219
+ button.addEventListener("click", () => generateDockerLog());
135220
+ break;
135221
+ case "Start Docker":
135222
+ button.addEventListener("click", () => startRawSimulation());
135223
+ break;
135224
+ case "Stop Docker":
135225
+ button.addEventListener("click", () => stopRawSimulation());
135226
+ break;
135142
135227
  }
135143
135228
  });
135144
135229
  }}>
135145
135230
  <style>
135146
- .demoBox {
135147
- position: relative;
135148
- background: #000000;
135149
- height: 100%;
135150
- width: 100%;
135151
- padding: 40px;
135152
- box-sizing: border-box;
135153
- display: flex;
135154
- flex-direction: column;
135155
- gap: 20px;
135156
- }
135157
- .controls {
135158
- display: flex;
135159
- gap: 10px;
135160
- flex-wrap: wrap;
135161
- }
135162
- .info {
135163
- color: #888;
135164
- font-size: 12px;
135165
- font-family: 'Geist Sans', sans-serif;
135166
- }
135167
- </style>
135231
+ ${i`
135232
+ .demoBox {
135233
+ position: relative;
135234
+ background: ${cssManager.bdTheme("hsl(0 0% 95%)", "hsl(0 0% 5%)")};
135235
+ height: 100%;
135236
+ width: 100%;
135237
+ padding: 40px;
135238
+ box-sizing: border-box;
135239
+ display: flex;
135240
+ flex-direction: column;
135241
+ gap: 24px;
135242
+ }
135243
+ .section {
135244
+ display: flex;
135245
+ flex-direction: column;
135246
+ gap: 12px;
135247
+ }
135248
+ .section-title {
135249
+ color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
135250
+ font-size: 14px;
135251
+ font-weight: 600;
135252
+ font-family: 'Geist Sans', sans-serif;
135253
+ }
135254
+ .section-description {
135255
+ color: ${cssManager.bdTheme("hsl(215.4 16.3% 46.9%)", "hsl(215 20.2% 65.1%)")};
135256
+ font-size: 12px;
135257
+ font-family: 'Geist Sans', sans-serif;
135258
+ }
135259
+ .controls {
135260
+ display: flex;
135261
+ gap: 10px;
135262
+ flex-wrap: wrap;
135263
+ }
135264
+ `}
135265
+ </style>
135168
135266
  <div class="demoBox">
135169
- <div class="controls">
135170
- <dees-button>Add Single Log</dees-button>
135171
- <dees-button>Start Simulation</dees-button>
135172
- <dees-button>Stop Simulation</dees-button>
135267
+ <!-- Structured Logs Section -->
135268
+ <div class="section">
135269
+ <div class="section-title">Structured Logs (ILogEntry)</div>
135270
+ <div class="section-description">
135271
+ Structured log entries with level, message, and source. Supports search and keyword highlighting.
135272
+ </div>
135273
+ <div class="controls">
135274
+ <dees-button>Add Structured Log</dees-button>
135275
+ <dees-button>Start Structured</dees-button>
135276
+ <dees-button>Stop Structured</dees-button>
135277
+ </div>
135278
+ <dees-chart-log
135279
+ id="structured-log"
135280
+ .label=${"Production Server Logs"}
135281
+ .highlightKeywords=${["error", "failed", "timeout"]}
135282
+ .showMetrics=${true}
135283
+ ></dees-chart-log>
135284
+ </div>
135285
+
135286
+ <!-- Raw Logs Section -->
135287
+ <div class="section">
135288
+ <div class="section-title">Raw Logs (Docker/Container Style)</div>
135289
+ <div class="section-description">
135290
+ Raw log output with ANSI escape sequences for real Docker/container logs.
135291
+ </div>
135292
+ <div class="controls">
135293
+ <dees-button>Add Docker Log</dees-button>
135294
+ <dees-button>Start Docker</dees-button>
135295
+ <dees-button>Stop Docker</dees-button>
135296
+ </div>
135297
+ <dees-chart-log
135298
+ id="raw-log"
135299
+ .label=${"Docker Container Logs"}
135300
+ .mode=${"raw"}
135301
+ .showMetrics=${false}
135302
+ ></dees-chart-log>
135173
135303
  </div>
135174
- <div class="info">Simulating realistic server logs with various levels and sources</div>
135175
- <dees-chart-log
135176
- .label=${"Production Server Logs"}
135177
- ></dees-chart-log>
135178
135304
  </div>
135179
135305
  </dees-demowrapper>
135180
135306
  `;
@@ -135184,16 +135310,37 @@ var demoFunc33 = () => {
135184
135310
  init_dist_ts26();
135185
135311
  init_dist_ts25();
135186
135312
  init_theme();
135187
- var _maxEntries_dec, _autoScroll_dec, _logEntries_dec, _label_dec6, _a45, _DeesChartLog_decorators, _init47, _label6, _logEntries, _autoScroll, _maxEntries;
135313
+ init_services();
135314
+ var _terminalReady_dec, _metrics_dec, _filterMode_dec, _searchQuery_dec2, _showMetrics_dec, _highlightKeywords_dec, _maxEntries_dec, _autoScroll_dec, _logEntries_dec, _mode_dec, _label_dec6, _a45, _DeesChartLog_decorators, _init47, _label6, _mode, _logEntries, _autoScroll, _maxEntries, _highlightKeywords, _showMetrics, _searchQuery2, _filterMode, _metrics, _terminalReady;
135188
135315
  _DeesChartLog_decorators = [t4("dees-chart-log")];
135189
- var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _logEntries_dec = [n5({ type: Array })], _autoScroll_dec = [n5({ type: Boolean })], _maxEntries_dec = [n5({ type: Number })], _a45) {
135316
+ var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _mode_dec = [n5({ type: String })], _logEntries_dec = [n5({ type: Array })], _autoScroll_dec = [n5({ type: Boolean })], _maxEntries_dec = [n5({ type: Number })], _highlightKeywords_dec = [n5({ type: Array })], _showMetrics_dec = [n5({ type: Boolean })], _searchQuery_dec2 = [r5()], _filterMode_dec = [r5()], _metrics_dec = [r5()], _terminalReady_dec = [r5()], _a45) {
135190
135317
  constructor() {
135191
135318
  super();
135192
135319
  __privateAdd(this, _label6, __runInitializers(_init47, 8, this, "Server Logs")), __runInitializers(_init47, 11, this);
135193
- __privateAdd(this, _logEntries, __runInitializers(_init47, 12, this, [])), __runInitializers(_init47, 15, this);
135194
- __privateAdd(this, _autoScroll, __runInitializers(_init47, 16, this, true)), __runInitializers(_init47, 19, this);
135195
- __privateAdd(this, _maxEntries, __runInitializers(_init47, 20, this, 1e3)), __runInitializers(_init47, 23, this);
135196
- __publicField(this, "logContainer");
135320
+ __privateAdd(this, _mode, __runInitializers(_init47, 12, this, "structured")), __runInitializers(_init47, 15, this);
135321
+ __privateAdd(this, _logEntries, __runInitializers(_init47, 16, this, [])), __runInitializers(_init47, 19, this);
135322
+ __privateAdd(this, _autoScroll, __runInitializers(_init47, 20, this, true)), __runInitializers(_init47, 23, this);
135323
+ __privateAdd(this, _maxEntries, __runInitializers(_init47, 24, this, 1e4)), __runInitializers(_init47, 27, this);
135324
+ __privateAdd(this, _highlightKeywords, __runInitializers(_init47, 28, this, [])), __runInitializers(_init47, 31, this);
135325
+ __privateAdd(this, _showMetrics, __runInitializers(_init47, 32, this, true)), __runInitializers(_init47, 35, this);
135326
+ __privateAdd(this, _searchQuery2, __runInitializers(_init47, 36, this, "")), __runInitializers(_init47, 39, this);
135327
+ __privateAdd(this, _filterMode, __runInitializers(_init47, 40, this, false)), __runInitializers(_init47, 43, this);
135328
+ __privateAdd(this, _metrics, __runInitializers(_init47, 44, this, { debug: 0, info: 0, warn: 0, error: 0, success: 0, total: 0, rate: 0 })), __runInitializers(_init47, 47, this);
135329
+ __privateAdd(this, _terminalReady, __runInitializers(_init47, 48, this, false)), __runInitializers(_init47, 51, this);
135330
+ // Buffer of all log entries for filter mode
135331
+ __publicField(this, "logBuffer", []);
135332
+ // Track trailing hidden entries count for live updates in filter mode
135333
+ __publicField(this, "trailingHiddenCount", 0);
135334
+ // xterm instances
135335
+ __publicField(this, "terminal", null);
135336
+ __publicField(this, "fitAddon", null);
135337
+ __publicField(this, "searchAddon", null);
135338
+ __publicField(this, "resizeObserver", null);
135339
+ __publicField(this, "terminalThemeSubscription", null);
135340
+ __publicField(this, "domtoolsInstance", null);
135341
+ // Rate calculation
135342
+ __publicField(this, "rateBuffer", []);
135343
+ __publicField(this, "rateInterval", null);
135197
135344
  domtools_elementbasic_exports.setup();
135198
135345
  }
135199
135346
  render() {
@@ -135201,105 +135348,508 @@ var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _log
135201
135348
  <div class="mainbox">
135202
135349
  <div class="header">
135203
135350
  <div class="title">${this.label}</div>
135351
+ <div class="search-box">
135352
+ <input
135353
+ type="text"
135354
+ placeholder="Search logs..."
135355
+ .value=${this.searchQuery}
135356
+ @input=${(e11) => this.handleSearchInput(e11)}
135357
+ @keydown=${(e11) => this.handleSearchKeydown(e11)}
135358
+ />
135359
+ <div class="search-nav">
135360
+ <button @click=${() => this.searchPrevious()} title="Previous match">↑</button>
135361
+ <button @click=${() => this.searchNext()} title="Next match">↓</button>
135362
+ </div>
135363
+ <button
135364
+ class="filter-toggle ${this.filterMode ? "active" : ""}"
135365
+ @click=${() => this.toggleFilterMode()}
135366
+ title="${this.filterMode ? "Switch to highlight mode" : "Switch to filter mode"}"
135367
+ >
135368
+ ${this.filterMode ? "Filter" : "Highlight"}
135369
+ </button>
135370
+ </div>
135204
135371
  <div class="controls">
135205
- <button
135372
+ <button
135206
135373
  class="control-button ${this.autoScroll ? "active" : ""}"
135207
- @click=${() => {
135208
- this.autoScroll = !this.autoScroll;
135209
- }}
135374
+ @click=${() => this.toggleAutoScroll()}
135210
135375
  >
135211
135376
  Auto Scroll
135212
135377
  </button>
135213
- <button
135214
- class="control-button"
135215
- @click=${() => {
135216
- this.clearLogs();
135217
- }}
135218
- >
135378
+ <button class="control-button" @click=${() => this.clearLogs()}>
135219
135379
  Clear
135220
135380
  </button>
135221
135381
  </div>
135222
135382
  </div>
135223
- <div class="logContainer">
135224
- ${this.logEntries.length === 0 ? b2`<div class="empty-state">No logs to display</div>` : this.logEntries.map((entry) => this.renderLogEntry(entry))}
135383
+
135384
+ <div class="terminal-container">
135385
+ ${!this.terminalReady ? b2`<div class="loading-state">Loading terminal...</div>` : ""}
135225
135386
  </div>
135387
+
135388
+ ${this.showMetrics ? b2`
135389
+ <div class="metrics-bar">
135390
+ <span class="metric error">errors: ${this.metrics.error}</span>
135391
+ <span class="metric warn">warns: ${this.metrics.warn}</span>
135392
+ <span class="metric info">info: ${this.metrics.info}</span>
135393
+ <span class="metric success">success: ${this.metrics.success}</span>
135394
+ <span class="metric debug">debug: ${this.metrics.debug}</span>
135395
+ <span class="metric rate">${this.metrics.rate.toFixed(1)} logs/sec</span>
135396
+ </div>
135397
+ ` : ""}
135226
135398
  </div>
135227
135399
  `;
135228
135400
  }
135229
- renderLogEntry(entry) {
135230
- const timestamp2 = new Date(entry.timestamp).toLocaleTimeString("en-US", {
135401
+ async firstUpdated() {
135402
+ this.domtoolsInstance = await this.domtoolsPromise;
135403
+ await this.initializeTerminal();
135404
+ if (this.logEntries.length > 0) {
135405
+ for (const entry of this.logEntries) {
135406
+ this.writeLogEntry(entry);
135407
+ }
135408
+ }
135409
+ }
135410
+ async initializeTerminal() {
135411
+ const libLoader = DeesServiceLibLoader.getInstance();
135412
+ const [xtermBundle, fitBundle, searchBundle] = await Promise.all([
135413
+ libLoader.loadXterm(),
135414
+ libLoader.loadXtermFitAddon(),
135415
+ libLoader.loadXtermSearchAddon()
135416
+ ]);
135417
+ await this.injectXtermStylesIntoShadow();
135418
+ this.terminal = new xtermBundle.Terminal({
135419
+ cursorBlink: false,
135420
+ disableStdin: true,
135421
+ fontSize: 12,
135422
+ fontFamily: "'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace",
135423
+ theme: this.getTerminalTheme(),
135424
+ scrollback: this.maxEntries,
135425
+ convertEol: true
135426
+ });
135427
+ this.fitAddon = new fitBundle.FitAddon();
135428
+ this.searchAddon = new searchBundle.SearchAddon();
135429
+ this.terminal.loadAddon(this.fitAddon);
135430
+ this.terminal.loadAddon(this.searchAddon);
135431
+ const container = this.shadowRoot.querySelector(".terminal-container");
135432
+ this.terminal.open(container);
135433
+ await new Promise((resolve2) => requestAnimationFrame(resolve2));
135434
+ this.fitAddon.fit();
135435
+ this.resizeObserver = new ResizeObserver(() => {
135436
+ this.fitAddon?.fit();
135437
+ });
135438
+ this.resizeObserver.observe(container);
135439
+ this.terminalThemeSubscription = this.domtoolsInstance.themeManager.themeObservable.subscribe(() => {
135440
+ if (this.terminal) {
135441
+ this.terminal.options.theme = this.getTerminalTheme();
135442
+ }
135443
+ });
135444
+ this.rateInterval = setInterval(() => this.calculateRate(), 1e3);
135445
+ this.terminalReady = true;
135446
+ }
135447
+ getTerminalTheme() {
135448
+ const isDark = this.domtoolsInstance?.themeManager?.isDarkMode ?? true;
135449
+ return isDark ? {
135450
+ background: "#0a0a0a",
135451
+ foreground: "#e0e0e0",
135452
+ cursor: "#e0e0e0",
135453
+ selectionBackground: "#404040",
135454
+ black: "#000000",
135455
+ red: "#ff5555",
135456
+ green: "#50fa7b",
135457
+ yellow: "#f1fa8c",
135458
+ blue: "#6272a4",
135459
+ magenta: "#ff79c6",
135460
+ cyan: "#8be9fd",
135461
+ white: "#f8f8f2",
135462
+ brightBlack: "#6272a4",
135463
+ brightRed: "#ff6e6e",
135464
+ brightGreen: "#69ff94",
135465
+ brightYellow: "#ffffa5",
135466
+ brightBlue: "#d6acff",
135467
+ brightMagenta: "#ff92df",
135468
+ brightCyan: "#a4ffff",
135469
+ brightWhite: "#ffffff"
135470
+ } : {
135471
+ background: "#ffffff",
135472
+ foreground: "#333333",
135473
+ cursor: "#333333",
135474
+ selectionBackground: "#add6ff",
135475
+ black: "#000000",
135476
+ red: "#cd3131",
135477
+ green: "#00bc00",
135478
+ yellow: "#949800",
135479
+ blue: "#0451a5",
135480
+ magenta: "#bc05bc",
135481
+ cyan: "#0598bc",
135482
+ white: "#555555",
135483
+ brightBlack: "#666666",
135484
+ brightRed: "#cd3131",
135485
+ brightGreen: "#14ce14",
135486
+ brightYellow: "#b5ba00",
135487
+ brightBlue: "#0451a5",
135488
+ brightMagenta: "#bc05bc",
135489
+ brightCyan: "#0598bc",
135490
+ brightWhite: "#a5a5a5"
135491
+ };
135492
+ }
135493
+ /**
135494
+ * Inject xterm CSS styles into shadow root
135495
+ * This is needed because shadow DOM doesn't inherit styles from document.head
135496
+ */
135497
+ async injectXtermStylesIntoShadow() {
135498
+ const styleId = "xterm-shadow-styles";
135499
+ if (this.shadowRoot.getElementById(styleId)) {
135500
+ return;
135501
+ }
135502
+ const cssUrl = `${CDN_BASE}/xterm@${CDN_VERSIONS.xterm}/css/xterm.css`;
135503
+ const response = await fetch(cssUrl);
135504
+ const cssText = await response.text();
135505
+ const style = document.createElement("style");
135506
+ style.id = styleId;
135507
+ style.textContent = cssText;
135508
+ this.shadowRoot.appendChild(style);
135509
+ }
135510
+ // =====================
135511
+ // Structured Log Methods
135512
+ // =====================
135513
+ /**
135514
+ * Add a single structured log entry
135515
+ */
135516
+ addLog(level, message2, source) {
135517
+ const entry = {
135518
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135519
+ level,
135520
+ message: message2,
135521
+ source
135522
+ };
135523
+ this.logBuffer.push(entry);
135524
+ if (this.logBuffer.length > this.maxEntries) {
135525
+ this.logBuffer.shift();
135526
+ }
135527
+ if (!this.filterMode || !this.searchQuery) {
135528
+ this.writeLogEntry(entry);
135529
+ } else if (this.entryMatchesFilter(entry)) {
135530
+ this.trailingHiddenCount = 0;
135531
+ this.writeLogEntry(entry);
135532
+ } else {
135533
+ this.updateTrailingPlaceholder();
135534
+ }
135535
+ this.updateMetrics(entry.level);
135536
+ }
135537
+ /**
135538
+ * Add multiple structured log entries
135539
+ */
135540
+ updateLog(entries) {
135541
+ if (!entries) return;
135542
+ for (const entry of entries) {
135543
+ this.logBuffer.push(entry);
135544
+ if (this.logBuffer.length > this.maxEntries) {
135545
+ this.logBuffer.shift();
135546
+ }
135547
+ if (!this.filterMode || !this.searchQuery) {
135548
+ this.writeLogEntry(entry);
135549
+ } else if (this.entryMatchesFilter(entry)) {
135550
+ this.trailingHiddenCount = 0;
135551
+ this.writeLogEntry(entry);
135552
+ } else {
135553
+ this.updateTrailingPlaceholder();
135554
+ }
135555
+ this.updateMetrics(entry.level);
135556
+ }
135557
+ }
135558
+ /**
135559
+ * Update the trailing hidden placeholder in real-time
135560
+ * Clears the last line if a placeholder already exists, then writes updated count
135561
+ */
135562
+ updateTrailingPlaceholder() {
135563
+ if (!this.terminal) return;
135564
+ if (this.trailingHiddenCount > 0) {
135565
+ this.terminal.write("\x1B[1A\x1B[2K\r");
135566
+ }
135567
+ this.trailingHiddenCount++;
135568
+ this.writeHiddenPlaceholder(this.trailingHiddenCount);
135569
+ if (this.autoScroll) {
135570
+ this.terminal.scrollToBottom();
135571
+ }
135572
+ }
135573
+ /**
135574
+ * Check if a log entry matches the current filter
135575
+ */
135576
+ entryMatchesFilter(entry) {
135577
+ if (!this.searchQuery) return true;
135578
+ const query4 = this.searchQuery.toLowerCase();
135579
+ return entry.message.toLowerCase().includes(query4) || entry.level.toLowerCase().includes(query4) || (entry.source?.toLowerCase().includes(query4) ?? false);
135580
+ }
135581
+ writeLogEntry(entry) {
135582
+ if (!this.terminal) return;
135583
+ const formatted = this.formatLogEntry(entry);
135584
+ this.terminal.writeln(formatted);
135585
+ if (this.autoScroll) {
135586
+ this.terminal.scrollToBottom();
135587
+ }
135588
+ }
135589
+ formatLogEntry(entry) {
135590
+ const timestamp2 = this.formatTimestamp(entry.timestamp);
135591
+ const levelColors = {
135592
+ debug: "\x1B[90m",
135593
+ // Gray
135594
+ info: "\x1B[36m",
135595
+ // Cyan
135596
+ warn: "\x1B[33m",
135597
+ // Yellow
135598
+ error: "\x1B[31m",
135599
+ // Red
135600
+ success: "\x1B[32m"
135601
+ // Green
135602
+ };
135603
+ const reset = "\x1B[0m";
135604
+ const dim = "\x1B[2m";
135605
+ const levelStr = `${levelColors[entry.level]}[${entry.level.toUpperCase().padEnd(7)}]${reset}`;
135606
+ const sourceStr = entry.source ? `${dim}[${entry.source}]${reset} ` : "";
135607
+ const messageStr = this.applyHighlights(entry.message);
135608
+ return `${dim}${timestamp2}${reset} ${levelStr} ${sourceStr}${messageStr}`;
135609
+ }
135610
+ formatTimestamp(isoString) {
135611
+ const date = new Date(isoString);
135612
+ return date.toLocaleTimeString("en-US", {
135231
135613
  hour12: false,
135232
135614
  hour: "2-digit",
135233
135615
  minute: "2-digit",
135234
135616
  second: "2-digit",
135235
135617
  fractionalSecondDigits: 3
135236
135618
  });
135237
- return b2`
135238
- <div class="logEntry">
135239
- <span class="timestamp">${timestamp2}</span>
135240
- <span class="level ${entry.level}">${entry.level}</span>
135241
- ${entry.source ? b2`<span class="source">[${entry.source}]</span>` : ""}
135242
- <span class="message">${entry.message}</span>
135243
- </div>
135244
- `;
135245
135619
  }
135246
- async firstUpdated() {
135247
- await this.domtoolsPromise;
135248
- this.logContainer = this.shadowRoot.querySelector(".logContainer");
135249
- const demoLogs = [
135250
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "Server started on port 3000", source: "Server" },
135251
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "debug", message: "Loading configuration from /etc/app/config.json", source: "Config" },
135252
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "Connected to MongoDB at mongodb://localhost:27017", source: "Database" },
135253
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "success", message: "Database connection established successfully", source: "Database" },
135254
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "warn", message: "No SSL certificate found, using self-signed certificate", source: "Security" },
135255
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "API routes initialized: GET /api/users, POST /api/users, DELETE /api/users/:id", source: "Router" },
135256
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "debug", message: "Middleware stack: cors, bodyParser, authentication, errorHandler", source: "Middleware" },
135257
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "WebSocket server listening on ws://localhost:3001", source: "WebSocket" }
135258
- ];
135259
- this.logEntries = demoLogs;
135260
- this.scrollToBottom();
135261
- }
135262
- async updateLog(entries) {
135263
- if (entries) {
135264
- this.logEntries = [...this.logEntries, ...entries];
135265
- if (this.logEntries.length > this.maxEntries) {
135266
- this.logEntries = this.logEntries.slice(-this.maxEntries);
135620
+ applyHighlights(text9) {
135621
+ const keywords = [...this.highlightKeywords];
135622
+ if (this.filterMode && this.searchQuery) {
135623
+ keywords.push(this.searchQuery);
135624
+ }
135625
+ if (keywords.length === 0) return text9;
135626
+ let result = text9;
135627
+ for (const keyword of keywords) {
135628
+ const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
135629
+ const regex = new RegExp(`(${escaped})`, "gi");
135630
+ result = result.replace(regex, "\x1B[43m\x1B[30m$1\x1B[0m");
135631
+ }
135632
+ return result;
135633
+ }
135634
+ // =====================
135635
+ // Raw Log Methods
135636
+ // =====================
135637
+ /**
135638
+ * Write raw data to the terminal (for Docker logs, etc.)
135639
+ */
135640
+ writeRaw(data) {
135641
+ if (!this.terminal) return;
135642
+ this.terminal.write(data);
135643
+ this.recordLogEvent();
135644
+ if (this.autoScroll) {
135645
+ this.terminal.scrollToBottom();
135646
+ }
135647
+ }
135648
+ /**
135649
+ * Write a raw line to the terminal
135650
+ */
135651
+ writelnRaw(line) {
135652
+ if (!this.terminal) return;
135653
+ this.terminal.writeln(line);
135654
+ this.recordLogEvent();
135655
+ if (this.autoScroll) {
135656
+ this.terminal.scrollToBottom();
135657
+ }
135658
+ }
135659
+ // =====================
135660
+ // Search Methods
135661
+ // =====================
135662
+ handleSearchInput(e11) {
135663
+ const input = e11.target;
135664
+ const newQuery = input.value;
135665
+ const queryChanged = this.searchQuery !== newQuery;
135666
+ this.searchQuery = newQuery;
135667
+ if (this.filterMode && queryChanged) {
135668
+ this.reRenderFilteredLogs();
135669
+ } else if (this.searchQuery) {
135670
+ this.searchAddon?.findNext(this.searchQuery);
135671
+ }
135672
+ }
135673
+ handleSearchKeydown(e11) {
135674
+ if (e11.key === "Enter") {
135675
+ if (e11.shiftKey) {
135676
+ this.searchPrevious();
135677
+ } else {
135678
+ this.searchNext();
135267
135679
  }
135268
- this.requestUpdate();
135269
- await this.updateComplete;
135270
- if (this.autoScroll) {
135271
- this.scrollToBottom();
135680
+ } else if (e11.key === "Escape") {
135681
+ this.searchQuery = "";
135682
+ e11.target.value = "";
135683
+ }
135684
+ }
135685
+ /**
135686
+ * Search for a query in the terminal
135687
+ */
135688
+ search(query4) {
135689
+ this.searchQuery = query4;
135690
+ this.searchAddon?.findNext(query4);
135691
+ }
135692
+ /**
135693
+ * Find next search match
135694
+ */
135695
+ searchNext() {
135696
+ if (this.searchQuery) {
135697
+ this.searchAddon?.findNext(this.searchQuery);
135698
+ }
135699
+ }
135700
+ /**
135701
+ * Find previous search match
135702
+ */
135703
+ searchPrevious() {
135704
+ if (this.searchQuery) {
135705
+ this.searchAddon?.findPrevious(this.searchQuery);
135706
+ }
135707
+ }
135708
+ // =====================
135709
+ // Control Methods
135710
+ // =====================
135711
+ toggleAutoScroll() {
135712
+ this.autoScroll = !this.autoScroll;
135713
+ if (this.autoScroll && this.terminal) {
135714
+ this.terminal.scrollToBottom();
135715
+ }
135716
+ }
135717
+ /**
135718
+ * Toggle between filter mode and highlight mode
135719
+ */
135720
+ toggleFilterMode() {
135721
+ this.filterMode = !this.filterMode;
135722
+ this.reRenderFilteredLogs();
135723
+ }
135724
+ /**
135725
+ * Re-render logs based on current filter state
135726
+ * In filter mode: show matching logs with placeholders for hidden entries
135727
+ * In highlight mode: show all logs
135728
+ */
135729
+ reRenderFilteredLogs() {
135730
+ if (!this.terminal) return;
135731
+ this.terminal.clear();
135732
+ this.trailingHiddenCount = 0;
135733
+ if (!this.filterMode || !this.searchQuery) {
135734
+ for (const entry of this.logBuffer) {
135735
+ const formatted = this.formatLogEntry(entry);
135736
+ this.terminal.writeln(formatted);
135272
135737
  }
135738
+ } else {
135739
+ let hiddenCount = 0;
135740
+ for (const entry of this.logBuffer) {
135741
+ if (this.entryMatchesFilter(entry)) {
135742
+ if (hiddenCount > 0) {
135743
+ this.writeHiddenPlaceholder(hiddenCount);
135744
+ hiddenCount = 0;
135745
+ }
135746
+ const formatted = this.formatLogEntry(entry);
135747
+ this.terminal.writeln(formatted);
135748
+ } else {
135749
+ hiddenCount++;
135750
+ }
135751
+ }
135752
+ if (hiddenCount > 0) {
135753
+ this.writeHiddenPlaceholder(hiddenCount);
135754
+ this.trailingHiddenCount = hiddenCount;
135755
+ }
135756
+ }
135757
+ if (this.autoScroll) {
135758
+ this.terminal.scrollToBottom();
135273
135759
  }
135274
135760
  }
135761
+ /**
135762
+ * Write a placeholder line showing how many log entries are hidden by filter
135763
+ */
135764
+ writeHiddenPlaceholder(count2) {
135765
+ const dim = "\x1B[2m";
135766
+ const reset = "\x1B[0m";
135767
+ const text9 = count2 === 1 ? `[1 log line hidden by filter ...]` : `[${count2} log lines hidden by filter ...]`;
135768
+ this.terminal?.writeln(`${dim}${text9}${reset}`);
135769
+ }
135770
+ /**
135771
+ * Clear all logs and reset metrics
135772
+ */
135275
135773
  clearLogs() {
135276
- this.logEntries = [];
135277
- this.requestUpdate();
135774
+ this.terminal?.clear();
135775
+ this.logBuffer = [];
135776
+ this.trailingHiddenCount = 0;
135777
+ this.resetMetrics();
135278
135778
  }
135779
+ /**
135780
+ * Scroll to the bottom of the log
135781
+ */
135279
135782
  scrollToBottom() {
135280
- if (this.logContainer) {
135281
- this.logContainer.scrollTop = this.logContainer.scrollHeight;
135282
- }
135783
+ this.terminal?.scrollToBottom();
135283
135784
  }
135284
- addLog(level, message2, source) {
135285
- const newEntry = {
135286
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135287
- level,
135288
- message: message2,
135289
- source
135785
+ // =====================
135786
+ // Metrics Methods
135787
+ // =====================
135788
+ updateMetrics(level) {
135789
+ this.metrics = {
135790
+ ...this.metrics,
135791
+ [level]: this.metrics[level] + 1,
135792
+ total: this.metrics.total + 1
135290
135793
  };
135291
- this.updateLog([newEntry]);
135794
+ this.recordLogEvent();
135795
+ }
135796
+ recordLogEvent() {
135797
+ this.rateBuffer.push(Date.now());
135798
+ }
135799
+ calculateRate() {
135800
+ const now2 = Date.now();
135801
+ this.rateBuffer = this.rateBuffer.filter((t9) => now2 - t9 < 1e4);
135802
+ const rate = this.rateBuffer.length / 10;
135803
+ if (rate !== this.metrics.rate) {
135804
+ this.metrics = { ...this.metrics, rate };
135805
+ }
135806
+ }
135807
+ resetMetrics() {
135808
+ this.metrics = { debug: 0, info: 0, warn: 0, error: 0, success: 0, total: 0, rate: 0 };
135809
+ this.rateBuffer = [];
135810
+ }
135811
+ // =====================
135812
+ // Lifecycle
135813
+ // =====================
135814
+ async disconnectedCallback() {
135815
+ await super.disconnectedCallback();
135816
+ if (this.resizeObserver) {
135817
+ this.resizeObserver.disconnect();
135818
+ }
135819
+ if (this.terminalThemeSubscription) {
135820
+ this.terminalThemeSubscription.unsubscribe();
135821
+ }
135822
+ if (this.rateInterval) {
135823
+ clearInterval(this.rateInterval);
135824
+ }
135825
+ if (this.terminal) {
135826
+ this.terminal.dispose();
135827
+ }
135292
135828
  }
135293
135829
  };
135294
135830
  _init47 = __decoratorStart(_a45);
135295
135831
  _label6 = new WeakMap();
135832
+ _mode = new WeakMap();
135296
135833
  _logEntries = new WeakMap();
135297
135834
  _autoScroll = new WeakMap();
135298
135835
  _maxEntries = new WeakMap();
135836
+ _highlightKeywords = new WeakMap();
135837
+ _showMetrics = new WeakMap();
135838
+ _searchQuery2 = new WeakMap();
135839
+ _filterMode = new WeakMap();
135840
+ _metrics = new WeakMap();
135841
+ _terminalReady = new WeakMap();
135299
135842
  __decorateElement(_init47, 4, "label", _label_dec6, DeesChartLog, _label6);
135843
+ __decorateElement(_init47, 4, "mode", _mode_dec, DeesChartLog, _mode);
135300
135844
  __decorateElement(_init47, 4, "logEntries", _logEntries_dec, DeesChartLog, _logEntries);
135301
135845
  __decorateElement(_init47, 4, "autoScroll", _autoScroll_dec, DeesChartLog, _autoScroll);
135302
135846
  __decorateElement(_init47, 4, "maxEntries", _maxEntries_dec, DeesChartLog, _maxEntries);
135847
+ __decorateElement(_init47, 4, "highlightKeywords", _highlightKeywords_dec, DeesChartLog, _highlightKeywords);
135848
+ __decorateElement(_init47, 4, "showMetrics", _showMetrics_dec, DeesChartLog, _showMetrics);
135849
+ __decorateElement(_init47, 4, "searchQuery", _searchQuery_dec2, DeesChartLog, _searchQuery2);
135850
+ __decorateElement(_init47, 4, "filterMode", _filterMode_dec, DeesChartLog, _filterMode);
135851
+ __decorateElement(_init47, 4, "metrics", _metrics_dec, DeesChartLog, _metrics);
135852
+ __decorateElement(_init47, 4, "terminalReady", _terminalReady_dec, DeesChartLog, _terminalReady);
135303
135853
  DeesChartLog = __decorateElement(_init47, 0, "DeesChartLog", _DeesChartLog_decorators, DeesChartLog);
135304
135854
  __publicField(DeesChartLog, "demo", demoFunc33);
135305
135855
  __publicField(DeesChartLog, "demoGroup", "Chart");
@@ -135307,13 +135857,12 @@ __publicField(DeesChartLog, "styles", [
135307
135857
  themeDefaultStyles,
135308
135858
  cssManager.defaultStyles,
135309
135859
  i`
135310
- /* TODO: Migrate hardcoded values to --dees-* CSS variables */
135311
135860
  :host {
135312
- font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace;
135861
+ display: block;
135862
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
135313
135863
  color: ${cssManager.bdTheme("hsl(0 0% 3.9%)", "hsl(0 0% 98%)")};
135314
- font-size: 12px;
135315
- line-height: 1.5;
135316
135864
  }
135865
+
135317
135866
  .mainbox {
135318
135867
  position: relative;
135319
135868
  width: 100%;
@@ -135328,143 +135877,197 @@ __publicField(DeesChartLog, "styles", [
135328
135877
 
135329
135878
  .header {
135330
135879
  background: ${cssManager.bdTheme("hsl(0 0% 97%)", "hsl(0 0% 7%)")};
135331
- padding: 12px 16px;
135880
+ padding: 8px 12px;
135332
135881
  border-bottom: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135333
135882
  display: flex;
135334
- justify-content: space-between;
135335
135883
  align-items: center;
135884
+ gap: 12px;
135336
135885
  flex-shrink: 0;
135886
+ flex-wrap: wrap;
135337
135887
  }
135338
135888
 
135339
135889
  .title {
135340
135890
  font-weight: 500;
135341
135891
  font-size: 14px;
135342
135892
  color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
135343
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
135893
+ white-space: nowrap;
135344
135894
  }
135345
135895
 
135346
- .controls {
135896
+ .search-box {
135347
135897
  display: flex;
135348
- gap: 8px;
135898
+ align-items: center;
135899
+ gap: 4px;
135900
+ flex: 1;
135901
+ min-width: 150px;
135902
+ max-width: 300px;
135349
135903
  }
135350
135904
 
135351
- .control-button {
135352
- background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
135353
- border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135354
- border-radius: 6px;
135355
- padding: 6px 12px;
135356
- color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135357
- cursor: pointer;
135905
+ .search-box input {
135906
+ flex: 1;
135907
+ padding: 4px 8px;
135358
135908
  font-size: 12px;
135359
- font-weight: 500;
135360
- transition: all 0.15s;
135361
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
135362
- }
135363
-
135364
- .control-button:hover {
135365
- background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 14.9%)")};
135366
- border-color: ${cssManager.bdTheme("hsl(0 0% 79.8%)", "hsl(0 0% 20.9%)")};
135367
- color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
135909
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135910
+ border-radius: 4px;
135911
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 9%)")};
135912
+ color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
135913
+ outline: none;
135368
135914
  }
135369
135915
 
135370
- .control-button.active {
135371
- background: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 93.9%)")};
135372
- color: ${cssManager.bdTheme("hsl(0 0% 98%)", "hsl(0 0% 3.9%)")};
135916
+ .search-box input:focus {
135917
+ border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
135373
135918
  }
135374
135919
 
135375
- .logContainer {
135376
- flex: 1;
135377
- overflow-y: auto;
135378
- overflow-x: hidden;
135379
- padding: 16px;
135380
- font-size: 12px;
135920
+ .search-box input::placeholder {
135921
+ color: ${cssManager.bdTheme("hsl(0 0% 63.9%)", "hsl(0 0% 45.1%)")};
135381
135922
  }
135382
135923
 
135383
- .logEntry {
135384
- margin-bottom: 4px;
135924
+ .search-nav {
135385
135925
  display: flex;
135386
- white-space: pre-wrap;
135387
- word-break: break-all;
135388
- font-variant-numeric: tabular-nums;
135926
+ gap: 2px;
135389
135927
  }
135390
135928
 
135391
- .timestamp {
135392
- color: ${cssManager.bdTheme("hsl(0 0% 63.9%)", "hsl(0 0% 45.1%)")};
135393
- margin-right: 12px;
135394
- flex-shrink: 0;
135929
+ .search-nav button {
135930
+ padding: 4px 6px;
135931
+ font-size: 11px;
135932
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
135933
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135934
+ border-radius: 3px;
135935
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135936
+ cursor: pointer;
135937
+ line-height: 1;
135395
135938
  }
135396
135939
 
135397
- .level {
135398
- margin-right: 8px;
135399
- padding: 0 6px;
135400
- border-radius: 3px;
135401
- font-weight: 600;
135402
- text-transform: uppercase;
135403
- font-size: 10px;
135404
- flex-shrink: 0;
135940
+ .search-nav button:hover {
135941
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
135942
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
135405
135943
  }
135406
135944
 
135407
- .level.debug {
135945
+ .filter-toggle {
135946
+ padding: 4px 8px;
135947
+ font-size: 11px;
135948
+ font-weight: 500;
135949
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
135950
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135951
+ border-radius: 4px;
135408
135952
  color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135409
- background: ${cssManager.bdTheme("hsl(0 0% 45.1% / 0.1)", "hsl(0 0% 63.9% / 0.1)")};
135953
+ cursor: pointer;
135954
+ transition: all 0.15s;
135955
+ white-space: nowrap;
135410
135956
  }
135411
135957
 
135412
- .level.info {
135413
- color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
135414
- background: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2% / 0.1)", "hsl(217.2 91.2% 59.8% / 0.1)")};
135958
+ .filter-toggle:hover {
135959
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
135960
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
135415
135961
  }
135416
135962
 
135417
- .level.warn {
135418
- color: ${cssManager.bdTheme("hsl(25 95% 53%)", "hsl(25 95% 63%)")};
135419
- background: ${cssManager.bdTheme("hsl(25 95% 53% / 0.1)", "hsl(25 95% 63% / 0.1)")};
135963
+ .filter-toggle.active {
135964
+ background: ${cssManager.bdTheme("hsl(45 93% 47%)", "hsl(45 93% 47%)")};
135965
+ border-color: ${cssManager.bdTheme("hsl(45 93% 47%)", "hsl(45 93% 47%)")};
135966
+ color: hsl(0 0% 9%);
135420
135967
  }
135421
135968
 
135422
- .level.error {
135423
- color: ${cssManager.bdTheme("hsl(0 84.2% 60.2%)", "hsl(0 72.2% 50.6%)")};
135424
- background: ${cssManager.bdTheme("hsl(0 84.2% 60.2% / 0.1)", "hsl(0 72.2% 50.6% / 0.1)")};
135969
+ .controls {
135970
+ display: flex;
135971
+ gap: 6px;
135972
+ margin-left: auto;
135425
135973
  }
135426
135974
 
135427
- .level.success {
135428
- color: ${cssManager.bdTheme("hsl(142.1 76.2% 36.3%)", "hsl(142.1 70.6% 45.3%)")};
135429
- background: ${cssManager.bdTheme("hsl(142.1 76.2% 36.3% / 0.1)", "hsl(142.1 70.6% 45.3% / 0.1)")};
135975
+ .control-button {
135976
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
135977
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
135978
+ border-radius: 4px;
135979
+ padding: 4px 10px;
135980
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135981
+ cursor: pointer;
135982
+ font-size: 12px;
135983
+ font-weight: 500;
135984
+ transition: all 0.15s;
135430
135985
  }
135431
135986
 
135432
- .source {
135433
- color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135434
- margin-right: 8px;
135435
- flex-shrink: 0;
135987
+ .control-button:hover {
135988
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
135989
+ border-color: ${cssManager.bdTheme("hsl(0 0% 79.8%)", "hsl(0 0% 25%)")};
135990
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
135436
135991
  }
135437
135992
 
135438
- .message {
135439
- color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 90%)")};
135993
+ .control-button.active {
135994
+ background: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
135995
+ border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
135996
+ color: white;
135997
+ }
135998
+
135999
+ .terminal-container {
135440
136000
  flex: 1;
136001
+ overflow: hidden;
136002
+ padding: 8px;
136003
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 3.9%)")};
135441
136004
  }
135442
136005
 
135443
- .empty-state {
136006
+ .terminal-container .xterm {
136007
+ height: 100%;
136008
+ }
136009
+
136010
+ .loading-state {
135444
136011
  display: flex;
135445
136012
  align-items: center;
135446
136013
  justify-content: center;
135447
136014
  height: 100%;
135448
136015
  color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
135449
136016
  font-style: italic;
136017
+ font-size: 13px;
135450
136018
  }
135451
136019
 
135452
- /* Custom scrollbar */
135453
- .logContainer::-webkit-scrollbar {
136020
+ .metrics-bar {
136021
+ background: ${cssManager.bdTheme("hsl(0 0% 97%)", "hsl(0 0% 7%)")};
136022
+ border-top: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
136023
+ padding: 6px 12px;
136024
+ display: flex;
136025
+ gap: 16px;
136026
+ font-size: 11px;
136027
+ font-weight: 500;
136028
+ flex-shrink: 0;
136029
+ }
136030
+
136031
+ .metric {
136032
+ display: flex;
136033
+ align-items: center;
136034
+ gap: 4px;
136035
+ }
136036
+
136037
+ .metric::before {
136038
+ content: '';
135454
136039
  width: 8px;
136040
+ height: 8px;
136041
+ border-radius: 50%;
136042
+ }
136043
+
136044
+ .metric.error::before {
136045
+ background: hsl(0 84.2% 60.2%);
135455
136046
  }
135456
136047
 
135457
- .logContainer::-webkit-scrollbar-track {
135458
- background: ${cssManager.bdTheme("hsl(0 0% 95%)", "hsl(0 0% 10%)")};
136048
+ .metric.warn::before {
136049
+ background: hsl(25 95% 53%);
135459
136050
  }
135460
136051
 
135461
- .logContainer::-webkit-scrollbar-thumb {
135462
- background: ${cssManager.bdTheme("hsl(0 0% 70%)", "hsl(0 0% 30%)")};
135463
- border-radius: 4px;
136052
+ .metric.info::before {
136053
+ background: hsl(222.2 47.4% 51.2%);
135464
136054
  }
135465
136055
 
135466
- .logContainer::-webkit-scrollbar-thumb:hover {
135467
- background: ${cssManager.bdTheme("hsl(0 0% 60%)", "hsl(0 0% 40%)")};
136056
+ .metric.success::before {
136057
+ background: hsl(142.1 76.2% 36.3%);
136058
+ }
136059
+
136060
+ .metric.debug::before {
136061
+ background: hsl(0 0% 63.9%);
136062
+ }
136063
+
136064
+ .metric.rate {
136065
+ margin-left: auto;
136066
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
136067
+ }
136068
+
136069
+ .metric.rate::before {
136070
+ display: none;
135468
136071
  }
135469
136072
  `
135470
136073
  ]);
@@ -159358,9 +159961,9 @@ var openWidgetContextMenu = ({
159358
159961
  // ts_web/elements/dees-dashboardgrid/dees-dashboardgrid.ts
159359
159962
  init_dist_ts26();
159360
159963
  init_dees_icon();
159361
- var _previewWidgets_dec, _resolvedMargins_dec, _metrics_dec, _placeholderPosition_dec, _activeBreakpoint_dec, _layouts_dec, _showGridLines_dec, _rtl_dec, _cellHeightUnit_dec, _enableAnimation_dec, _editable_dec, _columns_dec2, _margin_dec, _cellHeight_dec, _widgets_dec2, _a75, _DeesDashboardgrid_decorators, _init78, _widgets2, _cellHeight, _margin, _columns2, _editable, _enableAnimation, _cellHeightUnit, _rtl, _showGridLines, _layouts, _activeBreakpoint, _placeholderPosition, _metrics, _resolvedMargins, _previewWidgets;
159964
+ var _previewWidgets_dec, _resolvedMargins_dec, _metrics_dec2, _placeholderPosition_dec, _activeBreakpoint_dec, _layouts_dec, _showGridLines_dec, _rtl_dec, _cellHeightUnit_dec, _enableAnimation_dec, _editable_dec, _columns_dec2, _margin_dec, _cellHeight_dec, _widgets_dec2, _a75, _DeesDashboardgrid_decorators, _init78, _widgets2, _cellHeight, _margin, _columns2, _editable, _enableAnimation, _cellHeightUnit, _rtl, _showGridLines, _layouts, _activeBreakpoint, _placeholderPosition, _metrics2, _resolvedMargins, _previewWidgets;
159362
159965
  _DeesDashboardgrid_decorators = [t4("dees-dashboardgrid")];
159363
- var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({ type: Array })], _cellHeight_dec = [n5({ type: Number })], _margin_dec = [n5({ type: Object })], _columns_dec2 = [n5({ type: Number })], _editable_dec = [n5({ type: Boolean })], _enableAnimation_dec = [n5({ type: Boolean, reflect: true })], _cellHeightUnit_dec = [n5({ type: String })], _rtl_dec = [n5({ type: Boolean })], _showGridLines_dec = [n5({ type: Boolean })], _layouts_dec = [n5({ attribute: false })], _activeBreakpoint_dec = [n5({ type: String })], _placeholderPosition_dec = [r5()], _metrics_dec = [r5()], _resolvedMargins_dec = [r5()], _previewWidgets_dec = [r5()], _a75) {
159966
+ var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({ type: Array })], _cellHeight_dec = [n5({ type: Number })], _margin_dec = [n5({ type: Object })], _columns_dec2 = [n5({ type: Number })], _editable_dec = [n5({ type: Boolean })], _enableAnimation_dec = [n5({ type: Boolean, reflect: true })], _cellHeightUnit_dec = [n5({ type: String })], _rtl_dec = [n5({ type: Boolean })], _showGridLines_dec = [n5({ type: Boolean })], _layouts_dec = [n5({ attribute: false })], _activeBreakpoint_dec = [n5({ type: String })], _placeholderPosition_dec = [r5()], _metrics_dec2 = [r5()], _resolvedMargins_dec = [r5()], _previewWidgets_dec = [r5()], _a75) {
159364
159967
  constructor() {
159365
159968
  super(...arguments);
159366
159969
  __privateAdd(this, _widgets2, __runInitializers(_init78, 8, this, [])), __runInitializers(_init78, 11, this);
@@ -159375,7 +159978,7 @@ var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({
159375
159978
  __privateAdd(this, _layouts, __runInitializers(_init78, 44, this)), __runInitializers(_init78, 47, this);
159376
159979
  __privateAdd(this, _activeBreakpoint, __runInitializers(_init78, 48, this, "base")), __runInitializers(_init78, 51, this);
159377
159980
  __privateAdd(this, _placeholderPosition, __runInitializers(_init78, 52, this, null)), __runInitializers(_init78, 55, this);
159378
- __privateAdd(this, _metrics, __runInitializers(_init78, 56, this, null)), __runInitializers(_init78, 59, this);
159981
+ __privateAdd(this, _metrics2, __runInitializers(_init78, 56, this, null)), __runInitializers(_init78, 59, this);
159379
159982
  __privateAdd(this, _resolvedMargins, __runInitializers(_init78, 60, this, null)), __runInitializers(_init78, 63, this);
159380
159983
  __privateAdd(this, _previewWidgets, __runInitializers(_init78, 64, this, null)), __runInitializers(_init78, 67, this);
159381
159984
  __publicField(this, "containerBounds", null);
@@ -159952,7 +160555,7 @@ _showGridLines = new WeakMap();
159952
160555
  _layouts = new WeakMap();
159953
160556
  _activeBreakpoint = new WeakMap();
159954
160557
  _placeholderPosition = new WeakMap();
159955
- _metrics = new WeakMap();
160558
+ _metrics2 = new WeakMap();
159956
160559
  _resolvedMargins = new WeakMap();
159957
160560
  _previewWidgets = new WeakMap();
159958
160561
  __decorateElement(_init78, 4, "widgets", _widgets_dec2, DeesDashboardgrid, _widgets2);
@@ -159967,7 +160570,7 @@ __decorateElement(_init78, 4, "showGridLines", _showGridLines_dec, DeesDashboard
159967
160570
  __decorateElement(_init78, 4, "layouts", _layouts_dec, DeesDashboardgrid, _layouts);
159968
160571
  __decorateElement(_init78, 4, "activeBreakpoint", _activeBreakpoint_dec, DeesDashboardgrid, _activeBreakpoint);
159969
160572
  __decorateElement(_init78, 4, "placeholderPosition", _placeholderPosition_dec, DeesDashboardgrid, _placeholderPosition);
159970
- __decorateElement(_init78, 4, "metrics", _metrics_dec, DeesDashboardgrid, _metrics);
160573
+ __decorateElement(_init78, 4, "metrics", _metrics_dec2, DeesDashboardgrid, _metrics2);
159971
160574
  __decorateElement(_init78, 4, "resolvedMargins", _resolvedMargins_dec, DeesDashboardgrid, _resolvedMargins);
159972
160575
  __decorateElement(_init78, 4, "previewWidgets", _previewWidgets_dec, DeesDashboardgrid, _previewWidgets);
159973
160576
  DeesDashboardgrid = __decorateElement(_init78, 0, "DeesDashboardgrid", _DeesDashboardgrid_decorators, DeesDashboardgrid);