diff --git a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.html b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.html index 5a440208..357206de 100644 --- a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.html +++ b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.html @@ -1,158 +1,202 @@
- - -
- - Connecting to server... -
-
- - - - - -
-
-

Application Logs

- + + +
+ + Connecting to server...
- -
- + - -
-
- - - -
- -
-
- -
- -
-
-
- - - - -
- -
- - - - - - - - -
-
- - - - - - - - Timestamp - Level - Category - Message - Job Name - Instance - - - - - - - - - {{ log.timestamp | date: 'yyyy-MM-dd' }} -
{{ log.timestamp | date: 'HH:mm:ss' }}
- - - - - - {{ log.category }} - - - - {{ log.message }} - - - {{ log.jobName }} - {{ log.instanceName }} - - - - - -
-
{{ log.exception }}
-
- - -
- - - - - -
- -
- No logs found -
-

Waiting for new logs or try adjusting your filters

- -
-
Not connected to log hub
-

Attempting to reconnect to the server...

- + + + + +
+
+

Application Logs

+
- +
- - -
- -
+ + + +
+
+ + + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + Timestamp + Level + Category + Message + Job Name + Instance + + + + + + + + + {{ log.timestamp | date : "yyyy-MM-dd" }} +
+ {{ log.timestamp | date : "HH:mm:ss" }} +
+ + + + + + {{ log.category }} + + + + {{ log.message }} + + + {{ log.jobName }} + + {{ log.instanceName }} + + + + + + +
+
{{ log.exception }}
+
+ + +
+ + + + + +
+ +
No logs found
+

Waiting for new logs or try adjusting your filters

+ +
+
Not connected to log hub
+

Attempting to reconnect to the server...

