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 }} |
-
-
-
-
- |
-
- |
-
-
-
-
-
-
-
-
-
-
- No logs found
-
- Waiting for new logs or try adjusting your filters
-
-
- Not connected to log hub
- Attempting to reconnect to the 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 }}
+ |
+
+
+
+
+ |
+
+ |
+
+
+
+
+
+
+
+
+
+ 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 {