diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/log-viewer-date-range-selector.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/log-viewer-date-range-selector.element.ts index 71d6c6c8440e..7318a80b188b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/log-viewer-date-range-selector.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/components/log-viewer-date-range-selector.element.ts @@ -1,4 +1,3 @@ -import type { UmbLogViewerDateRange } from '../workspace/logviewer-workspace.context.js'; import { UMB_APP_LOG_VIEWER_CONTEXT } from '../workspace/logviewer-workspace.context-token.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; @@ -32,9 +31,9 @@ export class UmbLogViewerDateRangeSelectorElement extends UmbLitElement { #observeStuff() { this.observe( this._logViewerContext?.dateRange, - (dateRange: UmbLogViewerDateRange) => { - this._startDate = dateRange.startDate; - this._endDate = dateRange.endDate; + (dateRange) => { + this._startDate = dateRange?.startDate ?? ''; + this._endDate = dateRange?.endDate ?? ''; }, '_observeDateRange', ); diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts index 3e1bed642ee1..322c89fb8036 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-messages-list.element.ts @@ -5,6 +5,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { LogMessageResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { DirectionModel } from '@umbraco-cms/backoffice/external/backend-api'; import { consumeContext } from '@umbraco-cms/backoffice/context-api'; +import { skip } from '@umbraco-cms/backoffice/external/rxjs'; @customElement('umb-log-viewer-messages-list') export class UmbLogViewerMessagesListElement extends UmbLitElement { @@ -50,6 +51,17 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement { this.observe(this._logViewerContext?.sortingDirection, (direction) => { this._sortingDirection = direction ?? this._sortingDirection; }); + + // Observe filter expression changes to trigger search + // Only observes when this component is mounted (when logs are visible) + this.observe( + this._logViewerContext?.filterExpression.pipe( + skip(1), // Skip initial value to avoid duplicate search on page load + ), + () => { + this._logViewerContext?.getLogs(); + }, + ); } #sortLogs() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts index e4563d976123..ed1533ab6df9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/components/log-viewer-search-input.element.ts @@ -3,15 +3,16 @@ import { UMB_LOG_VIEWER_SAVE_SEARCH_MODAL } from './log-viewer-search-input-moda import { css, html, customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; import { escapeHTML } from '@umbraco-cms/backoffice/utils'; import { query as getQuery, path, toQueryString } from '@umbraco-cms/backoffice/router'; -import { Subject, debounceTime, tap } from '@umbraco-cms/backoffice/external/rxjs'; import { umbConfirmModal, umbOpenModal } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbDropdownElement } from '@umbraco-cms/backoffice/components'; import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; +import { consumeContext } from '@umbraco-cms/backoffice/context-api'; +import { UmbStringState } from '@umbraco-cms/backoffice/observable-api'; +import { debounceTime, skip } from '@umbraco-cms/backoffice/external/rxjs'; import './log-viewer-search-input-modal.element.js'; -import { consumeContext } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-log-viewer-search-input') export class UmbLogViewerSearchInputElement extends UmbLitElement { @@ -24,14 +25,11 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { @state() private _inputQuery = ''; - @state() - private _showLoader = false; - @state() private _isQuerySaved = false; - // TODO: Revisit this code, to not use RxJS directly: - #inputQuery$ = new Subject(); + // Local state for debouncing user input before updating context + #localQueryState = new UmbStringState(''); #logViewerContext?: typeof UMB_APP_LOG_VIEWER_CONTEXT.TYPE; @@ -48,17 +46,17 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { constructor() { super(); - this.#inputQuery$ - .pipe( - tap(() => (this._showLoader = true)), + // Debounce local input and update context + this.observe( + this.#localQueryState.asObservable().pipe( + skip(1), // Skip initial value debounceTime(250), - ) - .subscribe((query) => { + ), + (query) => { this._logViewerContext?.setFilterExpression(query); this.#persist(query); - this._isQuerySaved = this._savedSearches.some((search) => search.query === query); - this._showLoader = false; - }); + }, + ); } #observeStuff() { @@ -75,11 +73,14 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { #setQuery(event: Event) { const target = event.target as UUIInputElement; - this.#inputQuery$.next(target.value as string); + const query = target.value as string; + // Update local state which will debounce before updating context + this.#localQueryState.setValue(query); } #setQueryFromSavedSearch(query: string) { - this.#inputQuery$.next(query); + this._logViewerContext?.setFilterExpression(query); + this.#persist(query); this._searchDropdownElement.open = false; } @@ -95,8 +96,14 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { } #clearQuery() { - this.#inputQuery$.next(''); this._logViewerContext?.setFilterExpression(''); + this.#persist(''); + this.#localQueryState.setValue(''); + } + + #refreshSearch() { + // Force immediate search, bypassing debounce + this._logViewerContext?.getLogs(); } #saveSearch(savedSearch: SavedLogSearchResponseModel) { @@ -137,17 +144,14 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { slot="trigger" @input=${this.#setQuery} .value=${this._inputQuery}> - ${this._showLoader - ? html`
- -
` - : ''} ${this._inputQuery ? html`${!this._isQuerySaved ? html`` - : ''}` : html``} @@ -198,13 +202,6 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { flex: 1; } - #loader-container { - display: flex; - justify-content: center; - align-items: center; - margin: 0 var(--uui-size-space-4); - } - .saved-search-item { display: flex; justify-content: space-between; diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts index 317711c2e51a..513dd7ee50b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/views/search/log-search-view.element.ts @@ -34,7 +34,7 @@ export class UmbLogViewerSearchViewElement extends UmbLitElement { override render() { return html` -