+ +
+
+
+ + +
+
+
diff --git a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.scss b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.scss index 77d18fc8..26e7cf57 100644 --- a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.scss +++ b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.scss @@ -13,101 +13,7 @@ } ::ng-deep { - /* Card styling - add subtle animation on hover */ - .p-card { - height: 100%; - display: flex; - flex-direction: column; - transition: box-shadow 0.3s; - - .p-card-content { - flex: 1; - padding: 0 !important; - overflow: hidden; - display: flex; - flex-direction: column; - } - } - - /* Table styling - improved for readability */ - .p-datatable { - flex: 1; - display: flex; - flex-direction: column; - - .p-datatable-wrapper { - flex: 1; - } - - .p-datatable-header { - background-color: var(--surface-card); - padding: 1rem; - border-bottom: 1px solid var(--surface-border); - } - - .p-datatable-thead > tr > th { - background-color: var(--surface-section); - color: var(--text-color); - border-color: var(--surface-border); - padding: 0.75rem 1rem; - font-weight: 600; - position: sticky; - top: 0; - z-index: 1; - transition: background-color 0.2s; - - &:hover { - background-color: var(--surface-hover); - } - } - - .p-datatable-tbody { - > tr { - transition: background-color 0.2s; - border-radius: var(--border-radius); - - &:hover { - background-color: var(--surface-hover); - } - - &:nth-child(even) { - background-color: var(--surface-ground); - } - - > td { - padding: 0.75rem 1rem; - border-color: var(--surface-border); - transition: background-color 0.2s; - } - - /* Highlight rows with errors */ - &.error-row > td:first-child { - border-left: 4px solid var(--red-500); - } - - &.warning-row > td:first-child { - border-left: 4px solid var(--yellow-500); - } - } - } - - .p-paginator { - background-color: var(--surface-section); - border-color: var(--surface-border); - padding: 0.5rem; - display: flex; - align-items: center; - justify-content: space-between; - } - } - /* Exception handling with improved styling */ - .exception-row { - background-color: var(--surface-hover) !important; - transition: max-height 0.3s; - overflow: hidden; - } - .exception-cell { padding: 0 !important; } @@ -127,143 +33,6 @@ transition: all 0.3s; } - /* Tag styling with improved visibility */ - .p-tag { - font-weight: 600; - border-radius: var(--border-radius); - transition: all 0.2s; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - - &:hover { - transform: translateY(-1px); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); - } - - &.p-tag-danger { - background-color: var(--red-500); - color: var(--red-50); - } - - &.p-tag-warning { - background-color: var(--yellow-500); - color: var(--yellow-900); - } - - &.p-tag-info { - background-color: var(--blue-500); - color: var(--blue-50); - } - - &.p-tag-success { - background-color: var(--green-500); - color: var(--green-50); - } - } - - /* Form controls styling */ - .p-dropdown { - min-width: 180px; - border-radius: var(--border-radius); - transition: box-shadow 0.2s, border-color 0.2s; - - &:hover, &.p-focus { - border-color: var(--primary-color); - } - - &.p-focus { - box-shadow: 0 0 0 1px var(--primary-100); - } - - .p-dropdown-label { - padding: 0.5rem 0.75rem; - } - - /* Fix for consistent height dropdowns */ - &.fixed-height-dropdown { - .p-dropdown-label { - display: flex; - align-items: center; - height: 2.5rem; /* Fixed height for consistency */ - } - - .level-indicator { - display: flex; - align-items: center; - height: 100%; - } - - /* Ensure tags inside dropdowns maintain proper sizing */ - .level-tag { - padding: 0.25rem 0.5rem; - font-size: 0.85rem; - height: auto; - line-height: 1; - } - } - } - - .p-input-icon-left { - width: 100%; - max-width: 300px; - - input { - border-radius: var(--border-radius); - width: 100%; - transition: box-shadow 0.2s, border-color 0.2s; - padding: 0.5rem 0.75rem 0.5rem 2rem; - - &:hover, &:focus { - border-color: var(--primary-color); - } - - &:focus { - box-shadow: 0 0 0 1px var(--primary-100); - } - } - - i { - left: 0.75rem; - color: var(--text-color-secondary); - } - } - - /* Button styling with micro-interactions */ - .p-button { - border-radius: var(--border-radius); - transition: background-color 0.2s, color 0.2s, border-color 0.2s, transform 0.2s, box-shadow 0.2s; - - &:hover { - transform: translateY(-1px); - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); - } - - &:active { - transform: translateY(0); - } - - &.p-button-outlined { - background-color: transparent; - color: var(--primary-color); - border-color: var(--primary-color); - - &:hover { - background-color: var(--primary-50); - } - } - - &.p-button-text { - &:hover { - background-color: var(--surface-hover); - } - } - - &.p-button-rounded { - &:hover { - transform: translateY(-1px) rotate(15deg); - } - } - } - /* Empty state styling */ .empty-message { padding: 2rem; @@ -288,37 +57,4 @@ } } } -} - -/* Responsive adjustments */ -@media screen and (max-width: 768px) { - .logs-container { - height: calc(100vh - 7rem); - - .filter-container { - flex-direction: column; - gap: 1rem; - - > div { - width: 100%; - - .p-dropdown, .p-input-icon-left { - width: 100%; - max-width: 100%; - } - } - } - - ::ng-deep { - .p-datatable { - .p-datatable-thead > tr > th { - padding: 0.5rem; - } - - .p-datatable-tbody > tr > td { - padding: 0.5rem; - } - } - } - } } \ No newline at end of file diff --git a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.ts b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.ts index 633145fd..512ae608 100644 --- a/code/UI/src/app/logging/logs-viewer/logs-viewer.component.ts +++ b/code/UI/src/app/logging/logs-viewer/logs-viewer.component.ts @@ -7,7 +7,7 @@ import { Subject, takeUntil } from 'rxjs'; import { TableModule } from 'primeng/table'; import { InputTextModule } from 'primeng/inputtext'; import { ButtonModule } from 'primeng/button'; -import { DropdownModule } from 'primeng/dropdown'; +import { SelectModule } from 'primeng/select'; import { TagModule } from 'primeng/tag'; import { CardModule } from 'primeng/card'; import { ToolbarModule } from 'primeng/toolbar'; @@ -29,7 +29,7 @@ import { LogEntry } from '../../core/models/signalr.models'; TableModule, InputTextModule, ButtonModule, - DropdownModule, + SelectModule, TagModule, CardModule, ToolbarModule, @@ -51,7 +51,7 @@ export class LogsViewerComponent implements OnInit, OnDestroy { // Filter state levelFilter = signal(null); categoryFilter = signal(null); - searchFilter = ''; + searchFilter = signal(''); // Computed values filteredLogs = computed(() => { @@ -66,7 +66,7 @@ export class LogsViewerComponent implements OnInit, OnDestroy { } if (this.searchFilter) { - const search = this.searchFilter.toLowerCase(); + const search = this.searchFilter().toLowerCase(); filtered = filtered.filter(log => log.message.toLowerCase().includes(search) || (log.exception && log.exception.toLowerCase().includes(search))); @@ -112,22 +112,22 @@ export class LogsViewerComponent implements OnInit, OnDestroy { this.destroy$.complete(); } - onLevelFilterChange(level: string | null): void { + onLevelFilterChange(level: string): void { this.levelFilter.set(level); } - onCategoryFilterChange(category: string | null): void { + onCategoryFilterChange(category: string): void { this.categoryFilter.set(category); } onSearchChange(event: Event): void { - this.searchFilter = (event.target as HTMLInputElement).value; + this.searchFilter.set((event.target as HTMLInputElement).value); } clearFilters(): void { this.levelFilter.set(null); this.categoryFilter.set(null); - this.searchFilter = ''; + this.searchFilter.set(''); } getSeverity(level: string): string {