@ethlete/components 1.0.0-next.40 → 1.0.0-next.41
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.
- package/CHANGELOG.md +45 -0
- package/fesm2022/ethlete-components.mjs +942 -280
- package/fesm2022/ethlete-components.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ethlete-components.d.ts +160 -24
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, input, booleanAttribute, signal, computed, effect, untracked, Directive, inject, afterNextRender, DestroyRef, TemplateRef, ElementRef, model, linkedSignal, ViewEncapsulation, Component, numberAttribute, Injector, output, runInInjectionContext, contentChild, NgZone, ApplicationRef, viewChild, ViewContainerRef, createEnvironmentInjector, DOCUMENT, EnvironmentInjector, inputBinding, createComponent, isSignal, assertInInjectionContext, isDevMode as isDevMode$1, provideEnvironmentInitializer, viewChildren, contentChildren, afterRenderEffect, outputBinding, afterEveryRender, PLATFORM_ID } from '@angular/core';
|
|
3
3
|
import * as i1 from '@ethlete/core';
|
|
4
|
-
import { injectHostElement, RuntimeError, createComponentId, ProvideColorDirective, defineLabels, toProvideFn, toInjectFn, toToken, injectStyleManager, SurfaceInteractiveDirective, createCanAnimateSignal, ColorInteractiveDirective, injectSuccessTheme, injectWarningTheme, injectErrorTheme, injectLocale, defineStaticRootProvider, inferMimeType, injectColorThemes, injectRenderer, ProvideSurfaceDirective, COLOR_PROVIDER, SURFACE_PROVIDER, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceContextTracker, injectBoundaryElement, ANIMATED_LIFECYCLE_TOKEN, resolveAppRootColorProvider, resolveSurfaceByElevation, createCssSurfaceName, provideBoundaryElement, AnimatedLifecycleDirective, injectBreakpointObserver, isHTMLElement, equal, animationDebugLog, defineRootProvider, injectOverlayRuntime, anchoredOverlayPosition, enableAnchoredOverlayPositionExtras, randomId, forceReflow, nextFrame, elementCanScroll, matchesReducedMotion, createSwipeTracker, ScrollObserverDirective, signalElementScrollState, ScrollObserverStartDirective, ScrollObserverEndDirective, applyHostListener, injectQueryParam, createUnsavedChangesTracker, createDocumentElementSignal, defineProvider, fromNextFrame, injectRoute, AnimatedIfDirective, signalElementDimensions, applyInitialFocus, syncSignal, AutoSurfaceDirective, setInputSignal, injectTemplateRef, signalHostElementScrollState, applyStructuredDataBinding, typedBreakpointTransform, signalElementChildren, signalElementIntersection, signalHostAttributes, signalHostClasses, signalHostStyles, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, injectPrefersReducedMotion, injectIsDocumentVisible, signalHostElementIntersection, clamp as clamp$1, copyToClipboard, injectAnimatedBlockSize, injectObserveBreakpoint, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, createFlipAnimation, createObjectUrlHandle, createFlipAnimationGroup, ColorInteractiveHasFocusDirective, injectFocusVisibleTracker, htmlToMarkdown, markdownToHtml, injectHasTouchInput, signalHostElementDimensions, DragHandleDirective, ResizeHandlesComponent, numberBreakpointTransform, applyLinkBinding, applyHeadTitleBinding, injectFileDownload,
|
|
4
|
+
import { injectHostElement, RuntimeError, createComponentId, ProvideColorDirective, defineLabels, toProvideFn, toInjectFn, toToken, injectStyleManager, SurfaceInteractiveDirective, createCanAnimateSignal, ColorInteractiveDirective, injectSuccessTheme, injectWarningTheme, injectErrorTheme, injectLocale, defineStaticRootProvider, inferMimeType, injectColorThemes, injectRenderer, ProvideSurfaceDirective, COLOR_PROVIDER, SURFACE_PROVIDER, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceContextTracker, injectBoundaryElement, ANIMATED_LIFECYCLE_TOKEN, resolveAppRootColorProvider, resolveSurfaceByElevation, createCssSurfaceName, provideBoundaryElement, AnimatedLifecycleDirective, injectBreakpointObserver, isHTMLElement, equal, animationDebugLog, defineRootProvider, injectOverlayRuntime, anchoredOverlayPosition, enableAnchoredOverlayPositionExtras, randomId, forceReflow, nextFrame, elementCanScroll, matchesReducedMotion, createSwipeTracker, ScrollObserverDirective, signalElementScrollState, ScrollObserverStartDirective, ScrollObserverEndDirective, applyHostListener, injectQueryParam, createUnsavedChangesTracker, createDocumentElementSignal, defineProvider, fromNextFrame, injectRoute, AnimatedIfDirective, signalElementDimensions, applyInitialFocus, syncSignal, AutoSurfaceDirective, setInputSignal, injectTemplateRef, signalHostElementScrollState, applyStructuredDataBinding, typedBreakpointTransform, signalElementChildren, signalElementIntersection, signalHostAttributes, signalHostClasses, signalHostStyles, getScrollContainerTarget, getScrollItemTarget, getElementScrollCoordinates, provideBreakpointInstance, signalClasses, useCursorDragScroll, signalStyles, getScrollSnapTarget, injectPrefersReducedMotion, injectIsDocumentVisible, signalHostElementIntersection, clamp as clamp$1, copyToClipboard, injectAnimatedBlockSize, injectObserveBreakpoint, AnimatableDirective, ColorInteractiveContainerDirective, ColorInteractiveExcludeDirective, createFlipAnimation, createObjectUrlHandle, createFlipAnimationGroup, ColorInteractiveHasFocusDirective, injectFocusVisibleTracker, htmlToMarkdown, markdownToHtml, injectHasTouchInput, dragGestureFrom, signalHostElementDimensions, DragHandleDirective, ResizeHandlesComponent, numberBreakpointTransform, applyLinkBinding, applyHeadTitleBinding, injectFileDownload, injectViewportSize, getFocusableElements, injectRouterEvent, canUseSessionMemory, createAutoSessionMemoryKey, createSessionMemory } from '@ethlete/core';
|
|
5
5
|
import { NgTemplateOutlet, NgComponentOutlet, Location, DOCUMENT as DOCUMENT$1, isPlatformBrowser } from '@angular/common';
|
|
6
6
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
7
7
|
import { format, startOfWeek, startOfDay, endOfWeek, isBefore, addDays, endOfMonth, startOfMonth, isSameYear, isSameMonth, isSameDay, startOfYear, isAfter, addYears, addMonths, setMonth, setYear, getDate, setDate, lastDayOfMonth, getWeek, endOfYear, parse, isValid, setSeconds, setMinutes, setHours, setMilliseconds, endOfDay, eachDayOfInterval, addMinutes, addHours } from 'date-fns';
|
|
8
8
|
import { takeUntilDestroyed, toObservable, toSignal, outputFromObservable, outputToObservable, rxResource } from '@angular/core/rxjs-interop';
|
|
9
|
-
import { Subject, take, tap, timer, takeUntil, fromEvent, filter, combineLatest, switchMap, map, distinctUntilChanged, EMPTY, debounceTime, merge, defer, finalize, of, isObservable, from, catchError, firstValueFrom, concat, scan, interval, animationFrameScheduler, EmptyError, exhaustMap, Observable, shareReplay, defaultIfEmpty, expand, toArray, mergeMap } from 'rxjs';
|
|
9
|
+
import { Subject, take, tap, timer, takeUntil, fromEvent, filter, combineLatest, switchMap, map, distinctUntilChanged, EMPTY, debounceTime, merge, defer, finalize, of, isObservable, from, catchError, firstValueFrom, concat, scan, interval, animationFrameScheduler, EmptyError, animationFrames, NEVER, exhaustMap, Observable, shareReplay, defaultIfEmpty, expand, toArray, mergeMap } from 'rxjs';
|
|
10
10
|
import * as i1$1 from '@angular/router';
|
|
11
11
|
import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
|
|
12
12
|
import { withArgs, queryStateSignal, isQueryStateSuccess, isQueryStateFailure, isQueryStateLoading, executeUntilSettled, extractQuery, queryComputed, hasQueryDevtoolsOverridesAtPath, detectPaginationShape, isDateShapedLeaf, generateQueryDevtoolsStringPreset, generateQueryDevtoolsNumberPreset, collectLeafPaths, QUERY_DEVTOOLS_FAULT_STATUSES, clearQueryDevtoolsFaults, setQueryDevtoolsFault, clearQueryDevtoolsTombstones, queryDevtoolsResponseHistory, queryDevtoolsEntries, queryDevtoolsFaults, EMPTY_QUERY_DEVTOOLS_FAULT, isQueryDevtoolsFaultArmed, measureQueryDevtoolsPayload, createQueryErrorResponse, sumQueryDevtoolsStats, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleEn, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToTitleDe, queryErrorMessages } from '@ethlete/query';
|
|
13
13
|
import { FORM_FIELD, createManagedMetadataKey, metadata, validate, form } from '@angular/forms/signals';
|
|
14
14
|
import { tap as tap$1 } from 'rxjs/operators';
|
|
15
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
|
15
|
+
import { HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
|
16
16
|
|
|
17
17
|
// codes 3600-3699
|
|
18
18
|
const ACCORDION_ERROR_CODES = {
|
|
@@ -9790,11 +9790,11 @@ const mergeOverlayBreakpointConfigs = (...configs) => {
|
|
|
9790
9790
|
*/
|
|
9791
9791
|
class AnchoredDialogStylesComponent {
|
|
9792
9792
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AnchoredDialogStylesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9793
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: AnchoredDialogStylesComponent, isStandalone: true, selector: "et-overlay-anchored-dialog-styles", ngImport: i0, template: '', isInline: true, styles: ["@layer components{.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from
|
|
9793
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: AnchoredDialogStylesComponent, isStandalone: true, selector: "et-overlay-anchored-dialog-styles", ngImport: i0, template: '', isInline: true, styles: ["@layer components{.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0) scale(.85)!important;opacity:0}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-to{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0) scale(.7)!important;opacity:0}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:transform .3s var(--ease-out-5),opacity .3s var(--ease-out-5)}@supports (transition-timing-function: linear(0,1)){.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:transform .3s var(--ease-spring-2),opacity .3s var(--ease-out-5)}}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-active{transition:transform .15s var(--ease-out-5),opacity .15s var(--ease-out-5)}@media(prefers-reduced-motion:reduce){.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:opacity .3s var(--ease-out-5)}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-active{transition:opacity .15s var(--ease-out-5)}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from,.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-to{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0)!important}}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
9794
9794
|
}
|
|
9795
9795
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AnchoredDialogStylesComponent, decorators: [{
|
|
9796
9796
|
type: Component,
|
|
9797
|
-
args: [{ selector: 'et-overlay-anchored-dialog-styles', template: '', encapsulation: ViewEncapsulation.None, styles: ["@layer components{.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from
|
|
9797
|
+
args: [{ selector: 'et-overlay-anchored-dialog-styles', template: '', encapsulation: ViewEncapsulation.None, styles: ["@layer components{.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0) scale(.85)!important;opacity:0}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-to{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0) scale(.7)!important;opacity:0}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:transform .3s var(--ease-out-5),opacity .3s var(--ease-out-5)}@supports (transition-timing-function: linear(0,1)){.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:transform .3s var(--ease-spring-2),opacity .3s var(--ease-out-5)}}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-active{transition:transform .15s var(--ease-out-5),opacity .15s var(--ease-out-5)}@media(prefers-reduced-motion:reduce){.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-active{transition:opacity .3s var(--ease-out-5)}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-active{transition:opacity .15s var(--ease-out-5)}.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-enter-from,.et-overlay.et-with-default-animation.et-overlay--anchored-dialog.et-animation-leave-to{transform:translate3d(var(--et-overlay-anchored-x, 0px),var(--et-overlay-anchored-y, 0px),0)!important}}}\n"] }]
|
|
9798
9798
|
}] });
|
|
9799
9799
|
|
|
9800
9800
|
const DEFAULT_ANCHORED_DIALOG_POSITION = {
|
|
@@ -9825,23 +9825,12 @@ const ANCHORED_DIALOG_STRATEGY_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
9825
9825
|
const renderer = injectRenderer();
|
|
9826
9826
|
const build = (config = {}) => {
|
|
9827
9827
|
const cfg = mergeOverlayBreakpointConfigs(defaults, config);
|
|
9828
|
-
|
|
9828
|
+
// must run while the pane is untransformed - both hooks are called before the enter/leave classes land
|
|
9829
|
+
const applyOriginTransformOrigin = (context, origin) => {
|
|
9829
9830
|
const { containerEl } = context;
|
|
9830
|
-
const originRect = originElement.getBoundingClientRect();
|
|
9831
9831
|
const overlayRect = containerEl.getBoundingClientRect();
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
const originCenterX = originRect.left + originRect.width / 2;
|
|
9835
|
-
const originCenterY = originRect.top + originRect.height / 2;
|
|
9836
|
-
const overlayCenterX = overlayRect.left + overlayRect.width / 2;
|
|
9837
|
-
const overlayCenterY = overlayRect.top + overlayRect.height / 2;
|
|
9838
|
-
const translateX = originCenterX - overlayCenterX;
|
|
9839
|
-
const translateY = originCenterY - overlayCenterY;
|
|
9840
|
-
renderer.setCssProperties(containerEl, {
|
|
9841
|
-
'--origin-scale-x': `${scaleX}`,
|
|
9842
|
-
'--origin-scale-y': `${scaleY}`,
|
|
9843
|
-
'--origin-translate-x': `${translateX}px`,
|
|
9844
|
-
'--origin-translate-y': `${translateY}px`,
|
|
9832
|
+
renderer.setStyle(containerEl, {
|
|
9833
|
+
transformOrigin: `${origin.x - overlayRect.left}px ${origin.y - overlayRect.top}px`,
|
|
9845
9834
|
});
|
|
9846
9835
|
};
|
|
9847
9836
|
return {
|
|
@@ -9857,22 +9846,14 @@ const ANCHORED_DIALOG_STRATEGY_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
9857
9846
|
context.lifecycle.enter();
|
|
9858
9847
|
return;
|
|
9859
9848
|
}
|
|
9860
|
-
|
|
9861
|
-
renderer.setStyle(context.containerEl, { transformOrigin: 'center center' });
|
|
9849
|
+
applyOriginTransformOrigin(context, originData);
|
|
9862
9850
|
forceReflow(context.containerEl);
|
|
9863
9851
|
nextFrame(() => {
|
|
9864
9852
|
context.lifecycle.enter();
|
|
9865
9853
|
});
|
|
9866
9854
|
},
|
|
9867
9855
|
onSwitchedAwayFrom: (context) => {
|
|
9868
|
-
|
|
9869
|
-
renderer.setCssProperties(containerEl, {
|
|
9870
|
-
'--origin-scale-x': null,
|
|
9871
|
-
'--origin-scale-y': null,
|
|
9872
|
-
'--origin-translate-x': null,
|
|
9873
|
-
'--origin-translate-y': null,
|
|
9874
|
-
});
|
|
9875
|
-
renderer.setStyle(containerEl, { transformOrigin: null });
|
|
9856
|
+
renderer.setStyle(context.containerEl, { transformOrigin: null });
|
|
9876
9857
|
},
|
|
9877
9858
|
onBeforeLeave: (context) => {
|
|
9878
9859
|
if (!context.origin || !cfg.applyTransformOrigin) {
|
|
@@ -9884,7 +9865,7 @@ const ANCHORED_DIALOG_STRATEGY_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
9884
9865
|
context.lifecycle.leave();
|
|
9885
9866
|
return;
|
|
9886
9867
|
}
|
|
9887
|
-
|
|
9868
|
+
applyOriginTransformOrigin(context, originData);
|
|
9888
9869
|
context.lifecycle.leave();
|
|
9889
9870
|
},
|
|
9890
9871
|
};
|
|
@@ -9927,7 +9908,7 @@ const anchoredDialogOverlayStrategy = (options = {}) => {
|
|
|
9927
9908
|
};
|
|
9928
9909
|
|
|
9929
9910
|
/** Distance the pointer must travel along the dismiss axis before the overlay starts following it. */
|
|
9930
|
-
const COMMIT_THRESHOLD_PX$
|
|
9911
|
+
const COMMIT_THRESHOLD_PX$2 = 8;
|
|
9931
9912
|
/** Bounds for momentum-derived durations, so a crawl never stalls and a hard flick still animates. */
|
|
9932
9913
|
const MIN_MOMENTUM_DURATION_MS = 100;
|
|
9933
9914
|
const MAX_MOMENTUM_DURATION_MS = 350;
|
|
@@ -10190,7 +10171,7 @@ const enableDragToDismiss = (context) => {
|
|
|
10190
10171
|
// sitting at a snap point it drags the overlay in, but fully docked it is not this
|
|
10191
10172
|
// gesture's business and must stay available to whatever else wants the pointer.
|
|
10192
10173
|
const committedDistance = gestureStartOffset > 0 ? Math.abs(travelled) : travelled;
|
|
10193
|
-
if (committedDistance < COMMIT_THRESHOLD_PX$
|
|
10174
|
+
if (committedDistance < COMMIT_THRESHOLD_PX$2)
|
|
10194
10175
|
return;
|
|
10195
10176
|
// The threshold doubles as the window in which the browser may claim the gesture for a
|
|
10196
10177
|
// scroll: touch input starting on already-scrolled content is a scroll, not a drag.
|
|
@@ -38858,9 +38839,11 @@ class SelectDirective {
|
|
|
38858
38839
|
/** Whether the panel mirrors the anchor's width. Off for compact triggers (e.g. a country picker). */
|
|
38859
38840
|
this.mirrorPanelWidth = input(true, { ...(ngDevMode ? { debugName: "mirrorPanelWidth" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
38860
38841
|
/**
|
|
38861
|
-
* Fire-and-forget picker mode
|
|
38862
|
-
*
|
|
38863
|
-
* without the set-then-clear dance.
|
|
38842
|
+
* Fire-and-forget picker mode: committing an option emits `pickOption` without ever writing
|
|
38843
|
+
* `value`, so the field never displays a value of its own (no chips, no label, no clear) and can
|
|
38844
|
+
* feed an external list without the set-then-clear dance. Bind `value` to that list to check the
|
|
38845
|
+
* picked options in the panel. Single select closes on pick; multi keeps the panel open for
|
|
38846
|
+
* repeated adds.
|
|
38864
38847
|
*/
|
|
38865
38848
|
this.pickOnly = input(false, { ...(ngDevMode ? { debugName: "pickOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
38866
38849
|
/**
|
|
@@ -38876,9 +38859,9 @@ class SelectDirective {
|
|
|
38876
38859
|
/** The user picked the "Add new" row (`allowAddNew`). Emits the current search query for prefilling. */
|
|
38877
38860
|
this.addNew = output();
|
|
38878
38861
|
/**
|
|
38879
|
-
*
|
|
38880
|
-
* the only pick signal and `value` is never mutated;
|
|
38881
|
-
* value selection.
|
|
38862
|
+
* A single select - or a `pickOnly` multi select - committed an option, carrying the picked
|
|
38863
|
+
* value. In `pickOnly` mode this is the only pick signal and `value` is never mutated;
|
|
38864
|
+
* otherwise it fires alongside the normal value selection.
|
|
38882
38865
|
*/
|
|
38883
38866
|
this.pickOption = output();
|
|
38884
38867
|
/** The string in effect: this instance's `mixedLabel`, else `FORM_FIELD_LABELS`. */
|
|
@@ -38906,9 +38889,13 @@ class SelectDirective {
|
|
|
38906
38889
|
...(ngDevMode ? [{ debugName: "hasMoreItems" }] : /* istanbul ignore next */ []));
|
|
38907
38890
|
this.shouldDisplayError = computed(() => this.touched() && this.invalid(), /* @ts-ignore */
|
|
38908
38891
|
...(ngDevMode ? [{ debugName: "shouldDisplayError" }] : /* istanbul ignore next */ []));
|
|
38909
|
-
/**
|
|
38892
|
+
/**
|
|
38893
|
+
* The raw value normalized to the selection the control currently exposes. Mixed has no effective
|
|
38894
|
+
* selection, and neither has a `pickOnly` picker - its `value` marks the picked options in the
|
|
38895
|
+
* panel without ever becoming the field's own display.
|
|
38896
|
+
*/
|
|
38910
38897
|
this.effectiveValues = computed(() => {
|
|
38911
|
-
if (this.mixed()) {
|
|
38898
|
+
if (this.mixed() || this.pickOnly()) {
|
|
38912
38899
|
return [];
|
|
38913
38900
|
}
|
|
38914
38901
|
const value = this.value();
|
|
@@ -39383,6 +39370,11 @@ class SelectDirective {
|
|
|
39383
39370
|
return;
|
|
39384
39371
|
}
|
|
39385
39372
|
if (this.multiple()) {
|
|
39373
|
+
if (this.pickOnly()) {
|
|
39374
|
+
this.pickOption.emit(item.value());
|
|
39375
|
+
this.registeredSearch()?.clear();
|
|
39376
|
+
return;
|
|
39377
|
+
}
|
|
39386
39378
|
// toggle by value arithmetic instead of the registry (`selection.select` recomputes the
|
|
39387
39379
|
// array from registered options only, silently dropping values without a live option -
|
|
39388
39380
|
// custom values, or options an external filter removed)
|
|
@@ -41797,6 +41789,7 @@ class RatingComponent {
|
|
|
41797
41789
|
constructor() {
|
|
41798
41790
|
this.support = injectFormSupport();
|
|
41799
41791
|
this.rating = inject(RatingDirective);
|
|
41792
|
+
this.destroyRef = inject(DestroyRef);
|
|
41800
41793
|
this.baseIcons = viewChildren('baseIcon', /* @ts-ignore */
|
|
41801
41794
|
...(ngDevMode ? [{ debugName: "baseIcons" }] : /* istanbul ignore next */ []));
|
|
41802
41795
|
this.errorContentRef = viewChild('errorContent', /* @ts-ignore */
|
|
@@ -41833,41 +41826,26 @@ class RatingComponent {
|
|
|
41833
41826
|
// without its trailing click (drag off-target, cancelled synthetic click) - otherwise the
|
|
41834
41827
|
// next legitimate click is swallowed once
|
|
41835
41828
|
this.pointerCommitted = false;
|
|
41836
|
-
if (!this.rating.interactive()) {
|
|
41829
|
+
if (!this.rating.interactive() || event.button !== 0 || this.dragging) {
|
|
41837
41830
|
return;
|
|
41838
41831
|
}
|
|
41832
|
+
const surface = event.currentTarget;
|
|
41833
|
+
const pressX = event.clientX;
|
|
41834
|
+
const touch = event.pointerType === 'touch';
|
|
41839
41835
|
this.dragging = true;
|
|
41840
|
-
|
|
41841
|
-
|
|
41842
|
-
|
|
41843
|
-
|
|
41844
|
-
|
|
41845
|
-
|
|
41846
|
-
this.rating.setHoverValue(this.valueFromPointer(event));
|
|
41836
|
+
this.rating.setHoverValue(this.valueFromPosition(pressX));
|
|
41837
|
+
// every pointer move counts: the preview tracks the finger from the first pixel, so there is
|
|
41838
|
+
// no threshold below which the press is still just a click
|
|
41839
|
+
dragGestureFrom(event, surface, { commitThreshold: 0 })
|
|
41840
|
+
.pipe(tap((gesture) => this.applyGesture(gesture, { pressX, touch })), takeUntilDestroyed(this.destroyRef))
|
|
41841
|
+
.subscribe();
|
|
41847
41842
|
}
|
|
41843
|
+
/** Hover preview only - a press draws from its own gesture, and a resting finger is not a hover. */
|
|
41848
41844
|
handlePointerMove(event) {
|
|
41849
|
-
|
|
41850
|
-
if (!this.dragging && event.pointerType === 'touch') {
|
|
41845
|
+
if (this.dragging || event.pointerType === 'touch') {
|
|
41851
41846
|
return;
|
|
41852
41847
|
}
|
|
41853
|
-
this.rating.setHoverValue(this.
|
|
41854
|
-
}
|
|
41855
|
-
handlePointerUp(event) {
|
|
41856
|
-
if (!this.dragging) {
|
|
41857
|
-
return;
|
|
41858
|
-
}
|
|
41859
|
-
this.dragging = false;
|
|
41860
|
-
this.pointerCommitted = true;
|
|
41861
|
-
this.rating.commitPointer(this.valueFromPointer(event));
|
|
41862
|
-
if (event.pointerType === 'touch') {
|
|
41863
|
-
this.rating.clearHover();
|
|
41864
|
-
}
|
|
41865
|
-
}
|
|
41866
|
-
handlePointerCancel(event) {
|
|
41867
|
-
void event;
|
|
41868
|
-
this.dragging = false;
|
|
41869
|
-
this.pointerCommitted = false;
|
|
41870
|
-
this.rating.clearHover();
|
|
41848
|
+
this.rating.setHoverValue(this.valueFromPosition(event.clientX));
|
|
41871
41849
|
}
|
|
41872
41850
|
/** Fallback for synthetic clicks (tests, assistive tech) - real pointer flows commit on pointerup. */
|
|
41873
41851
|
handleIconClick(index, event) {
|
|
@@ -41882,25 +41860,48 @@ class RatingComponent {
|
|
|
41882
41860
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
41883
41861
|
this.rating.commitPointer(event.clientX - rect.left < rect.width / 2 ? index - 0.5 : index);
|
|
41884
41862
|
}
|
|
41863
|
+
applyGesture(gesture, press) {
|
|
41864
|
+
switch (gesture.type) {
|
|
41865
|
+
case 'start':
|
|
41866
|
+
return;
|
|
41867
|
+
case 'move':
|
|
41868
|
+
this.rating.setHoverValue(this.valueFromPosition(gesture.data.clientX));
|
|
41869
|
+
return;
|
|
41870
|
+
case 'end':
|
|
41871
|
+
case 'tapped':
|
|
41872
|
+
this.dragging = false;
|
|
41873
|
+
this.pointerCommitted = true;
|
|
41874
|
+
this.rating.commitPointer(this.valueFromPosition(gesture.type === 'end' ? gesture.data.clientX : press.pressX));
|
|
41875
|
+
if (press.touch) {
|
|
41876
|
+
this.rating.clearHover();
|
|
41877
|
+
}
|
|
41878
|
+
return;
|
|
41879
|
+
case 'cancelled':
|
|
41880
|
+
// the browser took the gesture away - the user never picked a rating, so nothing commits
|
|
41881
|
+
this.dragging = false;
|
|
41882
|
+
this.pointerCommitted = false;
|
|
41883
|
+
this.rating.clearHover();
|
|
41884
|
+
return;
|
|
41885
|
+
}
|
|
41886
|
+
}
|
|
41885
41887
|
// gap-immune: resolve the value from the actual icon rects under the pointer
|
|
41886
|
-
|
|
41888
|
+
valueFromPosition(clientX) {
|
|
41887
41889
|
const icons = this.baseIcons().map((ref) => ref.nativeElement);
|
|
41888
41890
|
let value = this.rating.step();
|
|
41889
41891
|
icons.forEach((icon, position) => {
|
|
41890
41892
|
const rect = icon.getBoundingClientRect();
|
|
41891
41893
|
const index = position + 1;
|
|
41892
|
-
if (
|
|
41894
|
+
if (clientX >= rect.right) {
|
|
41893
41895
|
value = index;
|
|
41894
41896
|
}
|
|
41895
|
-
else if (
|
|
41896
|
-
value =
|
|
41897
|
-
this.rating.allowHalf() && event.clientX < rect.left + rect.width / 2 ? Math.max(0.5, index - 0.5) : index;
|
|
41897
|
+
else if (clientX >= rect.left) {
|
|
41898
|
+
value = this.rating.allowHalf() && clientX < rect.left + rect.width / 2 ? Math.max(0.5, index - 0.5) : index;
|
|
41898
41899
|
}
|
|
41899
41900
|
});
|
|
41900
41901
|
return value;
|
|
41901
41902
|
}
|
|
41902
41903
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: RatingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
41903
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: RatingComponent, isStandalone: true, selector: "et-rating", host: { properties: { "attr.data-can-animate": "canAnimate.state() || null", "attr.data-error": "support.displaysError() || null" }, classAttribute: "et-rating" }, providers: [provideFormSupport(), provideIcons(STAR_ICON)], viewQueries: [{ propertyName: "baseIcons", predicate: ["baseIcon"], descendants: true, isSignal: true }, { propertyName: "errorContentRef", first: true, predicate: ["errorContent"], descendants: true, isSignal: true }, { propertyName: "hintContentRef", first: true, predicate: ["hintContent"], descendants: true, isSignal: true }, { propertyName: "errorAnimatableRef", first: true, predicate: ["errorAnimatable"], descendants: true, isSignal: true }, { propertyName: "hintAnimatableRef", first: true, predicate: ["hintAnimatable"], descendants: true, isSignal: true }], hostDirectives: [{ directive: FormFieldDirective }, { directive: RatingDirective, inputs: ["value", "value", "mixed", "mixed", "mixedLabel", "mixedLabel", "touched", "touched", "disabled", "disabled", "readonly", "readonly", "invalid", "invalid", "errors", "errors", "required", "required", "name", "name", "max", "max", "allowHalf", "allowHalf"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange"] }, { directive: i1.ProvideColorDirective, inputs: ["etProvideColor", "color"] }], ngImport: i0, template: "<ng-content />\n\n<!-- pointer-only by design: keyboard interaction lives on the slider host (APG slider\n pattern) and the icons are presentational for assistive tech -->\n<div\n [style.--_et-rating-fill-icons]=\"fillIcons()\"\n [style.--_et-rating-fill-gaps]=\"fillGaps()\"\n (
|
|
41904
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: RatingComponent, isStandalone: true, selector: "et-rating", host: { properties: { "attr.data-can-animate": "canAnimate.state() || null", "attr.data-error": "support.displaysError() || null" }, classAttribute: "et-rating" }, providers: [provideFormSupport(), provideIcons(STAR_ICON)], viewQueries: [{ propertyName: "baseIcons", predicate: ["baseIcon"], descendants: true, isSignal: true }, { propertyName: "errorContentRef", first: true, predicate: ["errorContent"], descendants: true, isSignal: true }, { propertyName: "hintContentRef", first: true, predicate: ["hintContent"], descendants: true, isSignal: true }, { propertyName: "errorAnimatableRef", first: true, predicate: ["errorAnimatable"], descendants: true, isSignal: true }, { propertyName: "hintAnimatableRef", first: true, predicate: ["hintAnimatable"], descendants: true, isSignal: true }], hostDirectives: [{ directive: FormFieldDirective }, { directive: RatingDirective, inputs: ["value", "value", "mixed", "mixed", "mixedLabel", "mixedLabel", "touched", "touched", "disabled", "disabled", "readonly", "readonly", "invalid", "invalid", "errors", "errors", "required", "required", "name", "name", "max", "max", "allowHalf", "allowHalf"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange"] }, { directive: i1.ProvideColorDirective, inputs: ["etProvideColor", "color"] }], ngImport: i0, template: "<ng-content />\n\n<!-- pointer-only by design: keyboard interaction lives on the slider host (APG slider\n pattern) and the icons are presentational for assistive tech -->\n<div\n [style.--_et-rating-fill-icons]=\"fillIcons()\"\n [style.--_et-rating-fill-gaps]=\"fillGaps()\"\n (pointerdown)=\"handlePointerDown($event)\"\n (pointermove)=\"handlePointerMove($event)\"\n class=\"et-rating-icons\"\n>\n @if (rating.registeredIconTemplate(); as iconTemplate) {\n <!-- custom icons render per-step with their state \u2014 the continuous sweep only applies\n to the default two-layer star rendering -->\n <div class=\"et-rating-row\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span\n #baseIcon\n [attr.data-state]=\"rating.iconState(index)\"\n (click)=\"handleIconClick(index, $event)\"\n class=\"et-rating-icon\"\n >\n <ng-template [ngTemplateOutlet]=\"iconTemplate.templateRef\" [ngTemplateOutletContext]=\"iconContext(index)\" />\n </span>\n }\n </div>\n } @else {\n <div class=\"et-rating-row\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span #baseIcon (click)=\"handleIconClick(index, $event)\" class=\"et-rating-icon\">\n <i class=\"et-rating-icon-base\" etIcon=\"et-star\"></i>\n </span>\n }\n </div>\n\n <!-- overlay clipped to one continuous width \u2014 the fill animates as a single motion -->\n <div class=\"et-rating-row et-rating-row--fill\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span class=\"et-rating-icon\">\n <i class=\"et-rating-icon-fill\" etIcon=\"et-star\"></i>\n </span>\n }\n </div>\n }\n</div>\n\n@if (support.shouldRenderSupport()) {\n <div [style.block-size.px]=\"support.supportHeight()\" class=\"et-rating-support\">\n <div class=\"et-rating-support-stack\">\n @if (support.shouldRenderError()) {\n <div\n #errorContent\n #errorAnimatable=\"etAnimatable\"\n [attr.aria-atomic]=\"support.errorActive() ? 'true' : null\"\n [attr.aria-hidden]=\"!support.errorActive() ? 'true' : null\"\n [attr.aria-live]=\"support.errorActive() ? 'polite' : null\"\n [attr.data-active]=\"support.errorActive() || null\"\n [etProvideColor]=\"support.errorColorTheme\"\n class=\"et-rating-support-content et-rating-errors\"\n etAnimatable\n >\n @for (error of support.visibleErrors(); track $index) {\n <et-form-error [error]=\"error\" />\n }\n </div>\n }\n\n @if (support.shouldRenderHint()) {\n <div\n #hintContent\n #hintAnimatable=\"etAnimatable\"\n [attr.aria-hidden]=\"!support.hintActive() ? 'true' : null\"\n [attr.data-active]=\"support.hintActive() || null\"\n class=\"et-rating-support-content et-rating-hint\"\n etAnimatable\n >\n <ng-content select=\"et-hint\" />\n </div>\n }\n </div>\n </div>\n}\n", styles: ["@layer components{@property --et-rating-icon-size{syntax: \"<length>\"; inherits: true; initial-value: 24px;}@property --et-rating-gap{syntax: \"<length>\"; inherits: true; initial-value: 4px;}@property --et-rating-label-font-size{syntax: \"<length>\"; inherits: true; initial-value: 13px;}@property --et-rating-support-duration{syntax: \"<time>\"; inherits: true; initial-value: .18s;}@property --et-rating-support-offset{syntax: \"<length>\"; inherits: true; initial-value: 4px;}@property --et-rating-error-font-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-rating-hint-font-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}et-rating{display:inline-flex;flex-direction:column;gap:6px;color:var(--et-surface-color-solid, currentColor);outline:none}et-rating>et-label{font-size:var(--et-rating-label-font-size);font-weight:500;line-height:1.2;letter-spacing:-.01em;color:var(--et-surface-color-muted-solid, currentColor);-webkit-user-select:none;user-select:none}et-rating:focus-visible .et-rating-icons{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:2px;border-radius:4px}et-rating .et-rating-icons{position:relative;display:grid;inline-size:fit-content;padding-block:max(0px,calc((44px - var(--et-rating-icon-size)) / 2));cursor:pointer;touch-action:pan-y}et-rating .et-rating-row{display:flex;align-items:center;gap:var(--et-rating-gap);grid-area:1 / 1}et-rating .et-rating-row--fill{--_et-rating-fill-width: calc( var(--_et-rating-fill-icons, 0) * var(--et-rating-icon-size) + var(--_et-rating-fill-gaps, 0) * var(--et-rating-gap) );pointer-events:none;clip-path:inset(0 calc(100% - var(--_et-rating-fill-width)) 0 0)}:is(et-rating[data-disabled],et-rating[data-readonly]) .et-rating-icons{cursor:default}et-rating[data-disabled]{opacity:.4}et-rating .et-rating-icon{position:relative;display:flex;inline-size:var(--et-rating-icon-size);block-size:var(--et-rating-icon-size);-webkit-user-select:none;user-select:none}et-rating .et-rating-icon .et-icon{inline-size:100%;block-size:100%}et-rating .et-rating-icon-base{color:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 32%,transparent)}et-rating .et-rating-icon-fill{color:var(--et-theme-color-primary-solid, currentColor)}et-rating[data-mixed] .et-rating-icons:after{content:\"\";position:absolute;inset-inline:0;inset-block-end:-6px;border-block-end:1px dashed var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-icon[data-state]{color:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 32%,transparent)}et-rating .et-rating-icon[data-state][data-state=full],et-rating .et-rating-icon[data-state][data-state=half]{color:var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-support{overflow:clip;block-size:0}et-rating .et-rating-support-stack{position:relative;display:grid}et-rating .et-rating-support-content{grid-area:1 / 1;min-inline-size:0;opacity:0;transform:translateY(0)}et-rating .et-rating-support-content[data-active]{opacity:1;transform:translateY(0)}et-rating .et-rating-errors{display:flex;flex-direction:column;gap:2px;padding-block-start:4px;font-size:var(--et-rating-error-font-size);color:var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-hint{padding-block-start:4px;font-size:var(--et-rating-hint-font-size);color:var(--et-surface-color-muted-solid, currentColor)}et-rating .et-rating-hint:empty{display:none}et-rating[data-can-animate] .et-rating-support{transition:block-size var(--et-rating-support-duration) ease}et-rating[data-can-animate] .et-rating-support-content{transition:opacity var(--et-rating-support-duration) ease,transform var(--et-rating-support-duration) ease}@starting-style{et-rating[data-can-animate] .et-rating-support-content[data-active]{opacity:0;transform:translateY(calc(var(--et-rating-support-offset) * -1))}}et-rating[data-can-animate] .et-rating-row--fill{transition:clip-path .16s ease}@media(prefers-reduced-motion:reduce){et-rating{--et-rating-support-duration: 1ms;--et-rating-support-offset: 0px}}}\n"], dependencies: [{ kind: "directive", type: AnimatableDirective, selector: "[etAnimatable]", exportAs: ["etAnimatable"] }, { kind: "component", type: FormErrorComponent, selector: "et-form-error", inputs: ["error"] }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
41904
41905
|
}
|
|
41905
41906
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: RatingComponent, decorators: [{
|
|
41906
41907
|
type: Component,
|
|
@@ -41929,7 +41930,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
41929
41930
|
class: 'et-rating',
|
|
41930
41931
|
'[attr.data-can-animate]': 'canAnimate.state() || null',
|
|
41931
41932
|
'[attr.data-error]': 'support.displaysError() || null',
|
|
41932
|
-
}, template: "<ng-content />\n\n<!-- pointer-only by design: keyboard interaction lives on the slider host (APG slider\n pattern) and the icons are presentational for assistive tech -->\n<div\n [style.--_et-rating-fill-icons]=\"fillIcons()\"\n [style.--_et-rating-fill-gaps]=\"fillGaps()\"\n (
|
|
41933
|
+
}, template: "<ng-content />\n\n<!-- pointer-only by design: keyboard interaction lives on the slider host (APG slider\n pattern) and the icons are presentational for assistive tech -->\n<div\n [style.--_et-rating-fill-icons]=\"fillIcons()\"\n [style.--_et-rating-fill-gaps]=\"fillGaps()\"\n (pointerdown)=\"handlePointerDown($event)\"\n (pointermove)=\"handlePointerMove($event)\"\n class=\"et-rating-icons\"\n>\n @if (rating.registeredIconTemplate(); as iconTemplate) {\n <!-- custom icons render per-step with their state \u2014 the continuous sweep only applies\n to the default two-layer star rendering -->\n <div class=\"et-rating-row\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span\n #baseIcon\n [attr.data-state]=\"rating.iconState(index)\"\n (click)=\"handleIconClick(index, $event)\"\n class=\"et-rating-icon\"\n >\n <ng-template [ngTemplateOutlet]=\"iconTemplate.templateRef\" [ngTemplateOutletContext]=\"iconContext(index)\" />\n </span>\n }\n </div>\n } @else {\n <div class=\"et-rating-row\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span #baseIcon (click)=\"handleIconClick(index, $event)\" class=\"et-rating-icon\">\n <i class=\"et-rating-icon-base\" etIcon=\"et-star\"></i>\n </span>\n }\n </div>\n\n <!-- overlay clipped to one continuous width \u2014 the fill animates as a single motion -->\n <div class=\"et-rating-row et-rating-row--fill\" aria-hidden=\"true\">\n @for (index of iconIndexes(); track index) {\n <span class=\"et-rating-icon\">\n <i class=\"et-rating-icon-fill\" etIcon=\"et-star\"></i>\n </span>\n }\n </div>\n }\n</div>\n\n@if (support.shouldRenderSupport()) {\n <div [style.block-size.px]=\"support.supportHeight()\" class=\"et-rating-support\">\n <div class=\"et-rating-support-stack\">\n @if (support.shouldRenderError()) {\n <div\n #errorContent\n #errorAnimatable=\"etAnimatable\"\n [attr.aria-atomic]=\"support.errorActive() ? 'true' : null\"\n [attr.aria-hidden]=\"!support.errorActive() ? 'true' : null\"\n [attr.aria-live]=\"support.errorActive() ? 'polite' : null\"\n [attr.data-active]=\"support.errorActive() || null\"\n [etProvideColor]=\"support.errorColorTheme\"\n class=\"et-rating-support-content et-rating-errors\"\n etAnimatable\n >\n @for (error of support.visibleErrors(); track $index) {\n <et-form-error [error]=\"error\" />\n }\n </div>\n }\n\n @if (support.shouldRenderHint()) {\n <div\n #hintContent\n #hintAnimatable=\"etAnimatable\"\n [attr.aria-hidden]=\"!support.hintActive() ? 'true' : null\"\n [attr.data-active]=\"support.hintActive() || null\"\n class=\"et-rating-support-content et-rating-hint\"\n etAnimatable\n >\n <ng-content select=\"et-hint\" />\n </div>\n }\n </div>\n </div>\n}\n", styles: ["@layer components{@property --et-rating-icon-size{syntax: \"<length>\"; inherits: true; initial-value: 24px;}@property --et-rating-gap{syntax: \"<length>\"; inherits: true; initial-value: 4px;}@property --et-rating-label-font-size{syntax: \"<length>\"; inherits: true; initial-value: 13px;}@property --et-rating-support-duration{syntax: \"<time>\"; inherits: true; initial-value: .18s;}@property --et-rating-support-offset{syntax: \"<length>\"; inherits: true; initial-value: 4px;}@property --et-rating-error-font-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-rating-hint-font-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}et-rating{display:inline-flex;flex-direction:column;gap:6px;color:var(--et-surface-color-solid, currentColor);outline:none}et-rating>et-label{font-size:var(--et-rating-label-font-size);font-weight:500;line-height:1.2;letter-spacing:-.01em;color:var(--et-surface-color-muted-solid, currentColor);-webkit-user-select:none;user-select:none}et-rating:focus-visible .et-rating-icons{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:2px;border-radius:4px}et-rating .et-rating-icons{position:relative;display:grid;inline-size:fit-content;padding-block:max(0px,calc((44px - var(--et-rating-icon-size)) / 2));cursor:pointer;touch-action:pan-y}et-rating .et-rating-row{display:flex;align-items:center;gap:var(--et-rating-gap);grid-area:1 / 1}et-rating .et-rating-row--fill{--_et-rating-fill-width: calc( var(--_et-rating-fill-icons, 0) * var(--et-rating-icon-size) + var(--_et-rating-fill-gaps, 0) * var(--et-rating-gap) );pointer-events:none;clip-path:inset(0 calc(100% - var(--_et-rating-fill-width)) 0 0)}:is(et-rating[data-disabled],et-rating[data-readonly]) .et-rating-icons{cursor:default}et-rating[data-disabled]{opacity:.4}et-rating .et-rating-icon{position:relative;display:flex;inline-size:var(--et-rating-icon-size);block-size:var(--et-rating-icon-size);-webkit-user-select:none;user-select:none}et-rating .et-rating-icon .et-icon{inline-size:100%;block-size:100%}et-rating .et-rating-icon-base{color:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 32%,transparent)}et-rating .et-rating-icon-fill{color:var(--et-theme-color-primary-solid, currentColor)}et-rating[data-mixed] .et-rating-icons:after{content:\"\";position:absolute;inset-inline:0;inset-block-end:-6px;border-block-end:1px dashed var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-icon[data-state]{color:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 32%,transparent)}et-rating .et-rating-icon[data-state][data-state=full],et-rating .et-rating-icon[data-state][data-state=half]{color:var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-support{overflow:clip;block-size:0}et-rating .et-rating-support-stack{position:relative;display:grid}et-rating .et-rating-support-content{grid-area:1 / 1;min-inline-size:0;opacity:0;transform:translateY(0)}et-rating .et-rating-support-content[data-active]{opacity:1;transform:translateY(0)}et-rating .et-rating-errors{display:flex;flex-direction:column;gap:2px;padding-block-start:4px;font-size:var(--et-rating-error-font-size);color:var(--et-theme-color-primary-solid, currentColor)}et-rating .et-rating-hint{padding-block-start:4px;font-size:var(--et-rating-hint-font-size);color:var(--et-surface-color-muted-solid, currentColor)}et-rating .et-rating-hint:empty{display:none}et-rating[data-can-animate] .et-rating-support{transition:block-size var(--et-rating-support-duration) ease}et-rating[data-can-animate] .et-rating-support-content{transition:opacity var(--et-rating-support-duration) ease,transform var(--et-rating-support-duration) ease}@starting-style{et-rating[data-can-animate] .et-rating-support-content[data-active]{opacity:0;transform:translateY(calc(var(--et-rating-support-offset) * -1))}}et-rating[data-can-animate] .et-rating-row--fill{transition:clip-path .16s ease}@media(prefers-reduced-motion:reduce){et-rating{--et-rating-support-duration: 1ms;--et-rating-support-offset: 0px}}}\n"] }]
|
|
41933
41934
|
}], ctorParameters: () => [], propDecorators: { baseIcons: [{ type: i0.ViewChildren, args: ['baseIcon', { isSignal: true }] }], errorContentRef: [{ type: i0.ViewChild, args: ['errorContent', { isSignal: true }] }], hintContentRef: [{ type: i0.ViewChild, args: ['hintContent', { isSignal: true }] }], errorAnimatableRef: [{ type: i0.ViewChild, args: ['errorAnimatable', { isSignal: true }] }], hintAnimatableRef: [{ type: i0.ViewChild, args: ['hintAnimatable', { isSignal: true }] }] } });
|
|
41934
41935
|
|
|
41935
41936
|
const RATING_IMPORTS = [RatingComponent, RatingDirective, RatingIconDirective];
|
|
@@ -42775,6 +42776,7 @@ class SliderTrackDirective {
|
|
|
42775
42776
|
constructor() {
|
|
42776
42777
|
this.slider = inject(SLIDER_TOKEN, { optional: true });
|
|
42777
42778
|
this.elementRef = inject(ElementRef);
|
|
42779
|
+
this.destroyRef = inject(DestroyRef);
|
|
42778
42780
|
this.vertical = computed(() => this.slider?.orientation() === 'vertical', /* @ts-ignore */
|
|
42779
42781
|
...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
|
|
42780
42782
|
if (ngDevMode) {
|
|
@@ -42787,53 +42789,57 @@ class SliderTrackDirective {
|
|
|
42787
42789
|
}
|
|
42788
42790
|
handlePointerDown(event) {
|
|
42789
42791
|
const slider = this.slider;
|
|
42790
|
-
if (!slider || !slider.interactive() || event.button !== 0) {
|
|
42792
|
+
if (!slider || !slider.interactive() || event.button !== 0 || slider.draggingThumbIndex() !== null) {
|
|
42791
42793
|
return;
|
|
42792
42794
|
}
|
|
42793
42795
|
// a tap that starts on a tick commits that tick exactly, not the value under the pointer
|
|
42794
|
-
const
|
|
42795
|
-
const index = nearestThumbIndex(
|
|
42796
|
+
const pressValue = markValueUnderPointer(event) ?? this.valueFromPosition(event.clientX, event.clientY);
|
|
42797
|
+
const index = nearestThumbIndex(pressValue, slider.thumbValues());
|
|
42796
42798
|
slider.draggingThumbIndex.set(index);
|
|
42797
|
-
slider.commitThumbValue(index,
|
|
42799
|
+
slider.commitThumbValue(index, pressValue);
|
|
42798
42800
|
slider.thumbs()[index]?.focus();
|
|
42799
|
-
try {
|
|
42800
|
-
this.elementRef.nativeElement.setPointerCapture(event.pointerId);
|
|
42801
|
-
}
|
|
42802
|
-
catch {
|
|
42803
|
-
// pointer capture is unavailable in some test environments - dragging still works
|
|
42804
|
-
}
|
|
42805
42801
|
// keep the interaction from selecting text or starting a native drag
|
|
42806
42802
|
event.preventDefault();
|
|
42803
|
+
// every pointer move counts: a slider follows the pointer from the first pixel, so there is
|
|
42804
|
+
// no threshold below which the press is still just a click
|
|
42805
|
+
dragGestureFrom(event, this.elementRef.nativeElement, { commitThreshold: 0 })
|
|
42806
|
+
.pipe(tap((gesture) => this.applyGesture(gesture, { index, pressValue })), takeUntilDestroyed(this.destroyRef))
|
|
42807
|
+
.subscribe();
|
|
42807
42808
|
}
|
|
42808
|
-
|
|
42809
|
+
applyGesture(gesture, press) {
|
|
42809
42810
|
const slider = this.slider;
|
|
42810
|
-
|
|
42811
|
-
if (!slider || draggingIndex === null) {
|
|
42811
|
+
if (!slider) {
|
|
42812
42812
|
return;
|
|
42813
42813
|
}
|
|
42814
|
-
|
|
42815
|
-
|
|
42816
|
-
|
|
42817
|
-
|
|
42818
|
-
|
|
42819
|
-
|
|
42820
|
-
|
|
42814
|
+
switch (gesture.type) {
|
|
42815
|
+
case 'start':
|
|
42816
|
+
return;
|
|
42817
|
+
case 'move':
|
|
42818
|
+
slider.commitThumbValue(press.index, this.valueFromPosition(gesture.data.clientX, gesture.data.clientY));
|
|
42819
|
+
return;
|
|
42820
|
+
case 'end':
|
|
42821
|
+
slider.commitThumbValue(press.index, this.valueFromPosition(gesture.data.clientX, gesture.data.clientY));
|
|
42822
|
+
slider.draggingThumbIndex.set(null);
|
|
42823
|
+
return;
|
|
42824
|
+
case 'cancelled':
|
|
42825
|
+
// the browser took the gesture away - the last position the user chose is the one they pressed
|
|
42826
|
+
slider.commitThumbValue(press.index, press.pressValue);
|
|
42827
|
+
slider.draggingThumbIndex.set(null);
|
|
42828
|
+
return;
|
|
42829
|
+
case 'tapped':
|
|
42830
|
+
slider.draggingThumbIndex.set(null);
|
|
42831
|
+
return;
|
|
42821
42832
|
}
|
|
42822
|
-
slider.commitThumbValue(draggingIndex, this.valueFromEvent(event));
|
|
42823
|
-
slider.draggingThumbIndex.set(null);
|
|
42824
|
-
}
|
|
42825
|
-
handlePointerCancel() {
|
|
42826
|
-
this.slider?.draggingThumbIndex.set(null);
|
|
42827
42833
|
}
|
|
42828
|
-
|
|
42834
|
+
valueFromPosition(clientX, clientY) {
|
|
42829
42835
|
const slider = this.slider;
|
|
42830
42836
|
if (!slider) {
|
|
42831
42837
|
return 0;
|
|
42832
42838
|
}
|
|
42833
42839
|
const element = this.elementRef.nativeElement;
|
|
42834
42840
|
return valueFromPointerPosition({
|
|
42835
|
-
clientX
|
|
42836
|
-
clientY
|
|
42841
|
+
clientX,
|
|
42842
|
+
clientY,
|
|
42837
42843
|
trackRect: element.getBoundingClientRect(),
|
|
42838
42844
|
rtl: getComputedStyle(element).direction === 'rtl',
|
|
42839
42845
|
orientation: slider.orientation(),
|
|
@@ -42841,7 +42847,7 @@ class SliderTrackDirective {
|
|
|
42841
42847
|
});
|
|
42842
42848
|
}
|
|
42843
42849
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SliderTrackDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
42844
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: SliderTrackDirective, isStandalone: true, selector: "[etSliderTrack]", host: { listeners: { "pointerdown": "handlePointerDown($event)"
|
|
42850
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: SliderTrackDirective, isStandalone: true, selector: "[etSliderTrack]", host: { listeners: { "pointerdown": "handlePointerDown($event)" }, properties: { "style.touch-action": "vertical() ? \"pan-x\" : \"pan-y\"" } }, exportAs: ["etSliderTrack"], ngImport: i0 }); }
|
|
42845
42851
|
}
|
|
42846
42852
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SliderTrackDirective, decorators: [{
|
|
42847
42853
|
type: Directive,
|
|
@@ -42852,9 +42858,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
42852
42858
|
// drags along the slider axis adjust it, page scrolling on the other axis stays native
|
|
42853
42859
|
'[style.touch-action]': 'vertical() ? "pan-x" : "pan-y"',
|
|
42854
42860
|
'(pointerdown)': 'handlePointerDown($event)',
|
|
42855
|
-
'(pointermove)': 'handlePointerMove($event)',
|
|
42856
|
-
'(pointerup)': 'handlePointerUp($event)',
|
|
42857
|
-
'(pointercancel)': 'handlePointerCancel()',
|
|
42858
42861
|
},
|
|
42859
42862
|
}]
|
|
42860
42863
|
}], ctorParameters: () => [] });
|
|
@@ -44644,6 +44647,16 @@ class GridDirective {
|
|
|
44644
44647
|
}
|
|
44645
44648
|
this.layoutOverrides.set(restored);
|
|
44646
44649
|
}
|
|
44650
|
+
return;
|
|
44651
|
+
}
|
|
44652
|
+
// Same items in the same places, but the host refreshed their `data` - a re-fetch landing
|
|
44653
|
+
// new widget contents, say. Copy `data` alone: an existing config's `layout` holds what
|
|
44654
|
+
// `moveItem` last wrote, which is ahead of the host's snapshot, so setting `initial`
|
|
44655
|
+
// wholesale here would revert the moves.
|
|
44656
|
+
const changedData = initial.filter((incoming) => currentById.get(incoming.id)?.data !== incoming.data);
|
|
44657
|
+
if (changedData.length > 0) {
|
|
44658
|
+
const dataById = new Map(changedData.map((item) => [item.id, item.data]));
|
|
44659
|
+
this.itemConfigs.update((items) => items.map((item) => (dataById.has(item.id) ? { ...item, data: dataById.get(item.id) } : item)));
|
|
44647
44660
|
}
|
|
44648
44661
|
return;
|
|
44649
44662
|
}
|
|
@@ -47451,7 +47464,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
47451
47464
|
}], ctorParameters: () => [], propDecorators: { ref: [{ type: i0.Input, args: [{ isSignal: true, alias: "etNotificationItem", required: true }] }] } });
|
|
47452
47465
|
|
|
47453
47466
|
/** Distance the pointer must travel along the swipe axis before the notification starts following it. */
|
|
47454
|
-
const COMMIT_THRESHOLD_PX = 8;
|
|
47467
|
+
const COMMIT_THRESHOLD_PX$1 = 8;
|
|
47455
47468
|
/** Fraction of the notification's width a slow drag must cover to count as a dismissal. */
|
|
47456
47469
|
const DISMISS_DISTANCE_RATIO = 0.3;
|
|
47457
47470
|
/** Floor for that distance, so a narrow notification still needs a deliberate drag. */
|
|
@@ -47570,7 +47583,7 @@ class NotificationSwipeToDismissDirective {
|
|
|
47570
47583
|
return;
|
|
47571
47584
|
}
|
|
47572
47585
|
const sign = this.allowedSign ?? (movementX >= 0 ? 1 : -1);
|
|
47573
|
-
if (movementX * sign < COMMIT_THRESHOLD_PX)
|
|
47586
|
+
if (movementX * sign < COMMIT_THRESHOLD_PX$1)
|
|
47574
47587
|
return;
|
|
47575
47588
|
this.sign = sign;
|
|
47576
47589
|
this.isCommitted = true;
|
|
@@ -48794,6 +48807,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
48794
48807
|
|
|
48795
48808
|
const PROGRESS_STEPS_IMPORTS = [ProgressStepsComponent, ProgressStepComponent];
|
|
48796
48809
|
|
|
48810
|
+
/** Duck-typed rather than `instanceof HttpHeaders`, so a second copy of `@angular/common/http` still reads. */
|
|
48811
|
+
const isHeadersValue = (value) => !!value &&
|
|
48812
|
+
typeof value === 'object' &&
|
|
48813
|
+
'keys' in value &&
|
|
48814
|
+
typeof value.keys === 'function' &&
|
|
48815
|
+
'getAll' in value &&
|
|
48816
|
+
typeof value.getAll === 'function' &&
|
|
48817
|
+
'lazyInit' in value;
|
|
48818
|
+
/**
|
|
48819
|
+
* How to render `value` if it is one of the built-ins the explorer knows, or `null` for anything it
|
|
48820
|
+
* should keep treating as a plain object or array.
|
|
48821
|
+
*/
|
|
48822
|
+
const exoticOf = (value) => {
|
|
48823
|
+
// A header provider is the case in practice; `String(fn)` would dump its whole source into the row.
|
|
48824
|
+
if (typeof value === 'function')
|
|
48825
|
+
return { typeName: 'fn', display: value.name || 'anonymous' };
|
|
48826
|
+
if (!value || typeof value !== 'object')
|
|
48827
|
+
return null;
|
|
48828
|
+
if (value instanceof Date) {
|
|
48829
|
+
return { typeName: 'Date', display: Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString() };
|
|
48830
|
+
}
|
|
48831
|
+
if (typeof File !== 'undefined' && value instanceof File) {
|
|
48832
|
+
return {
|
|
48833
|
+
typeName: 'File',
|
|
48834
|
+
entries: [
|
|
48835
|
+
{ k: 'name', v: value.name },
|
|
48836
|
+
{ k: 'size', v: value.size },
|
|
48837
|
+
{ k: 'type', v: value.type },
|
|
48838
|
+
{ k: 'lastModified', v: new Date(value.lastModified) },
|
|
48839
|
+
],
|
|
48840
|
+
};
|
|
48841
|
+
}
|
|
48842
|
+
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
48843
|
+
return {
|
|
48844
|
+
typeName: 'Blob',
|
|
48845
|
+
entries: [
|
|
48846
|
+
{ k: 'size', v: value.size },
|
|
48847
|
+
{ k: 'type', v: value.type },
|
|
48848
|
+
],
|
|
48849
|
+
};
|
|
48850
|
+
}
|
|
48851
|
+
if (value instanceof Map) {
|
|
48852
|
+
return { typeName: 'Map', entries: [...value].map(([k, v]) => ({ k: String(k), v })) };
|
|
48853
|
+
}
|
|
48854
|
+
if (value instanceof Set) {
|
|
48855
|
+
return { typeName: 'Set', entries: [...value].map((v, i) => ({ k: String(i), v })) };
|
|
48856
|
+
}
|
|
48857
|
+
if (typeof FormData !== 'undefined' && value instanceof FormData) {
|
|
48858
|
+
return { typeName: 'FormData', entries: [...value].map(([k, v]) => ({ k, v })) };
|
|
48859
|
+
}
|
|
48860
|
+
if (isHeadersValue(value)) {
|
|
48861
|
+
return { typeName: 'HttpHeaders', entries: headerEntries(value) };
|
|
48862
|
+
}
|
|
48863
|
+
return null;
|
|
48864
|
+
};
|
|
48865
|
+
/**
|
|
48866
|
+
* The headers an `HttpHeaders` actually holds, as `name: value` pairs. A header set more than once
|
|
48867
|
+
* joins on `, ` the way the wire format does.
|
|
48868
|
+
*/
|
|
48869
|
+
const headerEntries = (headers) => {
|
|
48870
|
+
try {
|
|
48871
|
+
return headers.keys().map((name) => ({ k: name, v: headers.getAll(name)?.join(', ') ?? '' }));
|
|
48872
|
+
}
|
|
48873
|
+
catch {
|
|
48874
|
+
return [];
|
|
48875
|
+
}
|
|
48876
|
+
};
|
|
48877
|
+
|
|
48797
48878
|
/**
|
|
48798
48879
|
* The value explorer's tree chrome, as a styles-only component the tree mounts itself - a session that
|
|
48799
48880
|
* never opens a JSON view does not inject it.
|
|
@@ -49055,6 +49136,9 @@ const kindOf = (value) => {
|
|
|
49055
49136
|
const entriesOf = (value) => {
|
|
49056
49137
|
if (Array.isArray(value))
|
|
49057
49138
|
return value.map((v, i) => ({ k: String(i), v }));
|
|
49139
|
+
const exotic = exoticOf(value);
|
|
49140
|
+
if (exotic)
|
|
49141
|
+
return exotic.entries ?? [];
|
|
49058
49142
|
if (value && typeof value === 'object') {
|
|
49059
49143
|
return Object.entries(value).map(([k, v]) => ({ k, v }));
|
|
49060
49144
|
}
|
|
@@ -49112,7 +49196,10 @@ class QueryDevtoolsJsonComponent {
|
|
|
49112
49196
|
...(ngDevMode ? [{ debugName: "overrides" }] : /* istanbul ignore next */ []));
|
|
49113
49197
|
this.kind = computed(() => kindOf(this.value()), /* @ts-ignore */
|
|
49114
49198
|
...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
|
|
49115
|
-
this.
|
|
49199
|
+
this.exotic = computed(() => exoticOf(this.value()), /* @ts-ignore */
|
|
49200
|
+
...(ngDevMode ? [{ debugName: "exotic" }] : /* istanbul ignore next */ []));
|
|
49201
|
+
/** A `Date` or a `File` is object-typed but has nothing to expand into, so it renders as a leaf. */
|
|
49202
|
+
this.isContainer = computed(() => (this.kind() === 'array' || this.kind() === 'object') && !this.exotic()?.display, /* @ts-ignore */
|
|
49116
49203
|
...(ngDevMode ? [{ debugName: "isContainer" }] : /* istanbul ignore next */ []));
|
|
49117
49204
|
/** The entries this node covers: the container's own, or just the window a chunk stands for. */
|
|
49118
49205
|
this.ownEntries = computed(() => {
|
|
@@ -49184,6 +49271,9 @@ class QueryDevtoolsJsonComponent {
|
|
|
49184
49271
|
const count = this.ownEntries().length;
|
|
49185
49272
|
if (this.kind() === 'array')
|
|
49186
49273
|
return count ? `[…] ${count}` : '[]';
|
|
49274
|
+
const typeName = this.exotic()?.typeName;
|
|
49275
|
+
if (typeName)
|
|
49276
|
+
return `${typeName}(${count})`;
|
|
49187
49277
|
return count ? `{…} ${count}` : '{}';
|
|
49188
49278
|
}, /* @ts-ignore */
|
|
49189
49279
|
...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
|
|
@@ -49229,13 +49319,16 @@ class QueryDevtoolsJsonComponent {
|
|
|
49229
49319
|
*/
|
|
49230
49320
|
copyValue() {
|
|
49231
49321
|
const kind = this.kind();
|
|
49232
|
-
const
|
|
49322
|
+
const exotic = this.exotic();
|
|
49323
|
+
const value = this.chunk() ? this.chunkValue() : this.copyableValue();
|
|
49233
49324
|
let text;
|
|
49234
49325
|
try {
|
|
49235
49326
|
if (kind === 'string')
|
|
49236
49327
|
text = value;
|
|
49237
49328
|
else if (kind === 'undefined')
|
|
49238
49329
|
text = 'undefined';
|
|
49330
|
+
else if (exotic?.display)
|
|
49331
|
+
text = exotic.display;
|
|
49239
49332
|
else
|
|
49240
49333
|
text = JSON.stringify(value, null, 2);
|
|
49241
49334
|
}
|
|
@@ -49248,6 +49341,11 @@ class QueryDevtoolsJsonComponent {
|
|
|
49248
49341
|
.then(() => this.flagCopied())
|
|
49249
49342
|
.catch(() => undefined);
|
|
49250
49343
|
}
|
|
49344
|
+
/** An exotic container copies the entries the tree shows, not the private fields `JSON.stringify` finds. */
|
|
49345
|
+
copyableValue() {
|
|
49346
|
+
const entries = this.exotic()?.entries;
|
|
49347
|
+
return entries ? Object.fromEntries(entries.map((entry) => [entry.k, entry.v])) : this.value();
|
|
49348
|
+
}
|
|
49251
49349
|
chunkValue() {
|
|
49252
49350
|
const entries = this.ownEntries();
|
|
49253
49351
|
if (this.kind() === 'array')
|
|
@@ -49483,6 +49581,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
49483
49581
|
// Below the component: an interpolated template literal above an inline template breaks the Angular
|
|
49484
49582
|
// language service for the whole template (see `ethlete/no-template-literal-before-inline-template`).
|
|
49485
49583
|
const displayOf = (value) => {
|
|
49584
|
+
const exotic = exoticOf(value);
|
|
49585
|
+
if (exotic?.display)
|
|
49586
|
+
return `${exotic.typeName}(${exotic.display})`;
|
|
49486
49587
|
switch (kindOf(value)) {
|
|
49487
49588
|
case 'string':
|
|
49488
49589
|
return `"${value}"`;
|
|
@@ -49509,8 +49610,9 @@ const buildChunks = (entries, window) => {
|
|
|
49509
49610
|
};
|
|
49510
49611
|
/** Whether a search term appears anywhere in a subtree - used to keep non-matching slices folded. */
|
|
49511
49612
|
const matchesDeep = (value, term) => {
|
|
49512
|
-
if (!value || typeof value !== 'object')
|
|
49613
|
+
if (!value || typeof value !== 'object' || exoticOf(value)?.display) {
|
|
49513
49614
|
return displayOf(value).toLowerCase().includes(term);
|
|
49615
|
+
}
|
|
49514
49616
|
return entriesOf(value).some(({ k, v }) => k.toLowerCase().includes(term) || matchesDeep(v, term));
|
|
49515
49617
|
};
|
|
49516
49618
|
|
|
@@ -49614,13 +49716,11 @@ class QueryDevtoolsFeaturesComponent {
|
|
|
49614
49716
|
</li>
|
|
49615
49717
|
}
|
|
49616
49718
|
</ul>
|
|
49617
|
-
`, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
|
|
49719
|
+
`, isInline: true, styles: ["@layer components{.et-query-devtools-features{display:grid;grid-template-columns:max-content minmax(0,1fr);align-items:center;gap:.4rem .8rem;margin:0 0 .8rem;padding:0;list-style:none}.et-query-devtools-meta .et-query-devtools-features{margin-block-end:0}.et-query-devtools-feature{display:contents}.et-query-devtools-feature>.et-query-devtools-chip{justify-self:start}.et-query-devtools-feature-details{display:flex;flex-wrap:wrap;gap:.3rem}.et-query-devtools-feature-detail{display:inline-flex;align-items:baseline;gap:.4rem;padding:.2rem .5rem;border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent);font-size:1.1rem}.et-query-devtools-feature-label{color:var(--_et-qdt-muted)}.et-query-devtools-feature-value{color:var(--_et-qdt-fg);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49618
49720
|
}
|
|
49619
49721
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsFeaturesComponent, decorators: [{
|
|
49620
49722
|
type: Component,
|
|
49621
|
-
args: [{
|
|
49622
|
-
selector: 'et-query-devtools-features',
|
|
49623
|
-
template: `
|
|
49723
|
+
args: [{ selector: 'et-query-devtools-features', template: `
|
|
49624
49724
|
<ul class="et-query-devtools-features">
|
|
49625
49725
|
@for (feature of features(); track feature.type) {
|
|
49626
49726
|
<li class="et-query-devtools-feature">
|
|
@@ -49638,9 +49738,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
49638
49738
|
</li>
|
|
49639
49739
|
}
|
|
49640
49740
|
</ul>
|
|
49641
|
-
`,
|
|
49642
|
-
encapsulation: ViewEncapsulation.None,
|
|
49643
|
-
}]
|
|
49741
|
+
`, encapsulation: ViewEncapsulation.None, styles: ["@layer components{.et-query-devtools-features{display:grid;grid-template-columns:max-content minmax(0,1fr);align-items:center;gap:.4rem .8rem;margin:0 0 .8rem;padding:0;list-style:none}.et-query-devtools-meta .et-query-devtools-features{margin-block-end:0}.et-query-devtools-feature{display:contents}.et-query-devtools-feature>.et-query-devtools-chip{justify-self:start}.et-query-devtools-feature-details{display:flex;flex-wrap:wrap;gap:.3rem}.et-query-devtools-feature-detail{display:inline-flex;align-items:baseline;gap:.4rem;padding:.2rem .5rem;border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent);font-size:1.1rem}.et-query-devtools-feature-label{color:var(--_et-qdt-muted)}.et-query-devtools-feature-value{color:var(--_et-qdt-fg);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}}\n"] }]
|
|
49644
49742
|
}], propDecorators: { features: [{ type: i0.Input, args: [{ isSignal: true, alias: "features", required: true }] }] } });
|
|
49645
49743
|
|
|
49646
49744
|
const QUERY_DEVTOOLS_HOST = new InjectionToken('QUERY_DEVTOOLS_HOST');
|
|
@@ -49653,11 +49751,11 @@ class QueryDevtoolsAuthTabComponent {
|
|
|
49653
49751
|
this.host = injectQueryDevtoolsHost();
|
|
49654
49752
|
}
|
|
49655
49753
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsAuthTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49656
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsAuthTabComponent, isStandalone: true, selector: "et-query-devtools-auth-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @for (entry of host.authEntries(); track entry.id) {\n @let auth = host.asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (host.authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (host.authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of host.authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @if (host.authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49754
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsAuthTabComponent, isStandalone: true, selector: "et-query-devtools-auth-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @for (entry of host.authEntries(); track entry.id) {\n @let auth = host.asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n @if (host.authLeadership(auth); as leadership) {\n <span\n [class.et-query-devtools-chip--success]=\"leadership.tone === 'success'\"\n [class.et-query-devtools-chip--muted]=\"leadership.tone === 'muted'\"\n [title]=\"leadership.title\"\n class=\"et-query-devtools-chip\"\n >\n {{ leadership.label }}\n </span>\n }\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (host.authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (host.authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of host.authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @if (host.authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49657
49755
|
}
|
|
49658
49756
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsAuthTabComponent, decorators: [{
|
|
49659
49757
|
type: Component,
|
|
49660
|
-
args: [{ selector: 'et-query-devtools-auth-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @for (entry of host.authEntries(); track entry.id) {\n @let auth = host.asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (host.authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (host.authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of host.authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @if (host.authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n</div>\n" }]
|
|
49758
|
+
args: [{ selector: 'et-query-devtools-auth-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @for (entry of host.authEntries(); track entry.id) {\n @let auth = host.asAuth(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'auth provider' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"auth.isAuthenticated()\"\n [class.et-query-devtools-chip--muted]=\"!auth.isAuthenticated()\"\n class=\"et-query-devtools-chip\"\n >\n {{ auth.isAuthenticated() ? 'authenticated' : 'anonymous' }}\n </span>\n @if (host.authLeadership(auth); as leadership) {\n <span\n [class.et-query-devtools-chip--success]=\"leadership.tone === 'success'\"\n [class.et-query-devtools-chip--muted]=\"leadership.tone === 'muted'\"\n [title]=\"leadership.title\"\n class=\"et-query-devtools-chip\"\n >\n {{ leadership.label }}\n </span>\n }\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.clientBaseUrl || entry.meta.clientName || '\u2014' }}</dd>\n <dt>Access token</dt>\n <dd>{{ auth.accessToken() ? 'present' : 'none' }}</dd>\n <dt>Refresh token</dt>\n <dd>{{ auth.refreshToken() ? 'present' : 'none' }}</dd>\n @if (host.authTokenExpiry(auth); as expiry) {\n <dt>Token expires in</dt>\n <dd>{{ expiry }}</dd>\n }\n @if (auth.executionState(); as state) {\n <dt>Execution state</dt>\n <dd>{{ state.type }} \u00B7 {{ state.state }}</dd>\n }\n @if (host.authQueryKeys(auth).length) {\n <dt>Queries</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (key of host.authQueryKeys(auth); track key) {\n <span class=\"et-query-devtools-chip\">{{ key }}</span>\n }\n </div>\n </dd>\n }\n @if (entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @if (host.authTokenPayload(auth); as payload) {\n <h4 class=\"et-query-devtools-section\">Access token payload</h4>\n <et-query-devtools-json [value]=\"payload\" />\n }\n\n @if (auth.latestNonInternalQuery(); as latest) {\n <h4 class=\"et-query-devtools-section\">Latest auth query \u00B7 {{ latest.key }}</h4>\n <et-query-devtools-json [value]=\"latest.snapshot.response()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No auth providers registered.</p>\n }\n</div>\n" }]
|
|
49661
49759
|
}] });
|
|
49662
49760
|
|
|
49663
49761
|
/** How the panel spells a teardown cause out - the same wording in the Events tab and the Cache tab. */
|
|
@@ -49678,11 +49776,11 @@ class QueryDevtoolsCacheTabComponent {
|
|
|
49678
49776
|
return DESTROY_CAUSE_LABELS[cause];
|
|
49679
49777
|
}
|
|
49680
49778
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsCacheTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49681
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsCacheTabComponent, isStandalone: true, selector: "et-query-devtools-cache-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @for (client of host.cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.rows.length }} entries</span>\n @if (client.rows.length) {\n <span\n class=\"et-query-devtools-count\"\n title=\"The measured size of every cached response. Sizes are read from the decoded bodies, so they ignore transport compression.\"\n >\n {{ host.formatTransferred(client.bytes, client.isEstimatedBytes) }}\n </span>\n }\n @if (client.unused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Entries with no consumer left. They are waiting out their keepUnusedFor window, not leaking.\"\n >\n {{ client.unused }} collectible\n </span>\n }\n @if (client.client?.subtle?.persistence) {\n <span class=\"et-query-devtools-count\">{{ host.persistedCount(client.client!) }} on disk</span>\n <button (click)=\"host.clearPersistedQueries(client.client!)\" class=\"et-query-devtools-btn\" type=\"button\">\n Clear disk\n </button>\n }\n <button\n [disabled]=\"!client.rows.length\"\n (click)=\"host.evictAllCacheEntries(client.repository)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Drop every entry of this client, consumers included - the cold-start check without a reload\"\n >\n Evict all\n </button>\n </div>\n @if (host.clientFeatures(client.client); as features) {\n <et-query-devtools-features [features]=\"features\" />\n }\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Size</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Sync</th>\n <th>Disk</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of client.rows; track row.entry.key) {\n @let cacheEntry = row.entry;\n @let expanded = host.isCacheValueExpanded(client.name, cacheEntry.key);\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>\n {{ cacheEntry.consumerCount }}\n <!-- An entry nothing holds any more is the one row worth explaining: it looks\n like a leak and is in fact a keepUnusedFor window running out. -->\n @if (cacheEntry.isUnused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"No consumer left - kept for its keepUnusedFor window, then collected\"\n >\n collectible\n </span>\n }\n </td>\n <td>{{ row.bytes ? host.formatTransferred(row.bytes, row.isEstimatedBytes) : '\u2014' }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ host.cacheFreshness(cacheEntry) }}</td>\n <td>{{ host.cacheSync(cacheEntry, client.pollStates) }}</td>\n <td>{{ host.cachePersistence(cacheEntry) }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n <button\n [class.et-query-devtools-btn--active]=\"expanded\"\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.toggleCacheValue(client.name, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the response held under this key\"\n >\n Value\n </button>\n <button (click)=\"host.refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"host.evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </span>\n </td>\n </tr>\n @if (expanded) {\n <tr>\n <td class=\"et-query-devtools-cell-value\" colspan=\"8\">\n <et-query-devtools-json [value]=\"cacheEntry.request.response()\" />\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"8\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (client.dropped.length) {\n <h4 class=\"et-query-devtools-section\">Dropped</h4>\n <ul class=\"et-query-devtools-dropped\">\n @for (entry of client.dropped; track entry.at) {\n <li>\n <span class=\"et-query-devtools-method\">{{ entry.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(entry.url) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{\n dropCauseLabel(entry.cause)\n }}</span>\n <span class=\"et-query-devtools-count\">{{ host.formatTime(entry.at) }}</span>\n </li>\n }\n </ul>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49779
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsCacheTabComponent, isStandalone: true, selector: "et-query-devtools-cache-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @for (client of host.cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.rows.length }} entries</span>\n @if (client.rows.length) {\n <span\n class=\"et-query-devtools-count\"\n title=\"The measured size of every cached response. Sizes are read from the decoded bodies, so they ignore transport compression.\"\n >\n {{ host.formatTransferred(client.bytes, client.isEstimatedBytes) }}\n </span>\n }\n @if (client.unused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Entries with no consumer left. They are waiting out their keepUnusedFor window, not leaking.\"\n >\n {{ client.unused }} collectible\n </span>\n }\n @if (client.client?.subtle?.persistence) {\n <span class=\"et-query-devtools-count\">{{ host.persistedCount(client.client!) }} on disk</span>\n <button (click)=\"host.clearPersistedQueries(client.client!)\" class=\"et-query-devtools-btn\" type=\"button\">\n Clear disk\n </button>\n }\n <button\n [disabled]=\"!client.rows.length\"\n (click)=\"host.evictAllCacheEntries(client.repository)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Drop every entry of this client, consumers included - the cold-start check without a reload\"\n >\n Evict all\n </button>\n </div>\n @if (host.clientFeatures(client.client); as features) {\n <et-query-devtools-features [features]=\"features\" />\n }\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Size</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Sync</th>\n <th>Disk</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of client.rows; track row.entry.key) {\n @let cacheEntry = row.entry;\n @let expanded = host.isCacheValueExpanded(client.name, cacheEntry.key);\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>\n {{ cacheEntry.consumerCount }}\n <!-- An entry nothing holds any more is the one row worth explaining: it looks\n like a leak and is in fact a keepUnusedFor window running out. -->\n @if (cacheEntry.isUnused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"No consumer left - kept for its keepUnusedFor window, then collected\"\n >\n collectible\n </span>\n }\n </td>\n <td>{{ row.bytes ? host.formatTransferred(row.bytes, row.isEstimatedBytes) : '\u2014' }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ host.cacheFreshness(cacheEntry) }}</td>\n <td>{{ host.cacheSync(cacheEntry, client.pollStates) }}</td>\n <td>{{ host.cachePersistence(cacheEntry) }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n <button\n [class.et-query-devtools-btn--active]=\"expanded\"\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.toggleCacheValue(client.name, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the response held under this key\"\n >\n Value\n </button>\n <button (click)=\"host.refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"host.evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </span>\n </td>\n </tr>\n @if (expanded) {\n <tr>\n <td class=\"et-query-devtools-cell-value\" colspan=\"8\">\n <et-query-devtools-json [value]=\"cacheEntry.request.response()\" />\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"8\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (client.dropped.length) {\n <h4 class=\"et-query-devtools-section\">Dropped</h4>\n <ul class=\"et-query-devtools-dropped\">\n @for (entry of client.dropped; track entry.at) {\n <li>\n <span class=\"et-query-devtools-method\">{{ entry.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(entry.url) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{\n dropCauseLabel(entry.cause)\n }}</span>\n <span class=\"et-query-devtools-count\">{{ host.formatTime(entry.at) }}</span>\n </li>\n }\n </ul>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-dropped{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none;color:var(--_et-qdt-muted)}.et-query-devtools-dropped li{display:flex;align-items:center;gap:.8rem}.et-query-devtools-cell-value{padding-inline-start:1.6rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49682
49780
|
}
|
|
49683
49781
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsCacheTabComponent, decorators: [{
|
|
49684
49782
|
type: Component,
|
|
49685
|
-
args: [{ selector: 'et-query-devtools-cache-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @for (client of host.cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.rows.length }} entries</span>\n @if (client.rows.length) {\n <span\n class=\"et-query-devtools-count\"\n title=\"The measured size of every cached response. Sizes are read from the decoded bodies, so they ignore transport compression.\"\n >\n {{ host.formatTransferred(client.bytes, client.isEstimatedBytes) }}\n </span>\n }\n @if (client.unused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Entries with no consumer left. They are waiting out their keepUnusedFor window, not leaking.\"\n >\n {{ client.unused }} collectible\n </span>\n }\n @if (client.client?.subtle?.persistence) {\n <span class=\"et-query-devtools-count\">{{ host.persistedCount(client.client!) }} on disk</span>\n <button (click)=\"host.clearPersistedQueries(client.client!)\" class=\"et-query-devtools-btn\" type=\"button\">\n Clear disk\n </button>\n }\n <button\n [disabled]=\"!client.rows.length\"\n (click)=\"host.evictAllCacheEntries(client.repository)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Drop every entry of this client, consumers included - the cold-start check without a reload\"\n >\n Evict all\n </button>\n </div>\n @if (host.clientFeatures(client.client); as features) {\n <et-query-devtools-features [features]=\"features\" />\n }\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Size</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Sync</th>\n <th>Disk</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of client.rows; track row.entry.key) {\n @let cacheEntry = row.entry;\n @let expanded = host.isCacheValueExpanded(client.name, cacheEntry.key);\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>\n {{ cacheEntry.consumerCount }}\n <!-- An entry nothing holds any more is the one row worth explaining: it looks\n like a leak and is in fact a keepUnusedFor window running out. -->\n @if (cacheEntry.isUnused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"No consumer left - kept for its keepUnusedFor window, then collected\"\n >\n collectible\n </span>\n }\n </td>\n <td>{{ row.bytes ? host.formatTransferred(row.bytes, row.isEstimatedBytes) : '\u2014' }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ host.cacheFreshness(cacheEntry) }}</td>\n <td>{{ host.cacheSync(cacheEntry, client.pollStates) }}</td>\n <td>{{ host.cachePersistence(cacheEntry) }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n <button\n [class.et-query-devtools-btn--active]=\"expanded\"\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.toggleCacheValue(client.name, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the response held under this key\"\n >\n Value\n </button>\n <button (click)=\"host.refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"host.evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </span>\n </td>\n </tr>\n @if (expanded) {\n <tr>\n <td class=\"et-query-devtools-cell-value\" colspan=\"8\">\n <et-query-devtools-json [value]=\"cacheEntry.request.response()\" />\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"8\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (client.dropped.length) {\n <h4 class=\"et-query-devtools-section\">Dropped</h4>\n <ul class=\"et-query-devtools-dropped\">\n @for (entry of client.dropped; track entry.at) {\n <li>\n <span class=\"et-query-devtools-method\">{{ entry.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(entry.url) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{\n dropCauseLabel(entry.cause)\n }}</span>\n <span class=\"et-query-devtools-count\">{{ host.formatTime(entry.at) }}</span>\n </li>\n }\n </ul>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n</div>\n" }]
|
|
49783
|
+
args: [{ selector: 'et-query-devtools-cache-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @for (client of host.cacheView(); track client.name) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.baseUrl || client.name }}</strong>\n <span class=\"et-query-devtools-count\">{{ client.rows.length }} entries</span>\n @if (client.rows.length) {\n <span\n class=\"et-query-devtools-count\"\n title=\"The measured size of every cached response. Sizes are read from the decoded bodies, so they ignore transport compression.\"\n >\n {{ host.formatTransferred(client.bytes, client.isEstimatedBytes) }}\n </span>\n }\n @if (client.unused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Entries with no consumer left. They are waiting out their keepUnusedFor window, not leaking.\"\n >\n {{ client.unused }} collectible\n </span>\n }\n @if (client.client?.subtle?.persistence) {\n <span class=\"et-query-devtools-count\">{{ host.persistedCount(client.client!) }} on disk</span>\n <button (click)=\"host.clearPersistedQueries(client.client!)\" class=\"et-query-devtools-btn\" type=\"button\">\n Clear disk\n </button>\n }\n <button\n [disabled]=\"!client.rows.length\"\n (click)=\"host.evictAllCacheEntries(client.repository)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Drop every entry of this client, consumers included - the cold-start check without a reload\"\n >\n Evict all\n </button>\n </div>\n @if (host.clientFeatures(client.client); as features) {\n <et-query-devtools-features [features]=\"features\" />\n }\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Request</th>\n <th>Consumers</th>\n <th>Size</th>\n <th>Secure</th>\n <th>Freshness</th>\n <th>Sync</th>\n <th>Disk</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of client.rows; track row.entry.key) {\n @let cacheEntry = row.entry;\n @let expanded = host.isCacheValueExpanded(client.name, cacheEntry.key);\n <tr>\n <td [title]=\"cacheEntry.request.method + ' ' + cacheEntry.request.url\">\n <span class=\"et-query-devtools-method\">{{ cacheEntry.request.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(cacheEntry.request.url) }}</span>\n </td>\n <td>\n {{ cacheEntry.consumerCount }}\n <!-- An entry nothing holds any more is the one row worth explaining: it looks\n like a leak and is in fact a keepUnusedFor window running out. -->\n @if (cacheEntry.isUnused) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"No consumer left - kept for its keepUnusedFor window, then collected\"\n >\n collectible\n </span>\n }\n </td>\n <td>{{ row.bytes ? host.formatTransferred(row.bytes, row.isEstimatedBytes) : '\u2014' }}</td>\n <td>{{ cacheEntry.isSecure ? 'yes' : 'no' }}</td>\n <td>{{ host.cacheFreshness(cacheEntry) }}</td>\n <td>{{ host.cacheSync(cacheEntry, client.pollStates) }}</td>\n <td>{{ host.cachePersistence(cacheEntry) }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n <button\n [class.et-query-devtools-btn--active]=\"expanded\"\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.toggleCacheValue(client.name, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the response held under this key\"\n >\n Value\n </button>\n <button (click)=\"host.refetchCacheEntry(cacheEntry)\" class=\"et-query-devtools-btn\" type=\"button\">\n Refetch\n </button>\n <button\n (click)=\"host.evictCacheEntry(client.repository, cacheEntry.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Evict\n </button>\n </span>\n </td>\n </tr>\n @if (expanded) {\n <tr>\n <td class=\"et-query-devtools-cell-value\" colspan=\"8\">\n <et-query-devtools-json [value]=\"cacheEntry.request.response()\" />\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <td class=\"et-query-devtools-empty\" colspan=\"8\">Cache empty.</td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (client.dropped.length) {\n <h4 class=\"et-query-devtools-section\">Dropped</h4>\n <ul class=\"et-query-devtools-dropped\">\n @for (entry of client.dropped; track entry.at) {\n <li>\n <span class=\"et-query-devtools-method\">{{ entry.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(entry.url) }}</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{\n dropCauseLabel(entry.cause)\n }}</span>\n <span class=\"et-query-devtools-count\">{{ host.formatTime(entry.at) }}</span>\n </li>\n }\n </ul>\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No clients with a cache yet.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-dropped{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none;color:var(--_et-qdt-muted)}.et-query-devtools-dropped li{display:flex;align-items:center;gap:.8rem}.et-query-devtools-cell-value{padding-inline-start:1.6rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}}\n"] }]
|
|
49686
49784
|
}] });
|
|
49687
49785
|
|
|
49688
49786
|
const jsonBody$1 = (body) => {
|
|
@@ -49803,81 +49901,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
49803
49901
|
args: [{ selector: 'et-query-devtools-events-tab', encapsulation: ViewEncapsulation.None, template: "<div class=\"et-query-devtools-pane\">\n <div class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n @if (eventClients().length > 1) {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #eventClientSelect\n [value]=\"host.eventClient() ?? ''\"\n (change)=\"host.eventClient.set(eventClientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of eventClients(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n @let errorsOnly = host.eventErrorsOnly();\n <button\n [class.et-query-devtools-facet--active]=\"errorsOnly\"\n [attr.aria-pressed]=\"errorsOnly\"\n (click)=\"toggleEventErrorsOnly()\"\n class=\"et-query-devtools-chip et-query-devtools-facet\"\n type=\"button\"\n title=\"Show only the requests that failed\"\n >\n Errors only\n <span class=\"et-query-devtools-facet-count\">{{ host.tabBadges().events.errors }}</span>\n </button>\n <span class=\"et-query-devtools-count\">\n @if (isEventLogNarrowed()) {\n {{ filteredEvents().length }} of {{ host.eventLog().length }} events\n } @else {\n {{ host.eventLog().length }} events\n }\n </span>\n @if (isEventLogNarrowed()) {\n <button\n (click)=\"clearEventFilters()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the client scope and the errors-only toggle\"\n aria-label=\"Clear filters\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n <button (click)=\"clearEvents()\" class=\"et-query-devtools-btn et-query-devtools-toolbar-btn\" type=\"button\">\n Clear\n </button>\n </div>\n </div>\n <div class=\"et-query-devtools-scroll\">\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Time</th>\n <th>Base URL</th>\n <th>Type</th>\n <th>Request</th>\n <th>Duration</th>\n <th>Size</th>\n </tr>\n </thead>\n <tbody>\n @for (event of filteredEvents(); track event.id) {\n <tr [attr.data-status]=\"eventRowStatus(event)\">\n <td>{{ host.formatTime(event.timestamp) }}</td>\n <td class=\"et-query-devtools-mono\">{{ event.client }}</td>\n <td>\n {{ eventTypeLabel(event) }}\n @if (event.isSecure) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">secure</span>\n }\n </td>\n @if (event.cause; as cause) {\n <td>\n <span class=\"et-query-devtools-url\">{{ host.causeLabel(cause) }}</span>\n @if (event.refreshed?.length) {\n <div class=\"et-query-devtools-chips\">\n @for (refreshed of event.refreshed; track $index) {\n @if (refreshed.queryIds[0]; as queryId) {\n <button\n (click)=\"host.selectQuery(queryId)\"\n class=\"et-query-devtools-chip et-query-devtools-chip--button\"\n type=\"button\"\n title=\"Open {{ refreshed.method }} {{ refreshed.path }}\"\n >\n {{ refreshed.method }} {{ refreshed.path }}\n <!-- One request, several queries on the same cache key. Spelling the count\n out beats repeating an identical row per consumer. -->\n @if (refreshed.queryIds.length > 1) {\n <small>\u00D7{{ refreshed.queryIds.length }}</small>\n }\n </button>\n } @else {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"No registered query holds this cache entry any more\"\n >\n {{ refreshed.method }} {{ refreshed.path }}\n </span>\n }\n }\n </div>\n } @else {\n <span class=\"et-query-devtools-hint\">matched no query in use</span>\n }\n </td>\n } @else if (event.url; as url) {\n <td>\n @if (event.queryId) {\n <button\n (click)=\"selectEventRow(event)\"\n class=\"et-query-devtools-row-link\"\n type=\"button\"\n title=\"Open {{ event.method }} {{ url }}\"\n >\n <span class=\"et-query-devtools-method\">{{ event.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(url) }}</span>\n </button>\n } @else {\n <span [title]=\"event.method + ' ' + url\">\n <span class=\"et-query-devtools-method\">{{ event.method }}</span>\n <span class=\"et-query-devtools-url\">{{ host.requestPath(url) }}</span>\n </span>\n }\n </td>\n } @else {\n <td class=\"et-query-devtools-url\">all secure entries dropped</td>\n }\n <td>{{ host.formatDuration(event.durationMs) }}</td>\n <td>{{ event.bytes === null ? '\u2014' : host.formatTransferred(event.bytes, event.isEstimatedBytes) }}</td>\n </tr>\n } @empty {\n <tr>\n @if (host.eventLog().length) {\n <td class=\"et-query-devtools-empty\" colspan=\"6\">\n No event matches the filter \u00B7 {{ host.eventLog().length }} in the log.\n </td>\n } @else {\n <td class=\"et-query-devtools-empty\" colspan=\"6\">No events captured yet.</td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n" }]
|
|
49804
49902
|
}] });
|
|
49805
49903
|
|
|
49806
|
-
/**
|
|
49807
|
-
* A route with its path params and query string picked out from the static path. The segments render
|
|
49808
|
-
* element-only: a text node between them would render as a space inside the route.
|
|
49809
|
-
*/
|
|
49810
|
-
class QueryDevtoolsRouteComponent {
|
|
49811
|
-
constructor() {
|
|
49812
|
-
this.segments = input.required(/* @ts-ignore */
|
|
49813
|
-
...(ngDevMode ? [{ debugName: "segments" }] : /* istanbul ignore next */ []));
|
|
49814
|
-
this.fallback = input('—', /* @ts-ignore */
|
|
49815
|
-
...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
|
|
49816
|
-
}
|
|
49817
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsRouteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49818
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsRouteComponent, isStandalone: true, selector: "et-query-devtools-route", inputs: { segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: true, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
49819
|
-
@for (segment of segments(); track $index) {
|
|
49820
|
-
<span [class]="'et-query-devtools-route-' + segment.kind" [attr.title]="segment.name">{{ segment.text }}</span>
|
|
49821
|
-
} @empty {
|
|
49822
|
-
{{ fallback() }}
|
|
49823
|
-
}
|
|
49824
|
-
`, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
|
|
49825
|
-
}
|
|
49826
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsRouteComponent, decorators: [{
|
|
49827
|
-
type: Component,
|
|
49828
|
-
args: [{
|
|
49829
|
-
selector: 'et-query-devtools-route',
|
|
49830
|
-
template: `
|
|
49831
|
-
@for (segment of segments(); track $index) {
|
|
49832
|
-
<span [class]="'et-query-devtools-route-' + segment.kind" [attr.title]="segment.name">{{ segment.text }}</span>
|
|
49833
|
-
} @empty {
|
|
49834
|
-
{{ fallback() }}
|
|
49835
|
-
}
|
|
49836
|
-
`,
|
|
49837
|
-
encapsulation: ViewEncapsulation.None,
|
|
49838
|
-
}]
|
|
49839
|
-
}], propDecorators: { segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: true }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }] } });
|
|
49840
|
-
|
|
49841
|
-
/**
|
|
49842
|
-
* The query detail: head, live progress, run/edit/force actions and the overview/history/data
|
|
49843
|
-
* sub-tabs. Rendered inline by the Queries tab and wrapped in `<et-query-devtools-drawer>` by every
|
|
49844
|
-
* other tab's split view - both read/write the same {@link QueryDevtoolsHost.detailTab} and JIT editor
|
|
49845
|
-
* state, so switching sub-tab in one instance is switching it everywhere, exactly as when this was one
|
|
49846
|
-
* component holding everything.
|
|
49847
|
-
*/
|
|
49848
|
-
class QueryDevtoolsDetailComponent {
|
|
49849
|
-
constructor() {
|
|
49850
|
-
this.host = injectQueryDevtoolsHost();
|
|
49851
|
-
this.sel = input.required(/* @ts-ignore */
|
|
49852
|
-
...(ngDevMode ? [{ debugName: "sel" }] : /* istanbul ignore next */ []));
|
|
49853
|
-
/**
|
|
49854
|
-
* Whether this is a tombstone. Everything that would run, edit or force the query is hidden for one -
|
|
49855
|
-
* its handle is a frozen snapshot, so those actions have nothing to act on.
|
|
49856
|
-
*/
|
|
49857
|
-
this.isGone = computed(() => !!this.sel().entry.destroyedAt, /* @ts-ignore */
|
|
49858
|
-
...(ngDevMode ? [{ debugName: "isGone" }] : /* istanbul ignore next */ []));
|
|
49859
|
-
this.detailTabs = [
|
|
49860
|
-
{ id: 'overview', label: 'Overview' },
|
|
49861
|
-
{ id: 'history', label: 'History' },
|
|
49862
|
-
{ id: 'data', label: 'Data' },
|
|
49863
|
-
];
|
|
49864
|
-
/** What a run's Diff button reads as at each end of the comparison. */
|
|
49865
|
-
this.diffRoles = {
|
|
49866
|
-
base: {
|
|
49867
|
-
label: 'Base',
|
|
49868
|
-
title: 'The older end of the comparison - click another run to set the newer one, or this one to clear it',
|
|
49869
|
-
},
|
|
49870
|
-
compare: { label: 'Compare', title: 'The newer end of the comparison - click to clear it' },
|
|
49871
|
-
};
|
|
49872
|
-
}
|
|
49873
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49874
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsDetailComponent, isStandalone: true, selector: "et-query-devtools-detail", inputs: { sel: { classPropertyName: "sel", publicName: "sel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let s = sel();\n\n<div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ s.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(s.entry, s.query)\" />\n </span>\n @if (host.isTampered(s.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n @if (isGone()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">gone</span>\n }\n</div>\n\n@if (s.entry.destroyedAt; as destroyedAt) {\n <p class=\"et-query-devtools-gone-note\">\n Destroyed at {{ host.formatTime(destroyedAt) }}. This is the last state the query held - nothing here updates, and\n it cannot be run again.\n </p>\n}\n\n@if (host.requestProgress(s.query); as live) {\n <div class=\"et-query-devtools-live\">\n @if (live.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"The retry policy is backing off before it tries again. A query stuck loading with this chip is waiting, not slow.\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n attempt {{ retry.attempt }} in {{ host.formatCountdown(live.retryInMs) }}\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.retryCause(retry.status) }} \u00B7 backing off {{ host.formatDuration(retry.delayMs) }}\n </span>\n } @else if (live.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"How many HTTP attempts the last execution took - the retry policy fired for the rest\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ live.attempts }} attempts\n </span>\n }\n\n @if (live.progress; as progress) {\n <span\n [attr.aria-valuenow]=\"progress.percentage\"\n class=\"et-query-devtools-progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-label=\"Transfer progress\"\n >\n <span [style.inline-size.%]=\"progress.percentage\" class=\"et-query-devtools-progress-bar\"></span>\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.formatPercent(progress.percentage) }} \u00B7 {{ host.formatBytes(progress.loaded) }} of\n {{ host.formatBytes(progress.total) }}\n @if (progress.speed !== null) {\n \u00B7 {{ host.formatSpeed(progress.speed) }}\n }\n @if (progress.remainingTime !== null) {\n \u00B7 {{ host.formatDuration(progress.remainingTime) }} left\n }\n </span>\n }\n </div>\n}\n\n<div class=\"et-query-devtools-actions\">\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"host.executeQuery(s.query, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.executeQuery(s.query, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"host.resetQuery(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n }\n <button (click)=\"host.copyReport(s.entry, s.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ host.copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <button\n (click)=\"host.copyCurlRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as a curl command - the URL, the headers as the request resolved them, and the body\"\n >\n {{ host.copiedCurl() ? '\u2713 Copied' : 'cURL' }}\n </button>\n <button\n (click)=\"host.copyInsomniaRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as an Insomnia collection (Import \u2192 From Clipboard). Includes the request headers, and the token refresh for a secure query.\"\n >\n {{ host.copiedInsomnia() ? '\u2713 Copied' : 'Insomnia' }}\n </button>\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"host.openResponseEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"host.openArgsEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"host.forceLoading(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"host.forceError(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"host.forceEmpty(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"host.clearForced(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n }\n</div>\n\n@if (!isGone() && host.editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (host.editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"host.editorSeed\"\n (input)=\"host.responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyResponse(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"host.editorSeed\"\n (input)=\"host.argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyArgs(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (host.editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n}\n\n@let detailRuns = host.queryRuns(s.entry);\n<nav class=\"et-query-devtools-subtabs\" role=\"tablist\">\n @for (tab of detailTabs; track tab.id) {\n <button\n [class.et-query-devtools-subtab--active]=\"host.detailTab() === tab.id\"\n [attr.aria-selected]=\"host.detailTab() === tab.id\"\n (click)=\"host.detailTab.set(tab.id)\"\n class=\"et-query-devtools-subtab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (tab.id === 'history' && detailRuns.length) {\n <span class=\"et-query-devtools-tab-badge\">{{ detailRuns.length }}</span>\n }\n <!-- The error body lives under Data, so the tab has to say so - a failure must not hide\n behind a tab that is not open. -->\n @if (tab.id === 'data' && s.query.error()) {\n <span class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\">!</span>\n }\n </button>\n }\n</nav>\n\n@switch (host.detailTab()) {\n @case ('overview') {\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">\n {{ s.entry.meta.clientBaseUrl || s.entry.meta.clientName || '\u2014' }}\n </dd>\n <dt>Route</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.entry.meta.route || '\u2014' }}</dd>\n <dt>Request URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ host.requestUrl(s.query) || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ host.queryStatus(s.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ host.formatTime(s.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ s.query.triggeredBy() || 'user' }}</dd>\n @let refreshes = host.refreshesFor(s.entry.id);\n @if (refreshes.length) {\n <dt title=\"Invalidations and mutation refreshes that re-executed this query, as far back as the event log goes\">\n Refetched by\n </dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (refresh of refreshes.slice(0, 5); track refresh.id) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ host.formatTime(refresh.timestamp) }} \u00B7 {{ refresh.label }}\n </span>\n }\n @if (refreshes.length > 5) {\n <span class=\"et-query-devtools-hint\">+{{ refreshes.length - 5 }} earlier</span>\n }\n </div>\n </dd>\n }\n @let drivers = host.formsDrivingQuery(s.entry);\n @if (drivers.length) {\n <dt>Args from</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (driver of drivers; track driver.id) {\n <button\n (click)=\"host.selectForm(driver.id)\"\n class=\"et-query-devtools-chip et-query-devtools-chip--button\"\n type=\"button\"\n title=\"Open the query form in the Forms tab\"\n >\n {{ driver.meta.name }}\n </button>\n }\n </div>\n </dd>\n }\n @if (s.entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"s.entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @let activity = host.queryActivity(s.entry);\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Activity</h4>\n <button\n [disabled]=\"!activity.hasActivity\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the counters and the run history, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n\n <dl class=\"et-query-devtools-stats\">\n <div class=\"et-query-devtools-stat\" title=\"Every time the query ran, cache hits included\">\n <dt>Refreshes</dt>\n <dd>{{ activity.stats.executions }}</dd>\n @if (activity.cacheServed) {\n <span class=\"et-query-devtools-stat-sub\">{{ activity.cacheServed }} without a request</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\" title=\"Executions that started a request, and how they ended\">\n <dt>Requests</dt>\n <dd>{{ activity.stats.requests }}</dd>\n <span class=\"et-query-devtools-stat-sub\">\n {{ activity.stats.responses }} ok\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n </span>\n </div>\n <div\n class=\"et-query-devtools-stat\"\n title=\"Total response payload received. Sizes without a content-length header are measured from the decoded body, so they ignore compression.\"\n >\n <dt>Received</dt>\n <dd>{{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}</dd>\n @if (activity.avgResponseBytes !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatBytes(activity.avgResponseBytes) }} per response</span>\n }\n </div>\n @if (activity.stats.sentBytes) {\n <div class=\"et-query-devtools-stat\" title=\"Total request body sent (headers not counted)\">\n <dt>Sent</dt>\n <dd>{{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}</dd>\n </div>\n }\n @if (activity.stats.retries) {\n <div\n class=\"et-query-devtools-stat\"\n title=\"Attempts the retry policy added on top of the first one. Which run they belong to is under History.\"\n >\n <dt>Retries</dt>\n <dd>{{ activity.stats.retries }}</dd>\n </div>\n }\n <div class=\"et-query-devtools-stat\" title=\"Measured from the execution that preceded each response\">\n <dt>Duration</dt>\n <dd>{{ host.formatDuration(activity.stats.lastDurationMs) }}</dd>\n @if (activity.avgDurationMs !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatDuration(activity.avgDurationMs) }} on average</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\">\n <dt>Last response</dt>\n <dd class=\"et-query-devtools-stat-value--sm\">{{ host.formatTime(activity.stats.lastResponseAt) }}</dd>\n @if (activity.stats.firstExecutedAt !== null) {\n <span class=\"et-query-devtools-stat-sub\"\n >first ran {{ host.formatTime(activity.stats.firstExecutedAt) }}</span\n >\n }\n </div>\n </dl>\n }\n @case ('history') {\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Runs</h4>\n <button\n [disabled]=\"!detailRuns.length\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the run history and the counters, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n @if (detailRuns.length) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Run</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Received</th>\n <th>Body</th>\n </tr>\n </thead>\n <tbody>\n @for (run of detailRuns; track run.index) {\n <tr [attr.data-status]=\"run.status === 'error' ? 'error' : null\">\n <td>\n <span class=\"et-query-devtools-run-cell\">\n <span\n [attr.data-status]=\"host.runStatus(run)\"\n [title]=\"run.status\"\n class=\"et-query-devtools-status\"\n ></span>\n #{{ run.index }}\n @if (run.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Took {{\n run.attempts\n }} attempts - the duration next to it covers every one of them, backoff included\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ run.attempts }}\n </span>\n }\n @if (!run.didRequest) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Arrived without a request of this query's own - a poll, another consumer of the same cache entry, or another tab\"\n >\n shared\n </span>\n }\n @if (run.error; as error) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"{{ error.messages.join(' \u00B7 ') || 'The failure carried no message' }}\"\n >\n {{ error.code || 'failed' }}\n </span>\n }\n </span>\n </td>\n <td>{{ host.formatTime(run.startedAt) }}</td>\n <td>\n @if (run.endedAt === null) {\n in flight\n } @else {\n {{ host.formatDuration(run.endedAt - run.startedAt) }}\n }\n </td>\n <td>{{ run.receivedBytes ? host.formatBytes(run.receivedBytes) : '\u2014' }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n @if (host.canDiffRun(s.entry, run)) {\n @let role = host.diffRunRole(s.entry, run);\n @let armed = role ? diffRoles[role] : null;\n <button\n [class.et-query-devtools-btn--active]=\"!!armed\"\n [title]=\"\n armed?.title ?? 'Compare this response against another run - click a second row to pick which'\n \"\n (click)=\"host.toggleRunDiff(s.entry, run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n {{ armed?.label ?? 'Diff' }}\n </button>\n } @else if (run.error?.hasBody) {\n <button\n [class.et-query-devtools-btn--active]=\"host.errorRunIndex() === run.index\"\n (click)=\"host.toggleRunError(run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the body this failure came with\"\n >\n Error\n </button>\n } @else if (run.hasResponse) {\n <span class=\"et-query-devtools-count\">the only body held</span>\n } @else if (run.status === 'success' || run.error) {\n <span\n class=\"et-query-devtools-count\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so this run can no longer be an end of a diff\"\n >\n body no longer held\n </span>\n } @else {\n <span class=\"et-query-devtools-count\">\u2014</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (host.pickedRunError(s.entry); as failure) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Error body \u00B7 run #{{ failure.run.index }} \u00B7 {{ failure.error.code || 'no status' }}\n </h5>\n </div>\n @for (message of failure.error.messages; track message) {\n <p class=\"et-query-devtools-count\">{{ message }}</p>\n }\n <et-query-devtools-json\n [value]=\"failure.error.body\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"runError\"\n />\n }\n\n @if (host.responseDiff(s.entry); as comparison) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Response diff \u00B7 run #{{ comparison.before.index }} \u2192 #{{ comparison.after.index }}\n </h5>\n <span class=\"et-query-devtools-count\">\n @if (host.diffBaseRunIndex() === null) {\n <span\n title=\"Nothing is picked to compare against, so this is the nearest older run that still holds a body - click another run's Diff to pick one\"\n >\n nearest older\n </span>\n \u00B7\n }\n @if (comparison.diff.entries.length) {\n {{ comparison.diff.entries.length }} path{{ comparison.diff.entries.length === 1 ? '' : 's' }}\n @if (comparison.diff.truncated) {\n (capped)\n }\n } @else {\n identical\n }\n </span>\n </div>\n @if (comparison.diff.entries.length) {\n <table class=\"et-query-devtools-table et-query-devtools-diff\">\n <thead>\n <tr>\n <th>Path</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n @for (change of comparison.diff.entries; track change.path) {\n <tr [attr.data-kind]=\"change.kind\">\n <td class=\"et-query-devtools-mono\">{{ change.path }}</td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-before\">\n {{ change.kind === 'added' ? '\u2014' : host.inlineValue(change.before) }}\n </td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-after\">\n {{ change.kind === 'removed' ? '\u2014' : host.inlineValue(change.after) }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"et-query-devtools-empty\">The two responses are identical.</p>\n }\n }\n } @else {\n <p class=\"et-query-devtools-empty\">No runs recorded yet.</p>\n }\n }\n @case ('data') {\n @if (s.entry.meta.gqlQuery; as gqlQuery) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <button\n (click)=\"host.copyGqlDocument(gqlQuery)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy the GraphQL document\"\n >\n {{ host.copiedGql() ? '\u2713 Copied' : '\u29C9 Copy' }}\n </button>\n </div>\n <pre class=\"et-query-devtools-code\">{{ host.gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"host.jsonSearch()\"\n (input)=\"host.jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"host.queryArgs(s.query)\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"args\"\n />\n\n @if (s.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Response</h5>\n @if (s.entry.overrides?.list()?.length) {\n <button (click)=\"s.entry.overrides?.clearAll()\" class=\"et-query-devtools-btn\" type=\"button\">\n Reset all overrides ({{ s.entry.overrides?.list()?.length }})\n </button>\n }\n </div>\n <et-query-devtools-json\n [value]=\"s.query.response()\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n [overrides]=\"s.entry.overrides ?? null\"\n path=\"response\"\n />\n }\n }\n}\n", dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
49875
|
-
}
|
|
49876
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDetailComponent, decorators: [{
|
|
49877
|
-
type: Component,
|
|
49878
|
-
args: [{ selector: 'et-query-devtools-detail', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "@let s = sel();\n\n<div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ s.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(s.entry, s.query)\" />\n </span>\n @if (host.isTampered(s.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n @if (isGone()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">gone</span>\n }\n</div>\n\n@if (s.entry.destroyedAt; as destroyedAt) {\n <p class=\"et-query-devtools-gone-note\">\n Destroyed at {{ host.formatTime(destroyedAt) }}. This is the last state the query held - nothing here updates, and\n it cannot be run again.\n </p>\n}\n\n@if (host.requestProgress(s.query); as live) {\n <div class=\"et-query-devtools-live\">\n @if (live.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"The retry policy is backing off before it tries again. A query stuck loading with this chip is waiting, not slow.\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n attempt {{ retry.attempt }} in {{ host.formatCountdown(live.retryInMs) }}\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.retryCause(retry.status) }} \u00B7 backing off {{ host.formatDuration(retry.delayMs) }}\n </span>\n } @else if (live.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"How many HTTP attempts the last execution took - the retry policy fired for the rest\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ live.attempts }} attempts\n </span>\n }\n\n @if (live.progress; as progress) {\n <span\n [attr.aria-valuenow]=\"progress.percentage\"\n class=\"et-query-devtools-progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-label=\"Transfer progress\"\n >\n <span [style.inline-size.%]=\"progress.percentage\" class=\"et-query-devtools-progress-bar\"></span>\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.formatPercent(progress.percentage) }} \u00B7 {{ host.formatBytes(progress.loaded) }} of\n {{ host.formatBytes(progress.total) }}\n @if (progress.speed !== null) {\n \u00B7 {{ host.formatSpeed(progress.speed) }}\n }\n @if (progress.remainingTime !== null) {\n \u00B7 {{ host.formatDuration(progress.remainingTime) }} left\n }\n </span>\n }\n </div>\n}\n\n<div class=\"et-query-devtools-actions\">\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"host.executeQuery(s.query, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.executeQuery(s.query, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"host.resetQuery(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n }\n <button (click)=\"host.copyReport(s.entry, s.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ host.copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <button\n (click)=\"host.copyCurlRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as a curl command - the URL, the headers as the request resolved them, and the body\"\n >\n {{ host.copiedCurl() ? '\u2713 Copied' : 'cURL' }}\n </button>\n <button\n (click)=\"host.copyInsomniaRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as an Insomnia collection (Import \u2192 From Clipboard). Includes the request headers, and the token refresh for a secure query.\"\n >\n {{ host.copiedInsomnia() ? '\u2713 Copied' : 'Insomnia' }}\n </button>\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"host.openResponseEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"host.openArgsEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"host.forceLoading(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"host.forceError(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"host.forceEmpty(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"host.clearForced(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n }\n</div>\n\n@if (!isGone() && host.editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (host.editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"host.editorSeed\"\n (input)=\"host.responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyResponse(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"host.editorSeed\"\n (input)=\"host.argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyArgs(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (host.editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n}\n\n@let detailRuns = host.queryRuns(s.entry);\n<nav class=\"et-query-devtools-subtabs\" role=\"tablist\">\n @for (tab of detailTabs; track tab.id) {\n <button\n [class.et-query-devtools-subtab--active]=\"host.detailTab() === tab.id\"\n [attr.aria-selected]=\"host.detailTab() === tab.id\"\n (click)=\"host.detailTab.set(tab.id)\"\n class=\"et-query-devtools-subtab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (tab.id === 'history' && detailRuns.length) {\n <span class=\"et-query-devtools-tab-badge\">{{ detailRuns.length }}</span>\n }\n <!-- The error body lives under Data, so the tab has to say so - a failure must not hide\n behind a tab that is not open. -->\n @if (tab.id === 'data' && s.query.error()) {\n <span class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\">!</span>\n }\n </button>\n }\n</nav>\n\n@switch (host.detailTab()) {\n @case ('overview') {\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">\n {{ s.entry.meta.clientBaseUrl || s.entry.meta.clientName || '\u2014' }}\n </dd>\n <dt>Route</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.entry.meta.route || '\u2014' }}</dd>\n <dt>Request URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ host.requestUrl(s.query) || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ host.queryStatus(s.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ host.formatTime(s.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ s.query.triggeredBy() || 'user' }}</dd>\n @let refreshes = host.refreshesFor(s.entry.id);\n @if (refreshes.length) {\n <dt title=\"Invalidations and mutation refreshes that re-executed this query, as far back as the event log goes\">\n Refetched by\n </dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (refresh of refreshes.slice(0, 5); track refresh.id) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ host.formatTime(refresh.timestamp) }} \u00B7 {{ refresh.label }}\n </span>\n }\n @if (refreshes.length > 5) {\n <span class=\"et-query-devtools-hint\">+{{ refreshes.length - 5 }} earlier</span>\n }\n </div>\n </dd>\n }\n @let drivers = host.formsDrivingQuery(s.entry);\n @if (drivers.length) {\n <dt>Args from</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (driver of drivers; track driver.id) {\n <button\n (click)=\"host.selectForm(driver.id)\"\n class=\"et-query-devtools-chip et-query-devtools-chip--button\"\n type=\"button\"\n title=\"Open the query form in the Forms tab\"\n >\n {{ driver.meta.name }}\n </button>\n }\n </div>\n </dd>\n }\n @if (s.entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"s.entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @let activity = host.queryActivity(s.entry);\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Activity</h4>\n <button\n [disabled]=\"!activity.hasActivity\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the counters and the run history, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n\n <dl class=\"et-query-devtools-stats\">\n <div class=\"et-query-devtools-stat\" title=\"Every time the query ran, cache hits included\">\n <dt>Refreshes</dt>\n <dd>{{ activity.stats.executions }}</dd>\n @if (activity.cacheServed) {\n <span class=\"et-query-devtools-stat-sub\">{{ activity.cacheServed }} without a request</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\" title=\"Executions that started a request, and how they ended\">\n <dt>Requests</dt>\n <dd>{{ activity.stats.requests }}</dd>\n <span class=\"et-query-devtools-stat-sub\">\n {{ activity.stats.responses }} ok\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n </span>\n </div>\n <div\n class=\"et-query-devtools-stat\"\n title=\"Total response payload received. Sizes without a content-length header are measured from the decoded body, so they ignore compression.\"\n >\n <dt>Received</dt>\n <dd>{{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}</dd>\n @if (activity.avgResponseBytes !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatBytes(activity.avgResponseBytes) }} per response</span>\n }\n </div>\n @if (activity.stats.sentBytes) {\n <div class=\"et-query-devtools-stat\" title=\"Total request body sent (headers not counted)\">\n <dt>Sent</dt>\n <dd>{{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}</dd>\n </div>\n }\n @if (activity.stats.retries) {\n <div\n class=\"et-query-devtools-stat\"\n title=\"Attempts the retry policy added on top of the first one. Which run they belong to is under History.\"\n >\n <dt>Retries</dt>\n <dd>{{ activity.stats.retries }}</dd>\n </div>\n }\n <div class=\"et-query-devtools-stat\" title=\"Measured from the execution that preceded each response\">\n <dt>Duration</dt>\n <dd>{{ host.formatDuration(activity.stats.lastDurationMs) }}</dd>\n @if (activity.avgDurationMs !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatDuration(activity.avgDurationMs) }} on average</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\">\n <dt>Last response</dt>\n <dd class=\"et-query-devtools-stat-value--sm\">{{ host.formatTime(activity.stats.lastResponseAt) }}</dd>\n @if (activity.stats.firstExecutedAt !== null) {\n <span class=\"et-query-devtools-stat-sub\"\n >first ran {{ host.formatTime(activity.stats.firstExecutedAt) }}</span\n >\n }\n </div>\n </dl>\n }\n @case ('history') {\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Runs</h4>\n <button\n [disabled]=\"!detailRuns.length\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the run history and the counters, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n @if (detailRuns.length) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Run</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Received</th>\n <th>Body</th>\n </tr>\n </thead>\n <tbody>\n @for (run of detailRuns; track run.index) {\n <tr [attr.data-status]=\"run.status === 'error' ? 'error' : null\">\n <td>\n <span class=\"et-query-devtools-run-cell\">\n <span\n [attr.data-status]=\"host.runStatus(run)\"\n [title]=\"run.status\"\n class=\"et-query-devtools-status\"\n ></span>\n #{{ run.index }}\n @if (run.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Took {{\n run.attempts\n }} attempts - the duration next to it covers every one of them, backoff included\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ run.attempts }}\n </span>\n }\n @if (!run.didRequest) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Arrived without a request of this query's own - a poll, another consumer of the same cache entry, or another tab\"\n >\n shared\n </span>\n }\n @if (run.error; as error) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"{{ error.messages.join(' \u00B7 ') || 'The failure carried no message' }}\"\n >\n {{ error.code || 'failed' }}\n </span>\n }\n </span>\n </td>\n <td>{{ host.formatTime(run.startedAt) }}</td>\n <td>\n @if (run.endedAt === null) {\n in flight\n } @else {\n {{ host.formatDuration(run.endedAt - run.startedAt) }}\n }\n </td>\n <td>{{ run.receivedBytes ? host.formatBytes(run.receivedBytes) : '\u2014' }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n @if (host.canDiffRun(s.entry, run)) {\n @let role = host.diffRunRole(s.entry, run);\n @let armed = role ? diffRoles[role] : null;\n <button\n [class.et-query-devtools-btn--active]=\"!!armed\"\n [title]=\"\n armed?.title ?? 'Compare this response against another run - click a second row to pick which'\n \"\n (click)=\"host.toggleRunDiff(s.entry, run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n {{ armed?.label ?? 'Diff' }}\n </button>\n } @else if (run.error?.hasBody) {\n <button\n [class.et-query-devtools-btn--active]=\"host.errorRunIndex() === run.index\"\n (click)=\"host.toggleRunError(run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the body this failure came with\"\n >\n Error\n </button>\n } @else if (run.hasResponse) {\n <span class=\"et-query-devtools-count\">the only body held</span>\n } @else if (run.status === 'success' || run.error) {\n <span\n class=\"et-query-devtools-count\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so this run can no longer be an end of a diff\"\n >\n body no longer held\n </span>\n } @else {\n <span class=\"et-query-devtools-count\">\u2014</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n @if (host.pickedRunError(s.entry); as failure) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Error body \u00B7 run #{{ failure.run.index }} \u00B7 {{ failure.error.code || 'no status' }}\n </h5>\n </div>\n @for (message of failure.error.messages; track message) {\n <p class=\"et-query-devtools-count\">{{ message }}</p>\n }\n <et-query-devtools-json\n [value]=\"failure.error.body\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"runError\"\n />\n }\n\n @if (host.responseDiff(s.entry); as comparison) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Response diff \u00B7 run #{{ comparison.before.index }} \u2192 #{{ comparison.after.index }}\n </h5>\n <span class=\"et-query-devtools-count\">\n @if (host.diffBaseRunIndex() === null) {\n <span\n title=\"Nothing is picked to compare against, so this is the nearest older run that still holds a body - click another run's Diff to pick one\"\n >\n nearest older\n </span>\n \u00B7\n }\n @if (comparison.diff.entries.length) {\n {{ comparison.diff.entries.length }} path{{ comparison.diff.entries.length === 1 ? '' : 's' }}\n @if (comparison.diff.truncated) {\n (capped)\n }\n } @else {\n identical\n }\n </span>\n </div>\n @if (comparison.diff.entries.length) {\n <table class=\"et-query-devtools-table et-query-devtools-diff\">\n <thead>\n <tr>\n <th>Path</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n @for (change of comparison.diff.entries; track change.path) {\n <tr [attr.data-kind]=\"change.kind\">\n <td class=\"et-query-devtools-mono\">{{ change.path }}</td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-before\">\n {{ change.kind === 'added' ? '\u2014' : host.inlineValue(change.before) }}\n </td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-after\">\n {{ change.kind === 'removed' ? '\u2014' : host.inlineValue(change.after) }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"et-query-devtools-empty\">The two responses are identical.</p>\n }\n }\n } @else {\n <p class=\"et-query-devtools-empty\">No runs recorded yet.</p>\n }\n }\n @case ('data') {\n @if (s.entry.meta.gqlQuery; as gqlQuery) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <button\n (click)=\"host.copyGqlDocument(gqlQuery)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy the GraphQL document\"\n >\n {{ host.copiedGql() ? '\u2713 Copied' : '\u29C9 Copy' }}\n </button>\n </div>\n <pre class=\"et-query-devtools-code\">{{ host.gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"host.jsonSearch()\"\n (input)=\"host.jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"host.queryArgs(s.query)\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"args\"\n />\n\n @if (s.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Response</h5>\n @if (s.entry.overrides?.list()?.length) {\n <button (click)=\"s.entry.overrides?.clearAll()\" class=\"et-query-devtools-btn\" type=\"button\">\n Reset all overrides ({{ s.entry.overrides?.list()?.length }})\n </button>\n }\n </div>\n <et-query-devtools-json\n [value]=\"s.query.response()\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n [overrides]=\"s.entry.overrides ?? null\"\n path=\"response\"\n />\n }\n }\n}\n" }]
|
|
49879
|
-
}], propDecorators: { sel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sel", required: true }] }] } });
|
|
49880
|
-
|
|
49881
49904
|
/** Enough to describe what changed between two responses; past this the list stops being readable. */
|
|
49882
49905
|
const MAX_ENTRIES = 200;
|
|
49883
49906
|
/**
|
|
@@ -49995,29 +50018,6 @@ const diffQueryDevtoolsResponses = (before, after) => {
|
|
|
49995
50018
|
return acc;
|
|
49996
50019
|
};
|
|
49997
50020
|
|
|
49998
|
-
/**
|
|
49999
|
-
* The split-view drawer every two-pane tab (stacks/sequences/forms/timeline) opens a query in - the
|
|
50000
|
-
* resize handle, the `<aside>` chrome and the close button around a `<et-query-devtools-detail>`. The
|
|
50001
|
-
* Queries tab renders that same detail component inline instead, without this wrapper, since it has no
|
|
50002
|
-
* separate list/drawer split to close.
|
|
50003
|
-
*/
|
|
50004
|
-
class QueryDevtoolsDrawerComponent {
|
|
50005
|
-
constructor() {
|
|
50006
|
-
this.host = injectQueryDevtoolsHost();
|
|
50007
|
-
this.sel = input(null, /* @ts-ignore */
|
|
50008
|
-
...(ngDevMode ? [{ debugName: "sel" }] : /* istanbul ignore next */ []));
|
|
50009
|
-
this.container = input.required(/* @ts-ignore */
|
|
50010
|
-
...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
|
|
50011
|
-
this.dismiss = output();
|
|
50012
|
-
}
|
|
50013
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50014
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsDrawerComponent, isStandalone: true, selector: "et-query-devtools-drawer", inputs: { sel: { classPropertyName: "sel", publicName: "sel", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: "@if (sel(); as selected) {\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'drawer', container: container() })\"\n (dblclick)=\"host.resetPaneSize('drawer')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button (click)=\"dismiss.emit()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close detail\">\u2715</button>\n </div>\n <et-query-devtools-detail [sel]=\"selected\" />\n </aside>\n}\n", dependencies: [{ kind: "component", type: QueryDevtoolsDetailComponent, selector: "et-query-devtools-detail", inputs: ["sel"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50015
|
-
}
|
|
50016
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDrawerComponent, decorators: [{
|
|
50017
|
-
type: Component,
|
|
50018
|
-
args: [{ selector: 'et-query-devtools-drawer', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDetailComponent], template: "@if (sel(); as selected) {\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'drawer', container: container() })\"\n (dblclick)=\"host.resetPaneSize('drawer')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button (click)=\"dismiss.emit()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close detail\">\u2715</button>\n </div>\n <et-query-devtools-detail [sel]=\"selected\" />\n </aside>\n}\n" }]
|
|
50019
|
-
}], propDecorators: { sel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sel", required: false }] }], container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
|
|
50020
|
-
|
|
50021
50021
|
/** The Faults tab: arms latency/failure injection per client - in-memory only, not persisted. */
|
|
50022
50022
|
class QueryDevtoolsFaultsTabComponent {
|
|
50023
50023
|
constructor() {
|
|
@@ -50048,24 +50048,140 @@ class QueryDevtoolsFaultsTabComponent {
|
|
|
50048
50048
|
return QUERY_DEVTOOLS_FAULT_STATUSES.find((entry) => entry.status === status)?.retryable ?? false;
|
|
50049
50049
|
}
|
|
50050
50050
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsFaultsTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50051
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsFaultsTabComponent, isStandalone: true, selector: "et-query-devtools-faults-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <p class=\"et-query-devtools-hint\">\n Faults are injected into the request pipeline, so retries, error handling features and the cache see them exactly\n as they would see a real one. Unlike the rest of the panel, what you arm here is not persisted - a page reload\n disarms every client.\n </p>\n </div>\n\n @for (client of host.faultClients(); track client.name) {\n @let fault = client.fault;\n <div [class.et-query-devtools-card--armed]=\"client.armed\" class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.name }}</strong>\n <span class=\"et-query-devtools-url\">{{ client.baseUrl }}</span>\n @if (client.armed) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">armed</span>\n <button (click)=\"CLEAR_FAULTS(client.name)\" class=\"et-query-devtools-btn\" type=\"button\">Disarm</button>\n }\n </div>\n\n <div class=\"et-query-devtools-faults\">\n <label class=\"et-query-devtools-field\">\n <span>Latency</span>\n <input\n #latencyInput\n [value]=\"fault.latencyMs\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'latencyMs', value: latencyInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"60000\"\n step=\"100\"\n />\n <small>ms before every attempt starts</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail next</span>\n <input\n #failNextInput\n [value]=\"fault.failNext\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failNext', value: failNextInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"99\"\n step=\"1\"\n />\n <small>attempts, counted down as they are spent</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail rate</span>\n <input\n #failRateInput\n [value]=\"fault.failRate\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failRate', value: failRateInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"5\"\n />\n <small>% of attempts, rolled per attempt</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Status</span>\n <select\n #statusSelect\n (change)=\"armFaultStatus({ clientName: client.name, value: statusSelect.value })\"\n class=\"et-query-devtools-select\"\n >\n @for (option of FAULT_STATUSES; track option.status) {\n <!-- `selected` on the option, not `value` on the select: the select's value is\n applied before its options exist, so it would fall back to the first one. -->\n <option [value]=\"option.status\" [selected]=\"option.status === fault.status\">\n {{ option.status }} \u00B7 {{ option.label }}\n </option>\n }\n </select>\n <small>\n @if (isFaultStatusRetryable(fault.status)) {\n the default retry policy retries this\n } @else {\n the default retry policy gives up on this\n }\n </small>\n </label>\n </div>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No query clients registered yet.</p>\n }\n</div>\n", encapsulation: i0.ViewEncapsulation.None }); }
|
|
50051
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsFaultsTabComponent, isStandalone: true, selector: "et-query-devtools-faults-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <p class=\"et-query-devtools-hint\">\n Faults are injected into the request pipeline, so retries, error handling features and the cache see them exactly\n as they would see a real one. Unlike the rest of the panel, what you arm here is not persisted - a page reload\n disarms every client.\n </p>\n </div>\n\n @for (client of host.faultClients(); track client.name) {\n @let fault = client.fault;\n <div [class.et-query-devtools-card--armed]=\"client.armed\" class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.name }}</strong>\n <span class=\"et-query-devtools-url\">{{ client.baseUrl }}</span>\n @if (client.armed) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">armed</span>\n <button (click)=\"CLEAR_FAULTS(client.name)\" class=\"et-query-devtools-btn\" type=\"button\">Disarm</button>\n }\n </div>\n\n <div class=\"et-query-devtools-faults\">\n <label class=\"et-query-devtools-field\">\n <span>Latency</span>\n <input\n #latencyInput\n [value]=\"fault.latencyMs\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'latencyMs', value: latencyInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"60000\"\n step=\"100\"\n />\n <small>ms before every attempt starts</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail next</span>\n <input\n #failNextInput\n [value]=\"fault.failNext\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failNext', value: failNextInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"99\"\n step=\"1\"\n />\n <small>attempts, counted down as they are spent</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail rate</span>\n <input\n #failRateInput\n [value]=\"fault.failRate\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failRate', value: failRateInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"5\"\n />\n <small>% of attempts, rolled per attempt</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Status</span>\n <select\n #statusSelect\n (change)=\"armFaultStatus({ clientName: client.name, value: statusSelect.value })\"\n class=\"et-query-devtools-select\"\n >\n @for (option of FAULT_STATUSES; track option.status) {\n <!-- `selected` on the option, not `value` on the select: the select's value is\n applied before its options exist, so it would fall back to the first one. -->\n <option [value]=\"option.status\" [selected]=\"option.status === fault.status\">\n {{ option.status }} \u00B7 {{ option.label }}\n </option>\n }\n </select>\n <small>\n @if (isFaultStatusRetryable(fault.status)) {\n the default retry policy retries this\n } @else {\n the default retry policy gives up on this\n }\n </small>\n </label>\n </div>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No query clients registered yet.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-card--armed{border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-error) 6%,transparent)}.et-query-devtools-faults{display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:.8rem 1.6rem}.et-query-devtools-faults .et-query-devtools-field{display:grid;grid-template-columns:8rem minmax(0,1fr);align-items:baseline;row-gap:.2rem;color:var(--_et-qdt-fg)}.et-query-devtools-faults .et-query-devtools-field small{grid-column:2;color:var(--_et-qdt-subtle);font-size:1.1rem}.et-query-devtools-input--number{inline-size:8rem;font-variant-numeric:tabular-nums}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50052
50052
|
}
|
|
50053
50053
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsFaultsTabComponent, decorators: [{
|
|
50054
50054
|
type: Component,
|
|
50055
|
-
args: [{ selector: 'et-query-devtools-faults-tab', encapsulation: ViewEncapsulation.None, template: "<div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <p class=\"et-query-devtools-hint\">\n Faults are injected into the request pipeline, so retries, error handling features and the cache see them exactly\n as they would see a real one. Unlike the rest of the panel, what you arm here is not persisted - a page reload\n disarms every client.\n </p>\n </div>\n\n @for (client of host.faultClients(); track client.name) {\n @let fault = client.fault;\n <div [class.et-query-devtools-card--armed]=\"client.armed\" class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.name }}</strong>\n <span class=\"et-query-devtools-url\">{{ client.baseUrl }}</span>\n @if (client.armed) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">armed</span>\n <button (click)=\"CLEAR_FAULTS(client.name)\" class=\"et-query-devtools-btn\" type=\"button\">Disarm</button>\n }\n </div>\n\n <div class=\"et-query-devtools-faults\">\n <label class=\"et-query-devtools-field\">\n <span>Latency</span>\n <input\n #latencyInput\n [value]=\"fault.latencyMs\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'latencyMs', value: latencyInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"60000\"\n step=\"100\"\n />\n <small>ms before every attempt starts</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail next</span>\n <input\n #failNextInput\n [value]=\"fault.failNext\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failNext', value: failNextInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"99\"\n step=\"1\"\n />\n <small>attempts, counted down as they are spent</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail rate</span>\n <input\n #failRateInput\n [value]=\"fault.failRate\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failRate', value: failRateInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"5\"\n />\n <small>% of attempts, rolled per attempt</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Status</span>\n <select\n #statusSelect\n (change)=\"armFaultStatus({ clientName: client.name, value: statusSelect.value })\"\n class=\"et-query-devtools-select\"\n >\n @for (option of FAULT_STATUSES; track option.status) {\n <!-- `selected` on the option, not `value` on the select: the select's value is\n applied before its options exist, so it would fall back to the first one. -->\n <option [value]=\"option.status\" [selected]=\"option.status === fault.status\">\n {{ option.status }} \u00B7 {{ option.label }}\n </option>\n }\n </select>\n <small>\n @if (isFaultStatusRetryable(fault.status)) {\n the default retry policy retries this\n } @else {\n the default retry policy gives up on this\n }\n </small>\n </label>\n </div>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No query clients registered yet.</p>\n }\n</div>\n" }]
|
|
50055
|
+
args: [{ selector: 'et-query-devtools-faults-tab', encapsulation: ViewEncapsulation.None, template: "<div class=\"et-query-devtools-scroll\">\n <div class=\"et-query-devtools-toolbar\">\n <p class=\"et-query-devtools-hint\">\n Faults are injected into the request pipeline, so retries, error handling features and the cache see them exactly\n as they would see a real one. Unlike the rest of the panel, what you arm here is not persisted - a page reload\n disarms every client.\n </p>\n </div>\n\n @for (client of host.faultClients(); track client.name) {\n @let fault = client.fault;\n <div [class.et-query-devtools-card--armed]=\"client.armed\" class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong class=\"et-query-devtools-mono\">{{ client.name }}</strong>\n <span class=\"et-query-devtools-url\">{{ client.baseUrl }}</span>\n @if (client.armed) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">armed</span>\n <button (click)=\"CLEAR_FAULTS(client.name)\" class=\"et-query-devtools-btn\" type=\"button\">Disarm</button>\n }\n </div>\n\n <div class=\"et-query-devtools-faults\">\n <label class=\"et-query-devtools-field\">\n <span>Latency</span>\n <input\n #latencyInput\n [value]=\"fault.latencyMs\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'latencyMs', value: latencyInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"60000\"\n step=\"100\"\n />\n <small>ms before every attempt starts</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail next</span>\n <input\n #failNextInput\n [value]=\"fault.failNext\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failNext', value: failNextInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"99\"\n step=\"1\"\n />\n <small>attempts, counted down as they are spent</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Fail rate</span>\n <input\n #failRateInput\n [value]=\"fault.failRate\"\n (change)=\"armFaultValue({ clientName: client.name, field: 'failRate', value: failRateInput.value })\"\n class=\"et-query-devtools-input et-query-devtools-input--number\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n step=\"5\"\n />\n <small>% of attempts, rolled per attempt</small>\n </label>\n\n <label class=\"et-query-devtools-field\">\n <span>Status</span>\n <select\n #statusSelect\n (change)=\"armFaultStatus({ clientName: client.name, value: statusSelect.value })\"\n class=\"et-query-devtools-select\"\n >\n @for (option of FAULT_STATUSES; track option.status) {\n <!-- `selected` on the option, not `value` on the select: the select's value is\n applied before its options exist, so it would fall back to the first one. -->\n <option [value]=\"option.status\" [selected]=\"option.status === fault.status\">\n {{ option.status }} \u00B7 {{ option.label }}\n </option>\n }\n </select>\n <small>\n @if (isFaultStatusRetryable(fault.status)) {\n the default retry policy retries this\n } @else {\n the default retry policy gives up on this\n }\n </small>\n </label>\n </div>\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No query clients registered yet.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-card--armed{border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-error) 6%,transparent)}.et-query-devtools-faults{display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:.8rem 1.6rem}.et-query-devtools-faults .et-query-devtools-field{display:grid;grid-template-columns:8rem minmax(0,1fr);align-items:baseline;row-gap:.2rem;color:var(--_et-qdt-fg)}.et-query-devtools-faults .et-query-devtools-field small{grid-column:2;color:var(--_et-qdt-subtle);font-size:1.1rem}.et-query-devtools-input--number{inline-size:8rem;font-variant-numeric:tabular-nums}}\n"] }]
|
|
50056
50056
|
}] });
|
|
50057
50057
|
|
|
50058
|
+
/**
|
|
50059
|
+
* A route with its path params and query string picked out from the static path. The segments render
|
|
50060
|
+
* element-only: a text node between them would render as a space inside the route.
|
|
50061
|
+
*/
|
|
50062
|
+
class QueryDevtoolsRouteComponent {
|
|
50063
|
+
constructor() {
|
|
50064
|
+
this.segments = input.required(/* @ts-ignore */
|
|
50065
|
+
...(ngDevMode ? [{ debugName: "segments" }] : /* istanbul ignore next */ []));
|
|
50066
|
+
this.fallback = input('—', /* @ts-ignore */
|
|
50067
|
+
...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
|
|
50068
|
+
}
|
|
50069
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsRouteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50070
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsRouteComponent, isStandalone: true, selector: "et-query-devtools-route", inputs: { segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: true, transformFunction: null }, fallback: { classPropertyName: "fallback", publicName: "fallback", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
50071
|
+
@for (segment of segments(); track $index) {
|
|
50072
|
+
<span [class]="'et-query-devtools-route-' + segment.kind" [attr.title]="segment.name">{{ segment.text }}</span>
|
|
50073
|
+
} @empty {
|
|
50074
|
+
{{ fallback() }}
|
|
50075
|
+
}
|
|
50076
|
+
`, isInline: true, styles: ["@layer components{.et-query-devtools-route-param{color:var(--_et-qdt-accent)}.et-query-devtools-route-query{color:var(--_et-qdt-muted)}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50077
|
+
}
|
|
50078
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsRouteComponent, decorators: [{
|
|
50079
|
+
type: Component,
|
|
50080
|
+
args: [{ selector: 'et-query-devtools-route', template: `
|
|
50081
|
+
@for (segment of segments(); track $index) {
|
|
50082
|
+
<span [class]="'et-query-devtools-route-' + segment.kind" [attr.title]="segment.name">{{ segment.text }}</span>
|
|
50083
|
+
} @empty {
|
|
50084
|
+
{{ fallback() }}
|
|
50085
|
+
}
|
|
50086
|
+
`, encapsulation: ViewEncapsulation.None, styles: ["@layer components{.et-query-devtools-route-param{color:var(--_et-qdt-accent)}.et-query-devtools-route-query{color:var(--_et-qdt-muted)}}\n"] }]
|
|
50087
|
+
}], propDecorators: { segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: true }] }], fallback: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallback", required: false }] }] } });
|
|
50088
|
+
|
|
50089
|
+
/**
|
|
50090
|
+
* The query detail: head, live progress, run/edit/force actions and the overview/history/data
|
|
50091
|
+
* sub-tabs. Rendered inline by the Queries tab and wrapped in `<et-query-devtools-drawer>` by every
|
|
50092
|
+
* other tab's split view - both read/write the same {@link QueryDevtoolsHost.detailTab} and JIT editor
|
|
50093
|
+
* state, so switching sub-tab in one instance is switching it everywhere, exactly as when this was one
|
|
50094
|
+
* component holding everything.
|
|
50095
|
+
*/
|
|
50096
|
+
class QueryDevtoolsDetailComponent {
|
|
50097
|
+
constructor() {
|
|
50098
|
+
this.host = injectQueryDevtoolsHost();
|
|
50099
|
+
this.sel = input.required(/* @ts-ignore */
|
|
50100
|
+
...(ngDevMode ? [{ debugName: "sel" }] : /* istanbul ignore next */ []));
|
|
50101
|
+
/**
|
|
50102
|
+
* Whether this is a tombstone. Everything that would run, edit or force the query is hidden for one -
|
|
50103
|
+
* its handle is a frozen snapshot, so those actions have nothing to act on.
|
|
50104
|
+
*/
|
|
50105
|
+
this.isGone = computed(() => !!this.sel().entry.destroyedAt, /* @ts-ignore */
|
|
50106
|
+
...(ngDevMode ? [{ debugName: "isGone" }] : /* istanbul ignore next */ []));
|
|
50107
|
+
this.detailTabs = [
|
|
50108
|
+
{ id: 'overview', label: 'Overview' },
|
|
50109
|
+
{ id: 'history', label: 'History' },
|
|
50110
|
+
{ id: 'data', label: 'Data' },
|
|
50111
|
+
];
|
|
50112
|
+
/** Whether the tail of runs that can no longer be diffed is unfolded. */
|
|
50113
|
+
this.foldedRunsOpen = signal(false, /* @ts-ignore */
|
|
50114
|
+
...(ngDevMode ? [{ debugName: "foldedRunsOpen" }] : /* istanbul ignore next */ []));
|
|
50115
|
+
/**
|
|
50116
|
+
* The runs split at the last one that still holds a body. Only the newest few can ever be an end of a
|
|
50117
|
+
* diff (`setQueryDevtoolsResponseHistory`, five by default) while the run log keeps twenty-five, so
|
|
50118
|
+
* without this the diff sits under twenty rows reading `body no longer held` and the pair and its
|
|
50119
|
+
* result never fit on one screen.
|
|
50120
|
+
*
|
|
50121
|
+
* Split, not filtered: a dead row *between* two live ones stays where it is, so the log keeps its order.
|
|
50122
|
+
*/
|
|
50123
|
+
this.runSections = computed(() => {
|
|
50124
|
+
const runs = this.host.queryRuns(this.sel().entry);
|
|
50125
|
+
const isActionable = (run) => run.hasResponse || !!run.error?.hasBody;
|
|
50126
|
+
let lastActionable = -1;
|
|
50127
|
+
runs.forEach((run, index) => {
|
|
50128
|
+
if (isActionable(run))
|
|
50129
|
+
lastActionable = index;
|
|
50130
|
+
});
|
|
50131
|
+
return { listed: runs.slice(0, lastActionable + 1), folded: runs.slice(lastActionable + 1) };
|
|
50132
|
+
}, /* @ts-ignore */
|
|
50133
|
+
...(ngDevMode ? [{ debugName: "runSections" }] : /* istanbul ignore next */ []));
|
|
50134
|
+
/** What a run's Diff button reads as at each end of the comparison. */
|
|
50135
|
+
this.diffRoles = {
|
|
50136
|
+
base: {
|
|
50137
|
+
label: 'Base',
|
|
50138
|
+
title: 'The older end of the comparison - click another run to set the newer one, or this one to clear it',
|
|
50139
|
+
},
|
|
50140
|
+
compare: { label: 'Compare', title: 'The newer end of the comparison - click to clear it' },
|
|
50141
|
+
};
|
|
50142
|
+
}
|
|
50143
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50144
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsDetailComponent, isStandalone: true, selector: "et-query-devtools-detail", inputs: { sel: { classPropertyName: "sel", publicName: "sel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let s = sel();\n\n<div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ s.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(s.entry, s.query)\" />\n </span>\n <button\n [attr.aria-label]=\"host.copyableRouteTitle(s.entry, s.query)\"\n [title]=\"host.copyableRouteTitle(s.entry, s.query)\"\n [class.et-query-devtools-route-copy--copied]=\"host.copiedRoute()\"\n (click)=\"host.copyRoute(s.entry, s.query)\"\n class=\"et-query-devtools-route-copy\"\n type=\"button\"\n >\n {{ host.copiedRoute() ? '\u2713' : '\u29C9' }}\n </button>\n @if (host.isTampered(s.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n @if (isGone()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">gone</span>\n }\n</div>\n\n@if (s.entry.destroyedAt; as destroyedAt) {\n <p class=\"et-query-devtools-gone-note\">\n Destroyed at {{ host.formatTime(destroyedAt) }}. This is the last state the query held - nothing here updates, and\n it cannot be run again.\n </p>\n}\n\n@if (host.requestProgress(s.query); as live) {\n <div class=\"et-query-devtools-live\">\n @if (live.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"The retry policy is backing off before it tries again. A query stuck loading with this chip is waiting, not slow.\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n attempt {{ retry.attempt }} in {{ host.formatCountdown(live.retryInMs) }}\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.retryCause(retry.status) }} \u00B7 backing off {{ host.formatDuration(retry.delayMs) }}\n </span>\n } @else if (live.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"How many HTTP attempts the last execution took - the retry policy fired for the rest\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ live.attempts }} attempts\n </span>\n }\n\n @if (live.progress; as progress) {\n <span\n [attr.aria-valuenow]=\"progress.percentage\"\n class=\"et-query-devtools-progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-label=\"Transfer progress\"\n >\n <span [style.inline-size.%]=\"progress.percentage\" class=\"et-query-devtools-progress-bar\"></span>\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.formatPercent(progress.percentage) }} \u00B7 {{ host.formatBytes(progress.loaded) }} of\n {{ host.formatBytes(progress.total) }}\n @if (progress.speed !== null) {\n \u00B7 {{ host.formatSpeed(progress.speed) }}\n }\n @if (progress.remainingTime !== null) {\n \u00B7 {{ host.formatDuration(progress.remainingTime) }} left\n }\n </span>\n }\n </div>\n}\n\n<div class=\"et-query-devtools-actions\">\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"host.executeQuery(s, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.executeQuery(s, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"host.resetQuery(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n }\n @let locatable = host.locatableElement(s.entry);\n <button\n [disabled]=\"!locatable\"\n [title]=\"\n locatable\n ? 'Scroll to and outline the element this query was created in. That is where it was created, not necessarily where its data is rendered.'\n : 'This query was created outside a component or directive - a root service, a resolver or a guard - so it has no element to point at.'\n \"\n (click)=\"host.locateQuery(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n @switch (host.locateState()) {\n @case ('located') {\n \u2316 Created here\n }\n @case ('offscreen') {\n \u2316 Not on screen\n }\n @default {\n \u2316 Locate\n }\n }\n </button>\n <button (click)=\"host.copyReport(s.entry, s.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ host.copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <button\n (click)=\"host.copyCurlRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as a curl command - the URL, the headers as the request resolved them, and the body\"\n >\n {{ host.copiedCurl() ? '\u2713 Copied' : 'cURL' }}\n </button>\n <button\n (click)=\"host.copyInsomniaRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as an Insomnia collection (Import \u2192 From Clipboard). Includes the request headers, and the token refresh for a secure query.\"\n >\n {{ host.copiedInsomnia() ? '\u2713 Copied' : 'Insomnia' }}\n </button>\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"host.openResponseEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"host.openArgsEditor(s)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"host.forceLoading(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"host.forceError(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"host.forceEmpty(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"host.clearForced(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n }\n</div>\n\n@if (!isGone() && host.editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (host.editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"host.editorSeed\"\n (input)=\"host.responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyResponse(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"host.editorSeed\"\n (input)=\"host.argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyArgs(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (host.editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n}\n\n@let detailRuns = host.queryRuns(s.entry);\n<nav class=\"et-query-devtools-subtabs\" role=\"tablist\">\n @for (tab of detailTabs; track tab.id) {\n <button\n [class.et-query-devtools-subtab--active]=\"host.detailTab() === tab.id\"\n [attr.aria-selected]=\"host.detailTab() === tab.id\"\n (click)=\"host.detailTab.set(tab.id)\"\n class=\"et-query-devtools-subtab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (tab.id === 'history' && detailRuns.length) {\n <span class=\"et-query-devtools-tab-badge\">{{ detailRuns.length }}</span>\n }\n <!-- The error body lives under Data, so the tab has to say so - a failure must not hide\n behind a tab that is not open. -->\n @if (tab.id === 'data' && s.query.error()) {\n <span class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\">!</span>\n }\n </button>\n }\n</nav>\n\n@switch (host.detailTab()) {\n @case ('overview') {\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">\n {{ s.entry.meta.clientBaseUrl || s.entry.meta.clientName || '\u2014' }}\n </dd>\n <dt>Route</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.entry.meta.route || '\u2014' }}</dd>\n <dt>Request URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ host.requestUrl(s.query) || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ host.queryStatus(s.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ host.formatTime(s.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ s.query.triggeredBy() || 'user' }}</dd>\n @let refreshes = host.refreshesFor(s.entry.id);\n @if (refreshes.length) {\n <dt title=\"Invalidations and mutation refreshes that re-executed this query, as far back as the event log goes\">\n Refetched by\n </dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (refresh of refreshes.slice(0, 5); track refresh.id) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ host.formatTime(refresh.timestamp) }} \u00B7 {{ refresh.label }}\n </span>\n }\n @if (refreshes.length > 5) {\n <span class=\"et-query-devtools-hint\">+{{ refreshes.length - 5 }} earlier</span>\n }\n </div>\n </dd>\n }\n @let drivers = host.formsDrivingQuery(s.entry);\n @if (drivers.length) {\n <dt>Args from</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (driver of drivers; track driver.id) {\n <button\n (click)=\"host.selectForm(driver.id)\"\n class=\"et-query-devtools-chip et-query-devtools-chip--button\"\n type=\"button\"\n title=\"Open the query form in the Forms tab\"\n >\n {{ driver.meta.name }}\n </button>\n }\n </div>\n </dd>\n }\n @if (s.entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"s.entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @let activity = host.queryActivity(s.entry);\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Activity</h4>\n <button\n [disabled]=\"!activity.hasActivity\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the counters and the run history, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n\n <dl class=\"et-query-devtools-stats\">\n <div class=\"et-query-devtools-stat\" title=\"Every time the query ran, cache hits included\">\n <dt>Refreshes</dt>\n <dd>{{ activity.stats.executions }}</dd>\n @if (activity.cacheServed) {\n <span class=\"et-query-devtools-stat-sub\">{{ activity.cacheServed }} without a request</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\" title=\"Executions that started a request, and how they ended\">\n <dt>Requests</dt>\n <dd>{{ activity.stats.requests }}</dd>\n <span class=\"et-query-devtools-stat-sub\">\n {{ activity.stats.responses }} ok\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n </span>\n </div>\n <div\n class=\"et-query-devtools-stat\"\n title=\"Total response payload received. Sizes without a content-length header are measured from the decoded body, so they ignore compression.\"\n >\n <dt>Received</dt>\n <dd>{{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}</dd>\n @if (activity.avgResponseBytes !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatBytes(activity.avgResponseBytes) }} per response</span>\n }\n </div>\n @if (activity.stats.sentBytes) {\n <div class=\"et-query-devtools-stat\" title=\"Total request body sent (headers not counted)\">\n <dt>Sent</dt>\n <dd>{{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}</dd>\n </div>\n }\n @if (activity.stats.retries) {\n <div\n class=\"et-query-devtools-stat\"\n title=\"Attempts the retry policy added on top of the first one. Which run they belong to is under History.\"\n >\n <dt>Retries</dt>\n <dd>{{ activity.stats.retries }}</dd>\n </div>\n }\n <div class=\"et-query-devtools-stat\" title=\"Measured from the execution that preceded each response\">\n <dt>Duration</dt>\n <dd>{{ host.formatDuration(activity.stats.lastDurationMs) }}</dd>\n @if (activity.avgDurationMs !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatDuration(activity.avgDurationMs) }} on average</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\">\n <dt>Last response</dt>\n <dd class=\"et-query-devtools-stat-value--sm\">{{ host.formatTime(activity.stats.lastResponseAt) }}</dd>\n @if (activity.stats.firstExecutedAt !== null) {\n <span class=\"et-query-devtools-stat-sub\"\n >first ran {{ host.formatTime(activity.stats.firstExecutedAt) }}</span\n >\n }\n </div>\n </dl>\n }\n @case ('history') {\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Runs</h4>\n <button\n [disabled]=\"!detailRuns.length\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the run history and the counters, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n @if (detailRuns.length) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Run</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Received</th>\n <th>Body</th>\n </tr>\n </thead>\n <tbody>\n @for (run of runSections().listed.concat(foldedRunsOpen() ? runSections().folded : []); track run.index) {\n <tr [attr.data-status]=\"run.status === 'error' ? 'error' : null\">\n <td>\n <span class=\"et-query-devtools-run-cell\">\n <span\n [attr.data-status]=\"host.runStatus(run)\"\n [title]=\"run.status\"\n class=\"et-query-devtools-status\"\n ></span>\n #{{ run.index }}\n @if (run.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Took {{\n run.attempts\n }} attempts - the duration next to it covers every one of them, backoff included\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ run.attempts }}\n </span>\n }\n @if (!run.didRequest) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Arrived without a request of this query's own - a poll, another consumer of the same cache entry, or another tab\"\n >\n shared\n </span>\n }\n @if (run.error; as error) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"{{ error.messages.join(' \u00B7 ') || 'The failure carried no message' }}\"\n >\n {{ error.code || 'failed' }}\n </span>\n }\n </span>\n </td>\n <td>{{ host.formatTime(run.startedAt) }}</td>\n <td>\n @if (run.endedAt === null) {\n in flight\n } @else {\n {{ host.formatDuration(run.endedAt - run.startedAt) }}\n }\n </td>\n <td>{{ run.receivedBytes ? host.formatBytes(run.receivedBytes) : '\u2014' }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n @if (host.canDiffRun(s.entry, run)) {\n @let role = host.diffRunRole(s.entry, run);\n @let armed = role ? diffRoles[role] : null;\n <button\n [class.et-query-devtools-btn--active]=\"!!armed\"\n [title]=\"\n armed?.title ?? 'Compare this response against another run - click a second row to pick which'\n \"\n (click)=\"host.toggleRunDiff(s.entry, run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n {{ armed?.label ?? 'Diff' }}\n </button>\n } @else if (run.error?.hasBody) {\n <button\n [class.et-query-devtools-btn--active]=\"host.errorRunIndex() === run.index\"\n (click)=\"host.toggleRunError(run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the body this failure came with\"\n >\n Error\n </button>\n } @else if (run.hasResponse) {\n <span class=\"et-query-devtools-count\">the only body held</span>\n } @else if (run.status === 'success' || run.error) {\n <span\n class=\"et-query-devtools-count\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so this run can no longer be an end of a diff\"\n >\n body no longer held\n </span>\n } @else {\n <span class=\"et-query-devtools-count\">\u2014</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @let foldedRuns = runSections().folded.length;\n @if (foldedRuns) {\n <button\n [attr.aria-expanded]=\"foldedRunsOpen()\"\n (click)=\"foldedRunsOpen.set(!foldedRunsOpen())\"\n class=\"et-query-devtools-btn et-query-devtools-runs-fold\"\n type=\"button\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so none of these older runs can be an end of a diff\"\n >\n <span aria-hidden=\"true\">{{ foldedRunsOpen() ? '\u25BE' : '\u25B8' }}</span>\n {{ foldedRunsOpen() ? 'Hide' : 'Show' }} {{ foldedRuns }} older run{{ foldedRuns === 1 ? '' : 's' }} with no\n body\n </button>\n }\n\n @if (host.pickedRunError(s.entry); as failure) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Error body \u00B7 run #{{ failure.run.index }} \u00B7 {{ failure.error.code || 'no status' }}\n </h5>\n </div>\n @for (message of failure.error.messages; track message) {\n <p class=\"et-query-devtools-count\">{{ message }}</p>\n }\n <et-query-devtools-json\n [value]=\"failure.error.body\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"runError\"\n />\n }\n\n @if (host.responseDiff(s.entry); as comparison) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Response diff \u00B7 run #{{ comparison.before.index }} \u2192 #{{ comparison.after.index }}\n </h5>\n <span class=\"et-query-devtools-diff-step\">\n <button\n [disabled]=\"!host.canStepRunDiff(s.entry, true)\"\n (click)=\"host.stepRunDiff(s.entry, true)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Compare the pair one run older, without going back to the table\"\n >\n \u25C2 Older\n </button>\n <button\n [disabled]=\"!host.canStepRunDiff(s.entry, false)\"\n (click)=\"host.stepRunDiff(s.entry, false)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Compare the pair one run newer, without going back to the table\"\n >\n Newer \u25B8\n </button>\n </span>\n <span class=\"et-query-devtools-count\">\n @if (host.diffBaseRunIndex() === null) {\n <span\n title=\"Nothing is picked to compare against, so this is the nearest older run that still holds a body - click another run's Diff to pick one\"\n >\n nearest older\n </span>\n \u00B7\n }\n @if (comparison.diff.entries.length) {\n {{ comparison.diff.entries.length }} path{{ comparison.diff.entries.length === 1 ? '' : 's' }}\n @if (comparison.diff.truncated) {\n (capped)\n }\n } @else {\n identical\n }\n </span>\n </div>\n @if (comparison.diff.entries.length) {\n <table class=\"et-query-devtools-table et-query-devtools-diff\">\n <thead>\n <tr>\n <th>Path</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n @for (change of comparison.diff.entries; track change.path) {\n <tr [attr.data-kind]=\"change.kind\">\n <td class=\"et-query-devtools-mono\">{{ change.path }}</td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-before\">\n {{ change.kind === 'added' ? '\u2014' : host.inlineValue(change.before) }}\n </td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-after\">\n {{ change.kind === 'removed' ? '\u2014' : host.inlineValue(change.after) }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"et-query-devtools-empty\">The two responses are identical.</p>\n }\n }\n } @else {\n <p class=\"et-query-devtools-empty\">No runs recorded yet.</p>\n }\n }\n @case ('data') {\n @if (s.entry.meta.gqlQuery; as gqlQuery) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <button\n (click)=\"host.copyGqlDocument(gqlQuery)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy the GraphQL document\"\n >\n {{ host.copiedGql() ? '\u2713 Copied' : '\u29C9 Copy' }}\n </button>\n </div>\n <pre class=\"et-query-devtools-code\">{{ host.gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"host.jsonSearch()\"\n (input)=\"host.jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"host.queryArgs(s.query)\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"args\"\n />\n\n @if (s.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Response</h5>\n @if (s.entry.overrides?.list()?.length) {\n <button (click)=\"s.entry.overrides?.clearAll()\" class=\"et-query-devtools-btn\" type=\"button\">\n Reset all overrides ({{ s.entry.overrides?.list()?.length }})\n </button>\n }\n </div>\n <et-query-devtools-json\n [value]=\"s.query.response()\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n [overrides]=\"s.entry.overrides ?? null\"\n path=\"response\"\n />\n }\n }\n}\n", styles: ["@layer components{.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-gone-note{margin:0 0 .8rem;color:var(--_et-qdt-muted);font-size:1.1rem}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-detail-head .et-query-devtools-route{flex:0 1 auto}.et-query-devtools-route-copy{appearance:none;margin-inline-end:auto;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;inline-size:2.2rem;block-size:2.2rem;margin-inline-start:-.4rem;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font:inherit;font-size:1.3rem;line-height:1}.et-query-devtools-route-copy:hover:not(.et-query-devtools-route-copy--copied){background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-route-copy--copied{color:var(--_et-qdt-success)}.et-query-devtools-live{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-live-note{color:var(--_et-qdt-muted);font-size:1.15rem}.et-query-devtools-progress{display:block;flex:1 1 12rem;min-inline-size:8rem;max-inline-size:24rem;block-size:.5rem;border-radius:999px;overflow:hidden;background:var(--_et-qdt-border)}.et-query-devtools-progress-bar{display:block;block-size:100%;border-radius:inherit;background:var(--_et-qdt-accent)}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));gap:.6rem;margin:0 0 1rem}.et-query-devtools-stat-value--sm{font-size:1.2rem}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-diff-step{display:flex;gap:.4rem;margin-inline-start:auto}.et-query-devtools-runs-fold{margin-block-start:.4rem;color:var(--_et-qdt-muted)}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-subtabs{display:flex;flex-wrap:wrap;gap:.2rem;border-block-end:1px solid var(--_et-qdt-border);margin-block:.8rem}.et-query-devtools-subtabs+.et-query-devtools-section-row{padding-block-start:0;border-block-start:0}.et-query-devtools-subtab{appearance:none;display:inline-flex;align-items:center;gap:.4rem;border:0;border-block-end:2px solid transparent;background:transparent;color:var(--_et-qdt-muted);font:inherit;font-size:1.15rem;padding:.4rem .6rem;margin-block-end:-1px;cursor:pointer}.et-query-devtools-subtab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-subtab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-run-cell{display:inline-flex;align-items:center;gap:.5rem}.et-query-devtools-diff td{max-inline-size:28rem;overflow-wrap:anywhere}.et-query-devtools-diff-before{color:var(--_et-qdt-muted)}.et-query-devtools-diff tr[data-kind=removed] .et-query-devtools-diff-before{color:var(--_et-qdt-error)}.et-query-devtools-diff tr[data-kind=added] .et-query-devtools-diff-after{color:var(--_et-qdt-success)}.et-query-devtools-diff tr[data-kind=changed] .et-query-devtools-diff-after{color:var(--_et-qdt-accent)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50145
|
+
}
|
|
50146
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDetailComponent, decorators: [{
|
|
50147
|
+
type: Component,
|
|
50148
|
+
args: [{ selector: 'et-query-devtools-detail', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsFeaturesComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "@let s = sel();\n\n<div class=\"et-query-devtools-detail-head\">\n <span class=\"et-query-devtools-method\">{{ s.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(s.entry, s.query)\" />\n </span>\n <button\n [attr.aria-label]=\"host.copyableRouteTitle(s.entry, s.query)\"\n [title]=\"host.copyableRouteTitle(s.entry, s.query)\"\n [class.et-query-devtools-route-copy--copied]=\"host.copiedRoute()\"\n (click)=\"host.copyRoute(s.entry, s.query)\"\n class=\"et-query-devtools-route-copy\"\n type=\"button\"\n >\n {{ host.copiedRoute() ? '\u2713' : '\u29C9' }}\n </button>\n @if (host.isTampered(s.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n @if (isGone()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">gone</span>\n }\n</div>\n\n@if (s.entry.destroyedAt; as destroyedAt) {\n <p class=\"et-query-devtools-gone-note\">\n Destroyed at {{ host.formatTime(destroyedAt) }}. This is the last state the query held - nothing here updates, and\n it cannot be run again.\n </p>\n}\n\n@if (host.requestProgress(s.query); as live) {\n <div class=\"et-query-devtools-live\">\n @if (live.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"The retry policy is backing off before it tries again. A query stuck loading with this chip is waiting, not slow.\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n attempt {{ retry.attempt }} in {{ host.formatCountdown(live.retryInMs) }}\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.retryCause(retry.status) }} \u00B7 backing off {{ host.formatDuration(retry.delayMs) }}\n </span>\n } @else if (live.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"How many HTTP attempts the last execution took - the retry policy fired for the rest\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ live.attempts }} attempts\n </span>\n }\n\n @if (live.progress; as progress) {\n <span\n [attr.aria-valuenow]=\"progress.percentage\"\n class=\"et-query-devtools-progress\"\n role=\"progressbar\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n aria-label=\"Transfer progress\"\n >\n <span [style.inline-size.%]=\"progress.percentage\" class=\"et-query-devtools-progress-bar\"></span>\n </span>\n <span class=\"et-query-devtools-live-note\">\n {{ host.formatPercent(progress.percentage) }} \u00B7 {{ host.formatBytes(progress.loaded) }} of\n {{ host.formatBytes(progress.total) }}\n @if (progress.speed !== null) {\n \u00B7 {{ host.formatSpeed(progress.speed) }}\n }\n @if (progress.remainingTime !== null) {\n \u00B7 {{ host.formatDuration(progress.remainingTime) }} left\n }\n </span>\n }\n </div>\n}\n\n<div class=\"et-query-devtools-actions\">\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Run</span>\n <button (click)=\"host.executeQuery(s, false)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.executeQuery(s, true)\" class=\"et-query-devtools-btn\" type=\"button\">Cached</button>\n <button (click)=\"host.resetQuery(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Reset</button>\n }\n @let locatable = host.locatableElement(s.entry);\n <button\n [disabled]=\"!locatable\"\n [title]=\"\n locatable\n ? 'Scroll to and outline the element this query was created in. That is where it was created, not necessarily where its data is rendered.'\n : 'This query was created outside a component or directive - a root service, a resolver or a guard - so it has no element to point at.'\n \"\n (click)=\"host.locateQuery(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n @switch (host.locateState()) {\n @case ('located') {\n \u2316 Created here\n }\n @case ('offscreen') {\n \u2316 Not on screen\n }\n @default {\n \u2316 Locate\n }\n }\n </button>\n <button (click)=\"host.copyReport(s.entry, s.query)\" class=\"et-query-devtools-btn\" type=\"button\">\n {{ host.copiedReport() ? '\u2713 Copied' : 'Copy report' }}\n </button>\n <button\n (click)=\"host.copyCurlRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as a curl command - the URL, the headers as the request resolved them, and the body\"\n >\n {{ host.copiedCurl() ? '\u2713 Copied' : 'cURL' }}\n </button>\n <button\n (click)=\"host.copyInsomniaRequest(s.entry, s.query)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy as an Insomnia collection (Import \u2192 From Clipboard). Includes the request headers, and the token refresh for a secure query.\"\n >\n {{ host.copiedInsomnia() ? '\u2713 Copied' : 'Insomnia' }}\n </button>\n @if (!isGone()) {\n <span class=\"et-query-devtools-actions-label\">Edit</span>\n <button (click)=\"host.openResponseEditor(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Response</button>\n <button (click)=\"host.openArgsEditor(s)\" class=\"et-query-devtools-btn\" type=\"button\">Replay args</button>\n <span class=\"et-query-devtools-actions-label\">Force</span>\n <button (click)=\"host.forceLoading(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Loading</button>\n <button (click)=\"host.forceError(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Error</button>\n <button (click)=\"host.forceEmpty(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Empty</button>\n <button (click)=\"host.clearForced(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Clear</button>\n }\n</div>\n\n@if (!isGone() && host.editorMode() !== 'none') {\n <div class=\"et-query-devtools-editor\">\n @if (host.editorMode() === 'response') {\n <h4 class=\"et-query-devtools-section\">Edit response \u2192 setResponse()</h4>\n <textarea\n #respArea\n [value]=\"host.editorSeed\"\n (input)=\"host.responseDraft.set(respArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyResponse(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Apply</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n } @else {\n <h4 class=\"et-query-devtools-section\">Replay with edited args \u2192 execute()</h4>\n <textarea\n #argsArea\n [value]=\"host.editorSeed\"\n (input)=\"host.argsDraft.set(argsArea.value)\"\n class=\"et-query-devtools-textarea\"\n spellcheck=\"false\"\n ></textarea>\n <div class=\"et-query-devtools-actions\">\n <button (click)=\"host.applyArgs(s.query)\" class=\"et-query-devtools-btn\" type=\"button\">Execute</button>\n <button (click)=\"host.cancelEditor()\" class=\"et-query-devtools-btn\" type=\"button\">Cancel</button>\n </div>\n }\n @if (host.editError(); as err) {\n <p class=\"et-query-devtools-editor-error\">{{ err }}</p>\n }\n </div>\n}\n\n@let detailRuns = host.queryRuns(s.entry);\n<nav class=\"et-query-devtools-subtabs\" role=\"tablist\">\n @for (tab of detailTabs; track tab.id) {\n <button\n [class.et-query-devtools-subtab--active]=\"host.detailTab() === tab.id\"\n [attr.aria-selected]=\"host.detailTab() === tab.id\"\n (click)=\"host.detailTab.set(tab.id)\"\n class=\"et-query-devtools-subtab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (tab.id === 'history' && detailRuns.length) {\n <span class=\"et-query-devtools-tab-badge\">{{ detailRuns.length }}</span>\n }\n <!-- The error body lives under Data, so the tab has to say so - a failure must not hide\n behind a tab that is not open. -->\n @if (tab.id === 'data' && s.query.error()) {\n <span class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\">!</span>\n }\n </button>\n }\n</nav>\n\n@switch (host.detailTab()) {\n @case ('overview') {\n <dl class=\"et-query-devtools-meta\">\n <dt>Base URL</dt>\n <dd class=\"et-query-devtools-mono\">\n {{ s.entry.meta.clientBaseUrl || s.entry.meta.clientName || '\u2014' }}\n </dd>\n <dt>Route</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.entry.meta.route || '\u2014' }}</dd>\n <dt>Request URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ host.requestUrl(s.query) || '\u2014' }}</dd>\n <dt>Status</dt>\n <dd>{{ host.queryStatus(s.query) }}</dd>\n <dt>Cache key</dt>\n <dd class=\"et-query-devtools-mono\">{{ s.query.id() || '\u2014' }}</dd>\n <dt>Last executed</dt>\n <dd>{{ host.formatTime(s.query.lastTimeExecutedAt()) }}</dd>\n <dt>Triggered by</dt>\n <dd>{{ s.query.triggeredBy() || 'user' }}</dd>\n @let refreshes = host.refreshesFor(s.entry.id);\n @if (refreshes.length) {\n <dt title=\"Invalidations and mutation refreshes that re-executed this query, as far back as the event log goes\">\n Refetched by\n </dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (refresh of refreshes.slice(0, 5); track refresh.id) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ host.formatTime(refresh.timestamp) }} \u00B7 {{ refresh.label }}\n </span>\n }\n @if (refreshes.length > 5) {\n <span class=\"et-query-devtools-hint\">+{{ refreshes.length - 5 }} earlier</span>\n }\n </div>\n </dd>\n }\n @let drivers = host.formsDrivingQuery(s.entry);\n @if (drivers.length) {\n <dt>Args from</dt>\n <dd>\n <div class=\"et-query-devtools-chips\">\n @for (driver of drivers; track driver.id) {\n <button\n (click)=\"host.selectForm(driver.id)\"\n class=\"et-query-devtools-chip et-query-devtools-chip--button\"\n type=\"button\"\n title=\"Open the query form in the Forms tab\"\n >\n {{ driver.meta.name }}\n </button>\n }\n </div>\n </dd>\n }\n @if (s.entry.meta.features?.length) {\n <dt>Features</dt>\n <dd>\n <et-query-devtools-features [features]=\"s.entry.meta.features ?? []\" />\n </dd>\n }\n </dl>\n\n @let activity = host.queryActivity(s.entry);\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Activity</h4>\n <button\n [disabled]=\"!activity.hasActivity\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the counters and the run history, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n\n <dl class=\"et-query-devtools-stats\">\n <div class=\"et-query-devtools-stat\" title=\"Every time the query ran, cache hits included\">\n <dt>Refreshes</dt>\n <dd>{{ activity.stats.executions }}</dd>\n @if (activity.cacheServed) {\n <span class=\"et-query-devtools-stat-sub\">{{ activity.cacheServed }} without a request</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\" title=\"Executions that started a request, and how they ended\">\n <dt>Requests</dt>\n <dd>{{ activity.stats.requests }}</dd>\n <span class=\"et-query-devtools-stat-sub\">\n {{ activity.stats.responses }} ok\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n </span>\n </div>\n <div\n class=\"et-query-devtools-stat\"\n title=\"Total response payload received. Sizes without a content-length header are measured from the decoded body, so they ignore compression.\"\n >\n <dt>Received</dt>\n <dd>{{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}</dd>\n @if (activity.avgResponseBytes !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatBytes(activity.avgResponseBytes) }} per response</span>\n }\n </div>\n @if (activity.stats.sentBytes) {\n <div class=\"et-query-devtools-stat\" title=\"Total request body sent (headers not counted)\">\n <dt>Sent</dt>\n <dd>{{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}</dd>\n </div>\n }\n @if (activity.stats.retries) {\n <div\n class=\"et-query-devtools-stat\"\n title=\"Attempts the retry policy added on top of the first one. Which run they belong to is under History.\"\n >\n <dt>Retries</dt>\n <dd>{{ activity.stats.retries }}</dd>\n </div>\n }\n <div class=\"et-query-devtools-stat\" title=\"Measured from the execution that preceded each response\">\n <dt>Duration</dt>\n <dd>{{ host.formatDuration(activity.stats.lastDurationMs) }}</dd>\n @if (activity.avgDurationMs !== null) {\n <span class=\"et-query-devtools-stat-sub\">{{ host.formatDuration(activity.avgDurationMs) }} on average</span>\n }\n </div>\n <div class=\"et-query-devtools-stat\">\n <dt>Last response</dt>\n <dd class=\"et-query-devtools-stat-value--sm\">{{ host.formatTime(activity.stats.lastResponseAt) }}</dd>\n @if (activity.stats.firstExecutedAt !== null) {\n <span class=\"et-query-devtools-stat-sub\"\n >first ran {{ host.formatTime(activity.stats.firstExecutedAt) }}</span\n >\n }\n </div>\n </dl>\n }\n @case ('history') {\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Runs</h4>\n <button\n [disabled]=\"!detailRuns.length\"\n (click)=\"host.resetStats(s.entry)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Clear the run history and the counters, so the next interaction can be measured on its own\"\n >\n \u27F2 Reset\n </button>\n </div>\n @if (detailRuns.length) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Run</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Received</th>\n <th>Body</th>\n </tr>\n </thead>\n <tbody>\n @for (run of runSections().listed.concat(foldedRunsOpen() ? runSections().folded : []); track run.index) {\n <tr [attr.data-status]=\"run.status === 'error' ? 'error' : null\">\n <td>\n <span class=\"et-query-devtools-run-cell\">\n <span\n [attr.data-status]=\"host.runStatus(run)\"\n [title]=\"run.status\"\n class=\"et-query-devtools-status\"\n ></span>\n #{{ run.index }}\n @if (run.attempts > 1) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Took {{\n run.attempts\n }} attempts - the duration next to it covers every one of them, backoff included\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ run.attempts }}\n </span>\n }\n @if (!run.didRequest) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Arrived without a request of this query's own - a poll, another consumer of the same cache entry, or another tab\"\n >\n shared\n </span>\n }\n @if (run.error; as error) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"{{ error.messages.join(' \u00B7 ') || 'The failure carried no message' }}\"\n >\n {{ error.code || 'failed' }}\n </span>\n }\n </span>\n </td>\n <td>{{ host.formatTime(run.startedAt) }}</td>\n <td>\n @if (run.endedAt === null) {\n in flight\n } @else {\n {{ host.formatDuration(run.endedAt - run.startedAt) }}\n }\n </td>\n <td>{{ run.receivedBytes ? host.formatBytes(run.receivedBytes) : '\u2014' }}</td>\n <td>\n <span class=\"et-query-devtools-cell-actions\">\n @if (host.canDiffRun(s.entry, run)) {\n @let role = host.diffRunRole(s.entry, run);\n @let armed = role ? diffRoles[role] : null;\n <button\n [class.et-query-devtools-btn--active]=\"!!armed\"\n [title]=\"\n armed?.title ?? 'Compare this response against another run - click a second row to pick which'\n \"\n (click)=\"host.toggleRunDiff(s.entry, run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n {{ armed?.label ?? 'Diff' }}\n </button>\n } @else if (run.error?.hasBody) {\n <button\n [class.et-query-devtools-btn--active]=\"host.errorRunIndex() === run.index\"\n (click)=\"host.toggleRunError(run)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Show the body this failure came with\"\n >\n Error\n </button>\n } @else if (run.hasResponse) {\n <span class=\"et-query-devtools-count\">the only body held</span>\n } @else if (run.status === 'success' || run.error) {\n <span\n class=\"et-query-devtools-count\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so this run can no longer be an end of a diff\"\n >\n body no longer held\n </span>\n } @else {\n <span class=\"et-query-devtools-count\">\u2014</span>\n }\n </span>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @let foldedRuns = runSections().folded.length;\n @if (foldedRuns) {\n <button\n [attr.aria-expanded]=\"foldedRunsOpen()\"\n (click)=\"foldedRunsOpen.set(!foldedRunsOpen())\"\n class=\"et-query-devtools-btn et-query-devtools-runs-fold\"\n type=\"button\"\n title=\"Only the newest {{\n host.retainedResponseCount\n }} bodies of a query are kept, so none of these older runs can be an end of a diff\"\n >\n <span aria-hidden=\"true\">{{ foldedRunsOpen() ? '\u25BE' : '\u25B8' }}</span>\n {{ foldedRunsOpen() ? 'Hide' : 'Show' }} {{ foldedRuns }} older run{{ foldedRuns === 1 ? '' : 's' }} with no\n body\n </button>\n }\n\n @if (host.pickedRunError(s.entry); as failure) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Error body \u00B7 run #{{ failure.run.index }} \u00B7 {{ failure.error.code || 'no status' }}\n </h5>\n </div>\n @for (message of failure.error.messages; track message) {\n <p class=\"et-query-devtools-count\">{{ message }}</p>\n }\n <et-query-devtools-json\n [value]=\"failure.error.body\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"runError\"\n />\n }\n\n @if (host.responseDiff(s.entry); as comparison) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">\n Response diff \u00B7 run #{{ comparison.before.index }} \u2192 #{{ comparison.after.index }}\n </h5>\n <span class=\"et-query-devtools-diff-step\">\n <button\n [disabled]=\"!host.canStepRunDiff(s.entry, true)\"\n (click)=\"host.stepRunDiff(s.entry, true)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Compare the pair one run older, without going back to the table\"\n >\n \u25C2 Older\n </button>\n <button\n [disabled]=\"!host.canStepRunDiff(s.entry, false)\"\n (click)=\"host.stepRunDiff(s.entry, false)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Compare the pair one run newer, without going back to the table\"\n >\n Newer \u25B8\n </button>\n </span>\n <span class=\"et-query-devtools-count\">\n @if (host.diffBaseRunIndex() === null) {\n <span\n title=\"Nothing is picked to compare against, so this is the nearest older run that still holds a body - click another run's Diff to pick one\"\n >\n nearest older\n </span>\n \u00B7\n }\n @if (comparison.diff.entries.length) {\n {{ comparison.diff.entries.length }} path{{ comparison.diff.entries.length === 1 ? '' : 's' }}\n @if (comparison.diff.truncated) {\n (capped)\n }\n } @else {\n identical\n }\n </span>\n </div>\n @if (comparison.diff.entries.length) {\n <table class=\"et-query-devtools-table et-query-devtools-diff\">\n <thead>\n <tr>\n <th>Path</th>\n <th>Before</th>\n <th>After</th>\n </tr>\n </thead>\n <tbody>\n @for (change of comparison.diff.entries; track change.path) {\n <tr [attr.data-kind]=\"change.kind\">\n <td class=\"et-query-devtools-mono\">{{ change.path }}</td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-before\">\n {{ change.kind === 'added' ? '\u2014' : host.inlineValue(change.before) }}\n </td>\n <td class=\"et-query-devtools-mono et-query-devtools-diff-after\">\n {{ change.kind === 'removed' ? '\u2014' : host.inlineValue(change.after) }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"et-query-devtools-empty\">The two responses are identical.</p>\n }\n }\n } @else {\n <p class=\"et-query-devtools-empty\">No runs recorded yet.</p>\n }\n }\n @case ('data') {\n @if (s.entry.meta.gqlQuery; as gqlQuery) {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">GraphQL document</h5>\n <button\n (click)=\"host.copyGqlDocument(gqlQuery)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Copy the GraphQL document\"\n >\n {{ host.copiedGql() ? '\u2713 Copied' : '\u29C9 Copy' }}\n </button>\n </div>\n <pre class=\"et-query-devtools-code\">{{ host.gqlDocument(gqlQuery) }}</pre>\n }\n\n <div class=\"et-query-devtools-section-row\">\n <h4 class=\"et-query-devtools-section\">Value explorer</h4>\n <input\n #jsonSearchInput\n [value]=\"host.jsonSearch()\"\n (input)=\"host.jsonSearch.set(jsonSearchInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter keys / values\u2026\"\n />\n </div>\n\n <h5 class=\"et-query-devtools-section\">Args</h5>\n <et-query-devtools-json\n [value]=\"host.queryArgs(s.query)\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"args\"\n />\n\n @if (s.query.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Error ({{ error.raw.status }})</h5>\n <et-query-devtools-json\n [value]=\"error.isList ? error.errors : error.error\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n path=\"error\"\n />\n } @else {\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Response</h5>\n @if (s.entry.overrides?.list()?.length) {\n <button (click)=\"s.entry.overrides?.clearAll()\" class=\"et-query-devtools-btn\" type=\"button\">\n Reset all overrides ({{ s.entry.overrides?.list()?.length }})\n </button>\n }\n </div>\n <et-query-devtools-json\n [value]=\"s.query.response()\"\n [search]=\"host.jsonSearchTerm()\"\n [expandedPaths]=\"host.jsonExpandedPaths()\"\n [collapsedPaths]=\"host.jsonCollapsedPaths()\"\n [toggleFn]=\"host.toggleJsonPath\"\n [overrides]=\"s.entry.overrides ?? null\"\n path=\"response\"\n />\n }\n }\n}\n", styles: ["@layer components{.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-gone-note{margin:0 0 .8rem;color:var(--_et-qdt-muted);font-size:1.1rem}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-detail-head .et-query-devtools-route{flex:0 1 auto}.et-query-devtools-route-copy{appearance:none;margin-inline-end:auto;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;inline-size:2.2rem;block-size:2.2rem;margin-inline-start:-.4rem;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font:inherit;font-size:1.3rem;line-height:1}.et-query-devtools-route-copy:hover:not(.et-query-devtools-route-copy--copied){background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-route-copy--copied{color:var(--_et-qdt-success)}.et-query-devtools-live{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-live-note{color:var(--_et-qdt-muted);font-size:1.15rem}.et-query-devtools-progress{display:block;flex:1 1 12rem;min-inline-size:8rem;max-inline-size:24rem;block-size:.5rem;border-radius:999px;overflow:hidden;background:var(--_et-qdt-border)}.et-query-devtools-progress-bar{display:block;block-size:100%;border-radius:inherit;background:var(--_et-qdt-accent)}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));gap:.6rem;margin:0 0 1rem}.et-query-devtools-stat-value--sm{font-size:1.2rem}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-diff-step{display:flex;gap:.4rem;margin-inline-start:auto}.et-query-devtools-runs-fold{margin-block-start:.4rem;color:var(--_et-qdt-muted)}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-subtabs{display:flex;flex-wrap:wrap;gap:.2rem;border-block-end:1px solid var(--_et-qdt-border);margin-block:.8rem}.et-query-devtools-subtabs+.et-query-devtools-section-row{padding-block-start:0;border-block-start:0}.et-query-devtools-subtab{appearance:none;display:inline-flex;align-items:center;gap:.4rem;border:0;border-block-end:2px solid transparent;background:transparent;color:var(--_et-qdt-muted);font:inherit;font-size:1.15rem;padding:.4rem .6rem;margin-block-end:-1px;cursor:pointer}.et-query-devtools-subtab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-subtab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-run-cell{display:inline-flex;align-items:center;gap:.5rem}.et-query-devtools-diff td{max-inline-size:28rem;overflow-wrap:anywhere}.et-query-devtools-diff-before{color:var(--_et-qdt-muted)}.et-query-devtools-diff tr[data-kind=removed] .et-query-devtools-diff-before{color:var(--_et-qdt-error)}.et-query-devtools-diff tr[data-kind=added] .et-query-devtools-diff-after{color:var(--_et-qdt-success)}.et-query-devtools-diff tr[data-kind=changed] .et-query-devtools-diff-after{color:var(--_et-qdt-accent)}}\n"] }]
|
|
50149
|
+
}], propDecorators: { sel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sel", required: true }] }] } });
|
|
50150
|
+
|
|
50151
|
+
/**
|
|
50152
|
+
* The split-view drawer every two-pane tab (stacks/sequences/forms/timeline) opens a query in - the
|
|
50153
|
+
* resize handle, the `<aside>` chrome and the close button around a `<et-query-devtools-detail>`. The
|
|
50154
|
+
* Queries tab renders that same detail component inline instead, without this wrapper, since it has no
|
|
50155
|
+
* separate list/drawer split to close.
|
|
50156
|
+
*/
|
|
50157
|
+
class QueryDevtoolsDrawerComponent {
|
|
50158
|
+
constructor() {
|
|
50159
|
+
this.host = injectQueryDevtoolsHost();
|
|
50160
|
+
this.sel = input(null, /* @ts-ignore */
|
|
50161
|
+
...(ngDevMode ? [{ debugName: "sel" }] : /* istanbul ignore next */ []));
|
|
50162
|
+
this.container = input.required(/* @ts-ignore */
|
|
50163
|
+
...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
|
|
50164
|
+
this.dismiss = output();
|
|
50165
|
+
}
|
|
50166
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50167
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsDrawerComponent, isStandalone: true, selector: "et-query-devtools-drawer", inputs: { sel: { classPropertyName: "sel", publicName: "sel", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: "@if (sel(); as selected) {\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'drawer', container: container() })\"\n (dblclick)=\"host.resetPaneSize('drawer')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button (click)=\"dismiss.emit()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close detail\">\u2715</button>\n </div>\n <et-query-devtools-detail [sel]=\"selected\" />\n </aside>\n}\n", styles: ["@layer components{.et-query-devtools-drawer{flex:0 0 var(--_et-qdt-drawer-width, 42%);min-inline-size:var(--_et-qdt-drawer-width, 26rem);max-inline-size:var(--_et-qdt-drawer-width, 48rem);overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsDetailComponent, selector: "et-query-devtools-detail", inputs: ["sel"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50168
|
+
}
|
|
50169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsDrawerComponent, decorators: [{
|
|
50170
|
+
type: Component,
|
|
50171
|
+
args: [{ selector: 'et-query-devtools-drawer', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDetailComponent], template: "@if (sel(); as selected) {\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'drawer', container: container() })\"\n (dblclick)=\"host.resetPaneSize('drawer')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <aside class=\"et-query-devtools-drawer\">\n <div class=\"et-query-devtools-drawer-head\">\n <span>Query detail</span>\n <button (click)=\"dismiss.emit()\" class=\"et-query-devtools-close\" type=\"button\" title=\"Close detail\">\u2715</button>\n </div>\n <et-query-devtools-detail [sel]=\"selected\" />\n </aside>\n}\n", styles: ["@layer components{.et-query-devtools-drawer{flex:0 0 var(--_et-qdt-drawer-width, 42%);min-inline-size:var(--_et-qdt-drawer-width, 26rem);max-inline-size:var(--_et-qdt-drawer-width, 48rem);overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}}\n"] }]
|
|
50172
|
+
}], propDecorators: { sel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sel", required: false }] }], container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
|
|
50173
|
+
|
|
50058
50174
|
/** The Forms tab: registered `defineQueryForm()` handles, each expandable to its field table. */
|
|
50059
50175
|
class QueryDevtoolsFormsTabComponent {
|
|
50060
50176
|
constructor() {
|
|
50061
50177
|
this.host = injectQueryDevtoolsHost();
|
|
50062
50178
|
}
|
|
50063
50179
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsFormsTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50064
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsFormsTabComponent, isStandalone: true, selector: "et-query-devtools-forms-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.formEntries(); track entry.id) {\n @let form = host.asForm(entry);\n @let expanded = host.selectedFormId() === entry.id;\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <button\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.selectedFormId.set(expanded ? null : entry.id)\"\n class=\"et-query-devtools-row-link\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-caret\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <strong>{{ entry.meta.name || 'query form' }}</strong>\n </button>\n @if (form.activeFilterCount(); as count) {\n <span class=\"et-query-devtools-chip\">{{ count }} active</span>\n } @else {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">at defaults</span>\n }\n @if (form.isCommitPending()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">debouncing</span>\n }\n @if (!form.isObserving()) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"observe() has not been called, so nothing syncs with the URL\"\n >\n not observing\n </span>\n }\n <button\n [disabled]=\"form.isAtDefaults()\"\n (click)=\"form.resetAll()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2 Reset all\n </button>\n </div>\n\n @let driven = host.queriesDrivenByForm(entry);\n <dl class=\"et-query-devtools-meta\">\n <dt>Drives</dt>\n <dd>\n @if (driven.length) {\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of driven; track link.id) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.formSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.formSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query'\" />\n </span>\n </button>\n }\n </div>\n } @else {\n <span class=\"et-query-devtools-hint\">\n No query has read this form's value yet. A query picks it up the first time its\n <code>withArgs</code> reads <code>value()</code>.\n </span>\n }\n </dd>\n </dl>\n\n @if (expanded) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Value</th>\n <th>Default</th>\n <th>URL param</th>\n <th>Rules</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (field of form.fields(); track field.key) {\n <tr [attr.data-status]=\"field.isDefault ? null : 'success'\">\n <td class=\"et-query-devtools-mono\">{{ field.key }}</td>\n <td class=\"et-query-devtools-mono\">\n {{ host.inlineValue(field.value) }}\n <!-- The live value only differs while a debounce is pending, which is exactly\n when \"the input says X but the query asked for Y\" needs explaining. -->\n @if (field.liveValue !== field.value) {\n <span class=\"et-query-devtools-stat-sub\">typing {{ host.inlineValue(field.liveValue) }}</span>\n }\n </td>\n <td class=\"et-query-devtools-mono\">{{ host.inlineValue(field.defaultValue) }}</td>\n <td class=\"et-query-devtools-mono\">\n @if (field.queryParam === undefined) {\n <span class=\"et-query-devtools-hint\">\u2014</span>\n } @else {\n {{ field.paramKey }}={{ host.inlineValue(field.queryParam) }}\n }\n </td>\n <td>\n <div class=\"et-query-devtools-chips\">\n @if (field.debounceMs !== null) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ field.debounceMs }}ms\n </span>\n }\n @if (field.isResetBy.length) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Reset to its default whenever one of these changes\"\n >\n reset by {{ field.isResetBy.join(', ') }}\n </span>\n }\n @if (!field.countsAsFilter) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Not counted by activeFilterCount\"\n >\n not a filter\n </span>\n }\n </div>\n </td>\n <td>\n <button\n [disabled]=\"field.isDefault\"\n (click)=\"form.resetField(field.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <h4 class=\"et-query-devtools-section\">Committed value</h4>\n <et-query-devtools-json [value]=\"form.value()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">\n No query forms registered. A form created with <code>defineQueryForm()</code> registers itself.\n </p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.formSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.formSelectedQueryId.set(null)\"\n />\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50180
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsFormsTabComponent, isStandalone: true, selector: "et-query-devtools-forms-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.formEntries(); track entry.id) {\n @let form = host.asForm(entry);\n @let expanded = host.selectedFormId() === entry.id;\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <button\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.selectedFormId.set(expanded ? null : entry.id)\"\n class=\"et-query-devtools-row-link\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-caret\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <strong>{{ entry.meta.name || 'query form' }}</strong>\n </button>\n @if (form.activeFilterCount(); as count) {\n <span class=\"et-query-devtools-chip\">{{ count }} active</span>\n } @else {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">at defaults</span>\n }\n @if (form.isCommitPending()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">debouncing</span>\n }\n @if (!form.isObserving()) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"observe() has not been called, so nothing syncs with the URL\"\n >\n not observing\n </span>\n }\n <button\n [disabled]=\"form.isAtDefaults()\"\n (click)=\"form.resetAll()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2 Reset all\n </button>\n </div>\n\n @let driven = host.queriesDrivenByForm(entry);\n <dl class=\"et-query-devtools-meta\">\n <dt>Drives</dt>\n <dd>\n @if (driven.length) {\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of driven; track link.id) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.formSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.formSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query'\" />\n </span>\n </button>\n }\n </div>\n } @else {\n <span class=\"et-query-devtools-hint\">\n No query has read this form's value yet. A query picks it up the first time its\n <code>withArgs</code> reads <code>value()</code>.\n </span>\n }\n </dd>\n </dl>\n\n @if (expanded) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Value</th>\n <th>Default</th>\n <th>URL param</th>\n <th>Rules</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (field of form.fields(); track field.key) {\n <tr [attr.data-status]=\"field.isDefault ? null : 'success'\">\n <td class=\"et-query-devtools-mono\">{{ field.key }}</td>\n <td class=\"et-query-devtools-mono\">\n {{ host.inlineValue(field.value) }}\n <!-- The live value only differs while a debounce is pending, which is exactly\n when \"the input says X but the query asked for Y\" needs explaining. -->\n @if (field.liveValue !== field.value) {\n <span class=\"et-query-devtools-stat-sub\">typing {{ host.inlineValue(field.liveValue) }}</span>\n }\n </td>\n <td class=\"et-query-devtools-mono\">{{ host.inlineValue(field.defaultValue) }}</td>\n <td class=\"et-query-devtools-mono\">\n @if (field.queryParam === undefined) {\n <span class=\"et-query-devtools-hint\">\u2014</span>\n } @else {\n {{ field.paramKey }}={{ host.inlineValue(field.queryParam) }}\n }\n </td>\n <td>\n <div class=\"et-query-devtools-chips\">\n @if (field.debounceMs !== null) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ field.debounceMs }}ms\n </span>\n }\n @if (field.isResetBy.length) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Reset to its default whenever one of these changes\"\n >\n reset by {{ field.isResetBy.join(', ') }}\n </span>\n }\n @if (!field.countsAsFilter) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Not counted by activeFilterCount\"\n >\n not a filter\n </span>\n }\n </div>\n </td>\n <td>\n <button\n [disabled]=\"field.isDefault\"\n (click)=\"form.resetField(field.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <h4 class=\"et-query-devtools-section\">Committed value</h4>\n <et-query-devtools-json [value]=\"form.value()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">\n No query forms registered. A form created with <code>defineQueryForm()</code> registers itself.\n </p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.formSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.formSelectedQueryId.set(null)\"\n />\n</div>\n", styles: ["@layer components{.et-query-devtools-caret{display:inline-block;width:1.2rem;color:var(--_et-qdt-muted)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50065
50181
|
}
|
|
50066
50182
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsFormsTabComponent, decorators: [{
|
|
50067
50183
|
type: Component,
|
|
50068
|
-
args: [{ selector: 'et-query-devtools-forms-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDrawerComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.formEntries(); track entry.id) {\n @let form = host.asForm(entry);\n @let expanded = host.selectedFormId() === entry.id;\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <button\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.selectedFormId.set(expanded ? null : entry.id)\"\n class=\"et-query-devtools-row-link\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-caret\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <strong>{{ entry.meta.name || 'query form' }}</strong>\n </button>\n @if (form.activeFilterCount(); as count) {\n <span class=\"et-query-devtools-chip\">{{ count }} active</span>\n } @else {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">at defaults</span>\n }\n @if (form.isCommitPending()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">debouncing</span>\n }\n @if (!form.isObserving()) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"observe() has not been called, so nothing syncs with the URL\"\n >\n not observing\n </span>\n }\n <button\n [disabled]=\"form.isAtDefaults()\"\n (click)=\"form.resetAll()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2 Reset all\n </button>\n </div>\n\n @let driven = host.queriesDrivenByForm(entry);\n <dl class=\"et-query-devtools-meta\">\n <dt>Drives</dt>\n <dd>\n @if (driven.length) {\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of driven; track link.id) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.formSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.formSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query'\" />\n </span>\n </button>\n }\n </div>\n } @else {\n <span class=\"et-query-devtools-hint\">\n No query has read this form's value yet. A query picks it up the first time its\n <code>withArgs</code> reads <code>value()</code>.\n </span>\n }\n </dd>\n </dl>\n\n @if (expanded) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Value</th>\n <th>Default</th>\n <th>URL param</th>\n <th>Rules</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (field of form.fields(); track field.key) {\n <tr [attr.data-status]=\"field.isDefault ? null : 'success'\">\n <td class=\"et-query-devtools-mono\">{{ field.key }}</td>\n <td class=\"et-query-devtools-mono\">\n {{ host.inlineValue(field.value) }}\n <!-- The live value only differs while a debounce is pending, which is exactly\n when \"the input says X but the query asked for Y\" needs explaining. -->\n @if (field.liveValue !== field.value) {\n <span class=\"et-query-devtools-stat-sub\">typing {{ host.inlineValue(field.liveValue) }}</span>\n }\n </td>\n <td class=\"et-query-devtools-mono\">{{ host.inlineValue(field.defaultValue) }}</td>\n <td class=\"et-query-devtools-mono\">\n @if (field.queryParam === undefined) {\n <span class=\"et-query-devtools-hint\">\u2014</span>\n } @else {\n {{ field.paramKey }}={{ host.inlineValue(field.queryParam) }}\n }\n </td>\n <td>\n <div class=\"et-query-devtools-chips\">\n @if (field.debounceMs !== null) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ field.debounceMs }}ms\n </span>\n }\n @if (field.isResetBy.length) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Reset to its default whenever one of these changes\"\n >\n reset by {{ field.isResetBy.join(', ') }}\n </span>\n }\n @if (!field.countsAsFilter) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Not counted by activeFilterCount\"\n >\n not a filter\n </span>\n }\n </div>\n </td>\n <td>\n <button\n [disabled]=\"field.isDefault\"\n (click)=\"form.resetField(field.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <h4 class=\"et-query-devtools-section\">Committed value</h4>\n <et-query-devtools-json [value]=\"form.value()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">\n No query forms registered. A form created with <code>defineQueryForm()</code> registers itself.\n </p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.formSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.formSelectedQueryId.set(null)\"\n />\n</div>\n" }]
|
|
50184
|
+
args: [{ selector: 'et-query-devtools-forms-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDrawerComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.formEntries(); track entry.id) {\n @let form = host.asForm(entry);\n @let expanded = host.selectedFormId() === entry.id;\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <button\n [attr.aria-expanded]=\"expanded\"\n (click)=\"host.selectedFormId.set(expanded ? null : entry.id)\"\n class=\"et-query-devtools-row-link\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-caret\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <strong>{{ entry.meta.name || 'query form' }}</strong>\n </button>\n @if (form.activeFilterCount(); as count) {\n <span class=\"et-query-devtools-chip\">{{ count }} active</span>\n } @else {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">at defaults</span>\n }\n @if (form.isCommitPending()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">debouncing</span>\n }\n @if (!form.isObserving()) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"observe() has not been called, so nothing syncs with the URL\"\n >\n not observing\n </span>\n }\n <button\n [disabled]=\"form.isAtDefaults()\"\n (click)=\"form.resetAll()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2 Reset all\n </button>\n </div>\n\n @let driven = host.queriesDrivenByForm(entry);\n <dl class=\"et-query-devtools-meta\">\n <dt>Drives</dt>\n <dd>\n @if (driven.length) {\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of driven; track link.id) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.formSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.formSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query'\" />\n </span>\n </button>\n }\n </div>\n } @else {\n <span class=\"et-query-devtools-hint\">\n No query has read this form's value yet. A query picks it up the first time its\n <code>withArgs</code> reads <code>value()</code>.\n </span>\n }\n </dd>\n </dl>\n\n @if (expanded) {\n <table class=\"et-query-devtools-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th>Value</th>\n <th>Default</th>\n <th>URL param</th>\n <th>Rules</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (field of form.fields(); track field.key) {\n <tr [attr.data-status]=\"field.isDefault ? null : 'success'\">\n <td class=\"et-query-devtools-mono\">{{ field.key }}</td>\n <td class=\"et-query-devtools-mono\">\n {{ host.inlineValue(field.value) }}\n <!-- The live value only differs while a debounce is pending, which is exactly\n when \"the input says X but the query asked for Y\" needs explaining. -->\n @if (field.liveValue !== field.value) {\n <span class=\"et-query-devtools-stat-sub\">typing {{ host.inlineValue(field.liveValue) }}</span>\n }\n </td>\n <td class=\"et-query-devtools-mono\">{{ host.inlineValue(field.defaultValue) }}</td>\n <td class=\"et-query-devtools-mono\">\n @if (field.queryParam === undefined) {\n <span class=\"et-query-devtools-hint\">\u2014</span>\n } @else {\n {{ field.paramKey }}={{ host.inlineValue(field.queryParam) }}\n }\n </td>\n <td>\n <div class=\"et-query-devtools-chips\">\n @if (field.debounceMs !== null) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">\n {{ field.debounceMs }}ms\n </span>\n }\n @if (field.isResetBy.length) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Reset to its default whenever one of these changes\"\n >\n reset by {{ field.isResetBy.join(', ') }}\n </span>\n }\n @if (!field.countsAsFilter) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"Not counted by activeFilterCount\"\n >\n not a filter\n </span>\n }\n </div>\n </td>\n <td>\n <button\n [disabled]=\"field.isDefault\"\n (click)=\"form.resetField(field.key)\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u27F2\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <h4 class=\"et-query-devtools-section\">Committed value</h4>\n <et-query-devtools-json [value]=\"form.value()\" />\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">\n No query forms registered. A form created with <code>defineQueryForm()</code> registers itself.\n </p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.formSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.formSelectedQueryId.set(null)\"\n />\n</div>\n", styles: ["@layer components{.et-query-devtools-caret{display:inline-block;width:1.2rem;color:var(--_et-qdt-muted)}}\n"] }]
|
|
50069
50185
|
}] });
|
|
50070
50186
|
|
|
50071
50187
|
/* eslint-disable @typescript-eslint/naming-convention -- the `__export_*` keys are Insomnia's file format */
|
|
@@ -50284,9 +50400,33 @@ class QueryDevtoolsQueriesTabComponent {
|
|
|
50284
50400
|
const items = this.searchedQueries().filter((item) => item.entry.destroyedAt
|
|
50285
50401
|
? this.listsTombstone(item.entry, facets)
|
|
50286
50402
|
: !facets.size || this.matchesFacets(item, facets));
|
|
50287
|
-
return this.pinnedFirst(items);
|
|
50403
|
+
return this.pinnedFirst(this.byLastExecuted(items));
|
|
50288
50404
|
}, /* @ts-ignore */
|
|
50289
50405
|
...(ngDevMode ? [{ debugName: "filteredQueries" }] : /* istanbul ignore next */ []));
|
|
50406
|
+
/**
|
|
50407
|
+
* The list as it is rendered: rows that would be indistinguishable from each other - same method, same
|
|
50408
|
+
* resolved route, same live-or-gone - folded into one group. One query used by several consumers is one
|
|
50409
|
+
* entry per consumer by design (the ids have to stay per-instance for the detail, pins and tombstones),
|
|
50410
|
+
* and this is where that stops being N identical lines.
|
|
50411
|
+
*
|
|
50412
|
+
* Grouping on what the row *shows* rather than on the registry's descriptor is deliberate: the
|
|
50413
|
+
* descriptor is the route template, so `/post/1` and `/post/2` share it while being different data.
|
|
50414
|
+
* Folding only what looks the same can never hide a distinction the list was making.
|
|
50415
|
+
*/
|
|
50416
|
+
this.queryGroups = computed(() => {
|
|
50417
|
+
const groups = new Map();
|
|
50418
|
+
for (const item of this.filteredQueries()) {
|
|
50419
|
+
const key = this.groupKey(item);
|
|
50420
|
+
const group = groups.get(key);
|
|
50421
|
+
if (group) {
|
|
50422
|
+
group.items.push(item);
|
|
50423
|
+
continue;
|
|
50424
|
+
}
|
|
50425
|
+
groups.set(key, { key, head: item, items: [item] });
|
|
50426
|
+
}
|
|
50427
|
+
return [...groups.values()];
|
|
50428
|
+
}, /* @ts-ignore */
|
|
50429
|
+
...(ngDevMode ? [{ debugName: "queryGroups" }] : /* istanbul ignore next */ []));
|
|
50290
50430
|
/** How many queries the list would hold with the search box empty, which is what the count compares to. */
|
|
50291
50431
|
this.scopedQueryCount = computed(() => {
|
|
50292
50432
|
const facets = this.host.queryFacets();
|
|
@@ -50295,19 +50435,53 @@ class QueryDevtoolsQueriesTabComponent {
|
|
|
50295
50435
|
...(ngDevMode ? [{ debugName: "scopedQueryCount" }] : /* istanbul ignore next */ []));
|
|
50296
50436
|
this.goneQueryCount = computed(() => this.host.scopedQueries().filter((entry) => !!entry.destroyedAt).length, /* @ts-ignore */
|
|
50297
50437
|
...(ngDevMode ? [{ debugName: "goneQueryCount" }] : /* istanbul ignore next */ []));
|
|
50438
|
+
/** The tombstones Forget would drop: the ones the list is showing, never the whole registry. */
|
|
50439
|
+
this.listedGoneQueries = computed(() => this.host.queryFacets().has('gone') ? this.filteredQueries().filter((item) => item.entry.destroyedAt) : [], /* @ts-ignore */
|
|
50440
|
+
...(ngDevMode ? [{ debugName: "listedGoneQueries" }] : /* istanbul ignore next */ []));
|
|
50298
50441
|
/** Whether the search box or a status chip is narrowing the list beyond its scope. */
|
|
50299
50442
|
this.isQueryListNarrowed = computed(() => !!this.host.queryFilter().trim() || this.host.queryFacets().size > 0, /* @ts-ignore */
|
|
50300
50443
|
...(ngDevMode ? [{ debugName: "isQueryListNarrowed" }] : /* istanbul ignore next */ []));
|
|
50301
50444
|
}
|
|
50445
|
+
/** The worst state in a folded group, so a collapsed row cannot hide the one instance that is failing. */
|
|
50446
|
+
groupStatus(group) {
|
|
50447
|
+
const statuses = group.items.map((item) => this.host.queryStatus(item.query));
|
|
50448
|
+
if (statuses.includes('error'))
|
|
50449
|
+
return 'error';
|
|
50450
|
+
if (statuses.includes('loading'))
|
|
50451
|
+
return 'loading';
|
|
50452
|
+
if (statuses.includes('success'))
|
|
50453
|
+
return 'success';
|
|
50454
|
+
return 'idle';
|
|
50455
|
+
}
|
|
50456
|
+
isGroupStale(group) {
|
|
50457
|
+
return group.items.some((item) => this.host.isStale(item.query));
|
|
50458
|
+
}
|
|
50459
|
+
isGroupTampered(group) {
|
|
50460
|
+
return group.items.some((item) => this.host.isTampered(item.entry));
|
|
50461
|
+
}
|
|
50462
|
+
/**
|
|
50463
|
+
* A group opens when the user opens it, and always while it holds the selected query - a detail pane
|
|
50464
|
+
* showing a query with no row to match it reads as the list having lost it.
|
|
50465
|
+
*/
|
|
50466
|
+
isGroupExpanded(group) {
|
|
50467
|
+
return (this.host.expandedQueryGroups().has(group.key) ||
|
|
50468
|
+
group.items.some((item) => item.entry.id === this.host.selectedQueryId()));
|
|
50469
|
+
}
|
|
50302
50470
|
forgetGoneQueries() {
|
|
50303
|
-
clearQueryDevtoolsTombstones();
|
|
50471
|
+
clearQueryDevtoolsTombstones(this.listedGoneQueries().map((item) => item.entry.id));
|
|
50304
50472
|
// Left lit, the chip would narrow the list to the tombstones that were just dropped - an empty list.
|
|
50305
|
-
|
|
50306
|
-
this.host.toggleFacet('gone');
|
|
50473
|
+
this.host.toggleFacet('gone');
|
|
50307
50474
|
}
|
|
50308
50475
|
downloadInsomniaCollection() {
|
|
50309
50476
|
this.host.downloadInsomniaCollection(this.filteredQueries(), this.host.selectedClientName());
|
|
50310
50477
|
}
|
|
50478
|
+
/**
|
|
50479
|
+
* When a query last ran, or `null` for one that never has. A tombstone's is frozen at whatever it held
|
|
50480
|
+
* when it died, so `destroyedAt` is the tiebreak that keeps gone entries ordered among themselves.
|
|
50481
|
+
*/
|
|
50482
|
+
lastExecutedAt(item) {
|
|
50483
|
+
return item.query.lastTimeExecutedAt() ?? item.entry.destroyedAt ?? null;
|
|
50484
|
+
}
|
|
50311
50485
|
/**
|
|
50312
50486
|
* A tombstone is the last state a query held, not a state it is in, so the list leaves one out unless the
|
|
50313
50487
|
* Gone chip asks for it - or the detail is showing it, so a query dying under the detail keeps its row.
|
|
@@ -50316,7 +50490,23 @@ class QueryDevtoolsQueriesTabComponent {
|
|
|
50316
50490
|
return facets.has('gone') || (!facets.size && entry.id === this.host.selectedQueryId());
|
|
50317
50491
|
}
|
|
50318
50492
|
/**
|
|
50319
|
-
*
|
|
50493
|
+
* Newest or oldest run first. A query that has **never** executed has no place on a time axis, so it
|
|
50494
|
+
* sinks to the bottom in *both* directions rather than piling up at whichever end `null` sorts to -
|
|
50495
|
+
* flipping the arrow must not turn the list into the queries that have not run yet.
|
|
50496
|
+
*/
|
|
50497
|
+
byLastExecuted(items) {
|
|
50498
|
+
const recentFirst = this.host.queryRecentFirst();
|
|
50499
|
+
// Copied first: `items` came out of a computed and `sort` is in place.
|
|
50500
|
+
return items.slice().sort((a, b) => {
|
|
50501
|
+
const left = this.lastExecutedAt(a);
|
|
50502
|
+
const right = this.lastExecutedAt(b);
|
|
50503
|
+
if (left === null || right === null)
|
|
50504
|
+
return Number(left === null) - Number(right === null);
|
|
50505
|
+
return recentFirst ? right - left : left - right;
|
|
50506
|
+
});
|
|
50507
|
+
}
|
|
50508
|
+
/**
|
|
50509
|
+
* Pinned queries first, everything else in {@link byLastExecuted} order. A chip could not do this job:
|
|
50320
50510
|
* {@link matchesFacets} widens, so a Pinned chip would mean "pinned or failing" and never both.
|
|
50321
50511
|
*/
|
|
50322
50512
|
pinnedFirst(items) {
|
|
@@ -50335,6 +50525,14 @@ class QueryDevtoolsQueriesTabComponent {
|
|
|
50335
50525
|
(facets.has('idle') && status === 'idle') ||
|
|
50336
50526
|
(facets.has('stale') && this.host.isStale(item.query)));
|
|
50337
50527
|
}
|
|
50528
|
+
/** What makes two rows indistinguishable on screen. A tombstone never folds into a live query. */
|
|
50529
|
+
groupKey(item) {
|
|
50530
|
+
const route = this.host
|
|
50531
|
+
.routeSegments(item.entry, item.query)
|
|
50532
|
+
.map((segment) => segment.text)
|
|
50533
|
+
.join('');
|
|
50534
|
+
return `${item.entry.destroyedAt ? 'gone' : 'live'}|${item.entry.meta.method ?? ''}|${route}`;
|
|
50535
|
+
}
|
|
50338
50536
|
/**
|
|
50339
50537
|
* What the search box matches against: what the row shows, plus the path of the request that ran for a
|
|
50340
50538
|
* query whose template differs from it.
|
|
@@ -50352,11 +50550,11 @@ class QueryDevtoolsQueriesTabComponent {
|
|
|
50352
50550
|
return parts.join(' ').toLowerCase();
|
|
50353
50551
|
}
|
|
50354
50552
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsQueriesTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50355
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsQueriesTabComponent, isStandalone: true, selector: "et-query-devtools-queries-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div [class.et-query-devtools-toolbar--filtered]=\"!!host.inspectFilterIds()\" class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n @if (host.inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\n <span class=\"et-query-devtools-filter-icon\" aria-hidden=\"true\">\u2316</span>\n Inspected element\n <span class=\"et-query-devtools-filter-count\">{{ ids.length }}</span>\n </span>\n <button\n (click)=\"host.clearInspectFilter()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the inspection filter and show all queries\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Clear\n </button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"host.selectedClientName() ?? ''\"\n (change)=\"host.selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of host.clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">\n @if (isQueryListNarrowed()) {\n {{ filteredQueries().length }} of {{ scopedQueryCount() }}\n } @else {\n {{ scopedQueryCount() }}\n }\n </span>\n <button\n [disabled]=\"!filteredQueries().length\"\n (click)=\"downloadInsomniaCollection()\"\n class=\"et-query-devtools-btn et-query-devtools-toolbar-btn\"\n type=\"button\"\n title=\"Download the listed queries as an Insomnia collection, with the auth provider's token refresh\"\n >\n \u2913 Insomnia\n </button>\n </div>\n\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #queryFilterInput\n [value]=\"host.queryFilter()\"\n (input)=\"host.queryFilter.set(queryFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter method / route / url\u2026\"\n aria-label=\"Filter queries\"\n />\n @for (facet of facets; track facet.id) {\n @let count = facetCounts()[facet.id];\n @let isActive = host.queryFacets().has(facet.id);\n <button\n [class.et-query-devtools-facet--active]=\"isActive\"\n [attr.aria-pressed]=\"isActive\"\n [disabled]=\"!count && !isActive\"\n (click)=\"host.toggleFacet(facet.id)\"\n class=\"et-query-devtools-chip et-query-devtools-facet\"\n type=\"button\"\n >\n {{ facet.label }}\n <span class=\"et-query-devtools-facet-count\">{{ count }}</span>\n </button>\n }\n @if (goneQueryCount()) {\n <button\n (click)=\"forgetGoneQueries()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Forget every destroyed query the panel is still holding\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Forget\n </button>\n }\n @if (isQueryListNarrowed()) {\n <button\n (click)=\"host.clearQueryFilters()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the search term and the status chips\"\n aria-label=\"Clear filters\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n\n @for (item of filteredQueries(); track item.entry.id) {\n @let isGone = !!item.entry.destroyedAt;\n @let isPinned = host.isQueryPinned(item.entry);\n @let pinLabel = isPinned ? 'Unpin this query' : 'Pin this query to the top of the list';\n <div\n [class.et-query-devtools-row--active]=\"host.selectedQueryId() === item.entry.id\"\n [class.et-query-devtools-row--gone]=\"isGone\"\n class=\"et-query-devtools-row\"\n >\n <button (click)=\"host.selectedQueryId.set(item.entry.id)\" class=\"et-query-devtools-row-select\" type=\"button\">\n <span\n [attr.data-status]=\"isGone ? null : host.queryStatus(item.query)\"\n [title]=\"isGone ? 'destroyed' : host.queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(item.entry, item.query)\" />\n </span>\n @if (isGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"This query no longer exists - what you see is the last state it held, frozen\"\n >\n gone\n </span>\n }\n <!-- A retry is the one thing a loading dot actively misrepresents: it reads as a request\n on its way when nothing is in flight at all. -->\n @if (!isGone && host.requestProgress(item.query)?.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Waiting out a retry backoff before attempt {{ retry.attempt }}\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ retry.attempt }}\n </span>\n }\n @if (!isGone && host.isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (host.isTampered(item.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n </button>\n <button\n [class.et-query-devtools-row-pin--active]=\"isPinned\"\n [title]=\"pinLabel\"\n [attr.aria-label]=\"pinLabel\"\n [attr.aria-pressed]=\"isPinned\"\n (click)=\"host.toggleQueryPin(item.entry)\"\n class=\"et-query-devtools-row-pin\"\n type=\"button\"\n >\n <span aria-hidden=\"true\">{{ isPinned ? '\u2605' : '\u2606' }}</span>\n </button>\n </div>\n } @empty {\n <!-- An empty scope is a different problem from a filter that matches nothing, and only the\n latter is the user's own doing - so it names the way out. -->\n @if (scopedQueryCount()) {\n <p class=\"et-query-devtools-empty\">No query matches the filter \u00B7 {{ scopedQueryCount() }} in scope.</p>\n } @else if (goneQueryCount()) {\n <p class=\"et-query-devtools-empty\">\n No query in scope still exists \u00B7 pick Gone to list the {{ goneQueryCount() }} destroyed.\n </p>\n } @else if (host.inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Clear the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n </div>\n\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'list', container: panes })\"\n (dblclick)=\"host.resetPaneSize('list')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <div class=\"et-query-devtools-detail\">\n @if (host.selectedQuery(); as sel) {\n <et-query-devtools-detail [sel]=\"sel\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsDetailComponent, selector: "et-query-devtools-detail", inputs: ["sel"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50553
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsQueriesTabComponent, isStandalone: true, selector: "et-query-devtools-queries-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div [class.et-query-devtools-toolbar--filtered]=\"!!host.inspectFilterIds()\" class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n @if (host.inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\n <span class=\"et-query-devtools-filter-icon\" aria-hidden=\"true\">\u2316</span>\n Inspected element\n <span class=\"et-query-devtools-filter-count\">{{ ids.length }}</span>\n </span>\n <button\n (click)=\"host.clearInspectFilter()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the inspection filter and show all queries\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Clear\n </button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"host.selectedClientName() ?? ''\"\n (change)=\"host.selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of host.clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">\n @if (isQueryListNarrowed()) {\n {{ filteredQueries().length }} of {{ scopedQueryCount() }}\n } @else {\n {{ scopedQueryCount() }}\n }\n </span>\n <button\n [disabled]=\"!filteredQueries().length\"\n (click)=\"downloadInsomniaCollection()\"\n class=\"et-query-devtools-btn et-query-devtools-toolbar-btn\"\n type=\"button\"\n title=\"Download the listed queries as an Insomnia collection, with the auth provider's token refresh\"\n >\n \u2913 Insomnia\n </button>\n </div>\n\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #queryFilterInput\n [value]=\"host.queryFilter()\"\n (input)=\"host.queryFilter.set(queryFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter method / route / url\u2026\"\n aria-label=\"Filter queries\"\n />\n @let recentFirst = host.queryRecentFirst();\n <button\n [title]=\"\n (recentFirst ? 'Newest run first.' : 'Oldest run first.') +\n ' Click to reverse. Queries that have never run stay at the bottom either way.'\n \"\n (click)=\"host.queryRecentFirst.set(!recentFirst)\"\n class=\"et-query-devtools-btn et-query-devtools-sort\"\n type=\"button\"\n >\n recent <span aria-hidden=\"true\">{{ recentFirst ? '\u2193' : '\u2191' }}</span>\n </button>\n @for (facet of facets; track facet.id) {\n @let count = facetCounts()[facet.id];\n @let isActive = host.queryFacets().has(facet.id);\n <button\n [class.et-query-devtools-facet--active]=\"isActive\"\n [attr.aria-pressed]=\"isActive\"\n [disabled]=\"!count && !isActive\"\n (click)=\"host.toggleFacet(facet.id)\"\n class=\"et-query-devtools-chip et-query-devtools-facet\"\n type=\"button\"\n >\n {{ facet.label }}\n <span class=\"et-query-devtools-facet-count\">{{ count }}</span>\n </button>\n }\n @let goneListed = listedGoneQueries().length;\n @if (goneListed) {\n <button\n (click)=\"forgetGoneQueries()\"\n class=\"et-query-devtools-forget\"\n type=\"button\"\n title=\"Drop the {{ goneListed }} destroyed queries listed below - they cannot be brought back\"\n >\n Forget {{ goneListed }}\n </button>\n }\n @if (isQueryListNarrowed()) {\n <button\n (click)=\"host.clearQueryFilters()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the search term and the status chips\"\n aria-label=\"Clear filters\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n\n @for (group of queryGroups(); track group.key) {\n @if (group.items.length === 1) {\n <ng-container [ngTemplateOutlet]=\"queryRow\" [ngTemplateOutletContext]=\"{ item: group.head }\" />\n } @else {\n @let expanded = isGroupExpanded(group);\n @let head = group.head;\n @let groupGone = !!head.entry.destroyedAt;\n <div class=\"et-query-devtools-row et-query-devtools-row--group\">\n <button\n [attr.aria-expanded]=\"expanded\"\n [title]=\"\n (expanded ? 'Collapse' : 'Expand') +\n ' the ' +\n group.items.length +\n ' consumers of this query - one registry entry each'\n \"\n (click)=\"host.toggleQueryGroup(group.key)\"\n class=\"et-query-devtools-row-select\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-row-caret\" aria-hidden=\"true\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <span\n [attr.data-status]=\"groupGone ? null : groupStatus(group)\"\n [title]=\"groupGone ? 'destroyed' : groupStatus(group)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ head.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(head.entry, head.query)\" />\n </span>\n @if (groupGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"These queries no longer exist - what you see is the last state they held, frozen\"\n >\n gone\n </span>\n }\n @if (!groupGone && isGroupStale(group)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (isGroupTampered(group)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"At least one of these is showing an armed response override or a devtools-injected failure\"\n >\n tampered\n </span>\n }\n <span class=\"et-query-devtools-row-count\">\u00D7{{ group.items.length }}</span>\n <span class=\"et-query-devtools-row-time\">{{ host.formatTime(lastExecutedAt(head)) }}</span>\n </button>\n </div>\n @if (expanded) {\n @for (item of group.items; track item.entry.id) {\n <ng-container [ngTemplateOutlet]=\"queryRow\" [ngTemplateOutletContext]=\"{ item, nested: true }\" />\n }\n }\n }\n } @empty {\n <!-- An empty scope is a different problem from a filter that matches nothing, and only the\n latter is the user's own doing - so it names the way out. -->\n @if (scopedQueryCount()) {\n <p class=\"et-query-devtools-empty\">No query matches the filter \u00B7 {{ scopedQueryCount() }} in scope.</p>\n } @else if (goneQueryCount()) {\n <p class=\"et-query-devtools-empty\">\n No query in scope still exists \u00B7 pick Gone to list the {{ goneQueryCount() }} destroyed.\n </p>\n } @else if (host.inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Clear the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n\n <ng-template #queryRow let-item=\"item\" let-nested=\"nested\">\n @let isGone = !!item.entry.destroyedAt;\n @let isPinned = host.isQueryPinned(item.entry);\n @let pinLabel = isPinned ? 'Unpin this query' : 'Pin this query to the top of the list';\n <div\n [class.et-query-devtools-row--active]=\"host.selectedQueryId() === item.entry.id\"\n [class.et-query-devtools-row--gone]=\"isGone\"\n [class.et-query-devtools-row--nested]=\"nested\"\n class=\"et-query-devtools-row\"\n >\n <button (click)=\"host.selectedQueryId.set(item.entry.id)\" class=\"et-query-devtools-row-select\" type=\"button\">\n <span class=\"et-query-devtools-row-caret\" aria-hidden=\"true\"></span>\n <span\n [attr.data-status]=\"isGone ? null : host.queryStatus(item.query)\"\n [title]=\"isGone ? 'destroyed' : host.queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(item.entry, item.query)\" />\n </span>\n @if (isGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"This query no longer exists - what you see is the last state it held, frozen\"\n >\n gone\n </span>\n }\n <!-- A retry is the one thing a loading dot actively misrepresents: it reads as a request\n on its way when nothing is in flight at all. -->\n @if (!isGone && host.requestProgress(item.query)?.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Waiting out a retry backoff before attempt {{ retry.attempt }}\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ retry.attempt }}\n </span>\n }\n @if (!isGone && host.isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (host.isTampered(item.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n <span class=\"et-query-devtools-row-time\">{{ host.formatTime(lastExecutedAt(item)) }}</span>\n </button>\n <button\n [class.et-query-devtools-row-pin--active]=\"isPinned\"\n [title]=\"pinLabel\"\n [attr.aria-label]=\"pinLabel\"\n [attr.aria-pressed]=\"isPinned\"\n (click)=\"host.toggleQueryPin(item.entry)\"\n class=\"et-query-devtools-row-pin\"\n type=\"button\"\n >\n <span aria-hidden=\"true\">{{ isPinned ? '\u2605' : '\u2606' }}</span>\n </button>\n </div>\n </ng-template>\n </div>\n\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'list', container: panes })\"\n (dblclick)=\"host.resetPaneSize('list')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <div class=\"et-query-devtools-detail\">\n @if (host.selectedQuery(); as sel) {\n <et-query-devtools-detail [sel]=\"sel\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n</div>\n", styles: ["@layer components{.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 var(--_et-qdt-list-width, 34%);min-inline-size:var(--_et-qdt-list-width, 22rem);max-inline-size:var(--_et-qdt-list-width, 40rem);overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-forget{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid color-mix(in srgb,var(--_et-qdt-error) 50%,transparent);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-error) 10%,transparent);color:var(--_et-qdt-error);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-forget:hover{border-color:var(--_et-qdt-error);background:color-mix(in srgb,var(--_et-qdt-error) 22%,transparent)}.et-query-devtools-list .et-query-devtools-toolbar-row .et-query-devtools-search{flex:1 1 100%}.et-query-devtools-toolbar--filtered{background:linear-gradient(to right,color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent),transparent 65%),var(--_et-qdt-bg);box-shadow:inset .2rem 0 0 var(--_et-qdt-accent),inset 0 -1px color-mix(in srgb,var(--_et-qdt-accent) 30%,transparent)}.et-query-devtools-row-select{display:flex;flex:1 1 auto;align-items:center;gap:.8rem;min-inline-size:0;text-align:start;appearance:none;border:none;background:transparent;color:inherit;padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row-select>.et-query-devtools-chip{padding-block:.1rem;line-height:1.2}.et-query-devtools-row-pin{display:flex;flex:0 0 auto;align-self:center;align-items:center;justify-content:center;inline-size:3.2rem;block-size:3.2rem;margin-inline-end:.4rem;appearance:none;border:none;border-radius:.4rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font-family:inherit;font-size:1.8rem;line-height:1;opacity:0}.et-query-devtools-row:hover .et-query-devtools-row-pin,.et-query-devtools-row-pin:focus-visible,.et-query-devtools-row-pin--active{opacity:1}.et-query-devtools-row-pin:hover{background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-row-pin--active,.et-query-devtools-row-pin--active:hover{color:var(--_et-qdt-accent)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-row--gone{color:var(--_et-qdt-muted)}.et-query-devtools-row-caret{flex:0 0 auto;inline-size:1rem;color:var(--_et-qdt-subtle);font-size:1rem;line-height:1}.et-query-devtools-row--group>.et-query-devtools-row-select{padding-inline-end:4.4rem}.et-query-devtools-row--nested>.et-query-devtools-row-select{padding-inline-start:2.6rem}.et-query-devtools-row--group{background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent)}.et-query-devtools-row-count{flex:0 0 auto;color:var(--_et-qdt-subtle);font-variant-numeric:tabular-nums;font-size:1.1rem}.et-query-devtools-row-time{flex:0 0 auto;inline-size:8ch;text-align:end;color:var(--_et-qdt-subtle);font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.1rem}.et-query-devtools-sort{flex:0 0 auto;color:var(--_et-qdt-muted)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QueryDevtoolsDetailComponent, selector: "et-query-devtools-detail", inputs: ["sel"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50356
50554
|
}
|
|
50357
50555
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsQueriesTabComponent, decorators: [{
|
|
50358
50556
|
type: Component,
|
|
50359
|
-
args: [{ selector: 'et-query-devtools-queries-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDetailComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div [class.et-query-devtools-toolbar--filtered]=\"!!host.inspectFilterIds()\" class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n @if (host.inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\n <span class=\"et-query-devtools-filter-icon\" aria-hidden=\"true\">\u2316</span>\n Inspected element\n <span class=\"et-query-devtools-filter-count\">{{ ids.length }}</span>\n </span>\n <button\n (click)=\"host.clearInspectFilter()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the inspection filter and show all queries\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Clear\n </button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"host.selectedClientName() ?? ''\"\n (change)=\"host.selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of host.clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">\n @if (isQueryListNarrowed()) {\n {{ filteredQueries().length }} of {{ scopedQueryCount() }}\n } @else {\n {{ scopedQueryCount() }}\n }\n </span>\n <button\n [disabled]=\"!filteredQueries().length\"\n (click)=\"downloadInsomniaCollection()\"\n class=\"et-query-devtools-btn et-query-devtools-toolbar-btn\"\n type=\"button\"\n title=\"Download the listed queries as an Insomnia collection, with the auth provider's token refresh\"\n >\n \u2913 Insomnia\n </button>\n </div>\n\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #queryFilterInput\n [value]=\"host.queryFilter()\"\n (input)=\"host.queryFilter.set(queryFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter method / route / url\u2026\"\n aria-label=\"Filter queries\"\n />\n @for (facet of facets; track facet.id) {\n @let count = facetCounts()[facet.id];\n @let isActive = host.queryFacets().has(facet.id);\n <button\n [class.et-query-devtools-facet--active]=\"isActive\"\n [attr.aria-pressed]=\"isActive\"\n [disabled]=\"!count && !isActive\"\n (click)=\"host.toggleFacet(facet.id)\"\n class=\"et-query-devtools-chip et-query-devtools-facet\"\n type=\"button\"\n >\n {{ facet.label }}\n <span class=\"et-query-devtools-facet-count\">{{ count }}</span>\n </button>\n }\n @if (goneQueryCount()) {\n <button\n (click)=\"forgetGoneQueries()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Forget every destroyed query the panel is still holding\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Forget\n </button>\n }\n @if (isQueryListNarrowed()) {\n <button\n (click)=\"host.clearQueryFilters()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the search term and the status chips\"\n aria-label=\"Clear filters\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n\n @for (item of filteredQueries(); track item.entry.id) {\n @let isGone = !!item.entry.destroyedAt;\n @let isPinned = host.isQueryPinned(item.entry);\n @let pinLabel = isPinned ? 'Unpin this query' : 'Pin this query to the top of the list';\n <div\n [class.et-query-devtools-row--active]=\"host.selectedQueryId() === item.entry.id\"\n [class.et-query-devtools-row--gone]=\"isGone\"\n class=\"et-query-devtools-row\"\n >\n <button (click)=\"host.selectedQueryId.set(item.entry.id)\" class=\"et-query-devtools-row-select\" type=\"button\">\n <span\n [attr.data-status]=\"isGone ? null : host.queryStatus(item.query)\"\n [title]=\"isGone ? 'destroyed' : host.queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(item.entry, item.query)\" />\n </span>\n @if (isGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"This query no longer exists - what you see is the last state it held, frozen\"\n >\n gone\n </span>\n }\n <!-- A retry is the one thing a loading dot actively misrepresents: it reads as a request\n on its way when nothing is in flight at all. -->\n @if (!isGone && host.requestProgress(item.query)?.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Waiting out a retry backoff before attempt {{ retry.attempt }}\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ retry.attempt }}\n </span>\n }\n @if (!isGone && host.isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (host.isTampered(item.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n </button>\n <button\n [class.et-query-devtools-row-pin--active]=\"isPinned\"\n [title]=\"pinLabel\"\n [attr.aria-label]=\"pinLabel\"\n [attr.aria-pressed]=\"isPinned\"\n (click)=\"host.toggleQueryPin(item.entry)\"\n class=\"et-query-devtools-row-pin\"\n type=\"button\"\n >\n <span aria-hidden=\"true\">{{ isPinned ? '\u2605' : '\u2606' }}</span>\n </button>\n </div>\n } @empty {\n <!-- An empty scope is a different problem from a filter that matches nothing, and only the\n latter is the user's own doing - so it names the way out. -->\n @if (scopedQueryCount()) {\n <p class=\"et-query-devtools-empty\">No query matches the filter \u00B7 {{ scopedQueryCount() }} in scope.</p>\n } @else if (goneQueryCount()) {\n <p class=\"et-query-devtools-empty\">\n No query in scope still exists \u00B7 pick Gone to list the {{ goneQueryCount() }} destroyed.\n </p>\n } @else if (host.inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Clear the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n </div>\n\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'list', container: panes })\"\n (dblclick)=\"host.resetPaneSize('list')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <div class=\"et-query-devtools-detail\">\n @if (host.selectedQuery(); as sel) {\n <et-query-devtools-detail [sel]=\"sel\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n</div>\n" }]
|
|
50557
|
+
args: [{ selector: 'et-query-devtools-queries-tab', encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet, QueryDevtoolsDetailComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-master-detail\">\n <div class=\"et-query-devtools-list\">\n <div [class.et-query-devtools-toolbar--filtered]=\"!!host.inspectFilterIds()\" class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n @if (host.inspectFilterIds(); as ids) {\n <span class=\"et-query-devtools-filter-chip\">\n <span class=\"et-query-devtools-filter-icon\" aria-hidden=\"true\">\u2316</span>\n Inspected element\n <span class=\"et-query-devtools-filter-count\">{{ ids.length }}</span>\n </span>\n <button\n (click)=\"host.clearInspectFilter()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the inspection filter and show all queries\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n Clear\n </button>\n } @else {\n <label class=\"et-query-devtools-field\">\n <span>Client</span>\n <select\n #clientSelect\n [value]=\"host.selectedClientName() ?? ''\"\n (change)=\"host.selectClient(clientSelect.value || null)\"\n class=\"et-query-devtools-select\"\n >\n <option value=\"\">All clients</option>\n @for (name of host.clientNames(); track name) {\n <option [value]=\"name\">{{ name }}</option>\n }\n </select>\n </label>\n }\n <span class=\"et-query-devtools-count\">\n @if (isQueryListNarrowed()) {\n {{ filteredQueries().length }} of {{ scopedQueryCount() }}\n } @else {\n {{ scopedQueryCount() }}\n }\n </span>\n <button\n [disabled]=\"!filteredQueries().length\"\n (click)=\"downloadInsomniaCollection()\"\n class=\"et-query-devtools-btn et-query-devtools-toolbar-btn\"\n type=\"button\"\n title=\"Download the listed queries as an Insomnia collection, with the auth provider's token refresh\"\n >\n \u2913 Insomnia\n </button>\n </div>\n\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #queryFilterInput\n [value]=\"host.queryFilter()\"\n (input)=\"host.queryFilter.set(queryFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter method / route / url\u2026\"\n aria-label=\"Filter queries\"\n />\n @let recentFirst = host.queryRecentFirst();\n <button\n [title]=\"\n (recentFirst ? 'Newest run first.' : 'Oldest run first.') +\n ' Click to reverse. Queries that have never run stay at the bottom either way.'\n \"\n (click)=\"host.queryRecentFirst.set(!recentFirst)\"\n class=\"et-query-devtools-btn et-query-devtools-sort\"\n type=\"button\"\n >\n recent <span aria-hidden=\"true\">{{ recentFirst ? '\u2193' : '\u2191' }}</span>\n </button>\n @for (facet of facets; track facet.id) {\n @let count = facetCounts()[facet.id];\n @let isActive = host.queryFacets().has(facet.id);\n <button\n [class.et-query-devtools-facet--active]=\"isActive\"\n [attr.aria-pressed]=\"isActive\"\n [disabled]=\"!count && !isActive\"\n (click)=\"host.toggleFacet(facet.id)\"\n class=\"et-query-devtools-chip et-query-devtools-facet\"\n type=\"button\"\n >\n {{ facet.label }}\n <span class=\"et-query-devtools-facet-count\">{{ count }}</span>\n </button>\n }\n @let goneListed = listedGoneQueries().length;\n @if (goneListed) {\n <button\n (click)=\"forgetGoneQueries()\"\n class=\"et-query-devtools-forget\"\n type=\"button\"\n title=\"Drop the {{ goneListed }} destroyed queries listed below - they cannot be brought back\"\n >\n Forget {{ goneListed }}\n </button>\n }\n @if (isQueryListNarrowed()) {\n <button\n (click)=\"host.clearQueryFilters()\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the search term and the status chips\"\n aria-label=\"Clear filters\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n\n @for (group of queryGroups(); track group.key) {\n @if (group.items.length === 1) {\n <ng-container [ngTemplateOutlet]=\"queryRow\" [ngTemplateOutletContext]=\"{ item: group.head }\" />\n } @else {\n @let expanded = isGroupExpanded(group);\n @let head = group.head;\n @let groupGone = !!head.entry.destroyedAt;\n <div class=\"et-query-devtools-row et-query-devtools-row--group\">\n <button\n [attr.aria-expanded]=\"expanded\"\n [title]=\"\n (expanded ? 'Collapse' : 'Expand') +\n ' the ' +\n group.items.length +\n ' consumers of this query - one registry entry each'\n \"\n (click)=\"host.toggleQueryGroup(group.key)\"\n class=\"et-query-devtools-row-select\"\n type=\"button\"\n >\n <span class=\"et-query-devtools-row-caret\" aria-hidden=\"true\">{{ expanded ? '\u25BE' : '\u25B8' }}</span>\n <span\n [attr.data-status]=\"groupGone ? null : groupStatus(group)\"\n [title]=\"groupGone ? 'destroyed' : groupStatus(group)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ head.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(head.entry, head.query)\" />\n </span>\n @if (groupGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"These queries no longer exist - what you see is the last state they held, frozen\"\n >\n gone\n </span>\n }\n @if (!groupGone && isGroupStale(group)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (isGroupTampered(group)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"At least one of these is showing an armed response override or a devtools-injected failure\"\n >\n tampered\n </span>\n }\n <span class=\"et-query-devtools-row-count\">\u00D7{{ group.items.length }}</span>\n <span class=\"et-query-devtools-row-time\">{{ host.formatTime(lastExecutedAt(head)) }}</span>\n </button>\n </div>\n @if (expanded) {\n @for (item of group.items; track item.entry.id) {\n <ng-container [ngTemplateOutlet]=\"queryRow\" [ngTemplateOutletContext]=\"{ item, nested: true }\" />\n }\n }\n }\n } @empty {\n <!-- An empty scope is a different problem from a filter that matches nothing, and only the\n latter is the user's own doing - so it names the way out. -->\n @if (scopedQueryCount()) {\n <p class=\"et-query-devtools-empty\">No query matches the filter \u00B7 {{ scopedQueryCount() }} in scope.</p>\n } @else if (goneQueryCount()) {\n <p class=\"et-query-devtools-empty\">\n No query in scope still exists \u00B7 pick Gone to list the {{ goneQueryCount() }} destroyed.\n </p>\n } @else if (host.inspectFilterIds()) {\n <p class=\"et-query-devtools-empty\">\n The inspected element's queries are no longer registered. Clear the filter.\n </p>\n } @else {\n <p class=\"et-query-devtools-empty\">No queries registered.</p>\n }\n }\n\n <ng-template #queryRow let-item=\"item\" let-nested=\"nested\">\n @let isGone = !!item.entry.destroyedAt;\n @let isPinned = host.isQueryPinned(item.entry);\n @let pinLabel = isPinned ? 'Unpin this query' : 'Pin this query to the top of the list';\n <div\n [class.et-query-devtools-row--active]=\"host.selectedQueryId() === item.entry.id\"\n [class.et-query-devtools-row--gone]=\"isGone\"\n [class.et-query-devtools-row--nested]=\"nested\"\n class=\"et-query-devtools-row\"\n >\n <button (click)=\"host.selectedQueryId.set(item.entry.id)\" class=\"et-query-devtools-row-select\" type=\"button\">\n <span class=\"et-query-devtools-row-caret\" aria-hidden=\"true\"></span>\n <span\n [attr.data-status]=\"isGone ? null : host.queryStatus(item.query)\"\n [title]=\"isGone ? 'destroyed' : host.queryStatus(item.query)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ item.entry.meta.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"host.routeSegments(item.entry, item.query)\" />\n </span>\n @if (isGone) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--muted\"\n title=\"This query no longer exists - what you see is the last state it held, frozen\"\n >\n gone\n </span>\n }\n <!-- A retry is the one thing a loading dot actively misrepresents: it reads as a request\n on its way when nothing is in flight at all. -->\n @if (!isGone && host.requestProgress(item.query)?.retry; as retry) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--loading\"\n title=\"Waiting out a retry backoff before attempt {{ retry.attempt }}\"\n >\n <span class=\"et-query-devtools-retry-glyph\" aria-hidden=\"true\">\u27F3</span>\n {{ retry.attempt }}\n </span>\n }\n @if (!isGone && host.isStale(item.query)) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">stale</span>\n }\n @if (host.isTampered(item.entry)) {\n <span\n class=\"et-query-devtools-chip et-query-devtools-chip--error\"\n title=\"Showing an armed response override or a devtools-injected failure, not what the server actually sent\"\n >\n tampered\n </span>\n }\n <span class=\"et-query-devtools-row-time\">{{ host.formatTime(lastExecutedAt(item)) }}</span>\n </button>\n <button\n [class.et-query-devtools-row-pin--active]=\"isPinned\"\n [title]=\"pinLabel\"\n [attr.aria-label]=\"pinLabel\"\n [attr.aria-pressed]=\"isPinned\"\n (click)=\"host.toggleQueryPin(item.entry)\"\n class=\"et-query-devtools-row-pin\"\n type=\"button\"\n >\n <span aria-hidden=\"true\">{{ isPinned ? '\u2605' : '\u2606' }}</span>\n </button>\n </div>\n </ng-template>\n </div>\n\n <div\n (pointerdown)=\"host.startPaneResize($event, { pane: 'list', container: panes })\"\n (dblclick)=\"host.resetPaneSize('list')\"\n class=\"et-query-devtools-pane-resize\"\n title=\"Drag to resize, double-click to reset\"\n aria-hidden=\"true\"\n ></div>\n\n <div class=\"et-query-devtools-detail\">\n @if (host.selectedQuery(); as sel) {\n <et-query-devtools-detail [sel]=\"sel\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Select a query to inspect it.</p>\n }\n </div>\n</div>\n", styles: ["@layer components{.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 var(--_et-qdt-list-width, 34%);min-inline-size:var(--_et-qdt-list-width, 22rem);max-inline-size:var(--_et-qdt-list-width, 40rem);overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-forget{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid color-mix(in srgb,var(--_et-qdt-error) 50%,transparent);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-error) 10%,transparent);color:var(--_et-qdt-error);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-forget:hover{border-color:var(--_et-qdt-error);background:color-mix(in srgb,var(--_et-qdt-error) 22%,transparent)}.et-query-devtools-list .et-query-devtools-toolbar-row .et-query-devtools-search{flex:1 1 100%}.et-query-devtools-toolbar--filtered{background:linear-gradient(to right,color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent),transparent 65%),var(--_et-qdt-bg);box-shadow:inset .2rem 0 0 var(--_et-qdt-accent),inset 0 -1px color-mix(in srgb,var(--_et-qdt-accent) 30%,transparent)}.et-query-devtools-row-select{display:flex;flex:1 1 auto;align-items:center;gap:.8rem;min-inline-size:0;text-align:start;appearance:none;border:none;background:transparent;color:inherit;padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row-select>.et-query-devtools-chip{padding-block:.1rem;line-height:1.2}.et-query-devtools-row-pin{display:flex;flex:0 0 auto;align-self:center;align-items:center;justify-content:center;inline-size:3.2rem;block-size:3.2rem;margin-inline-end:.4rem;appearance:none;border:none;border-radius:.4rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font-family:inherit;font-size:1.8rem;line-height:1;opacity:0}.et-query-devtools-row:hover .et-query-devtools-row-pin,.et-query-devtools-row-pin:focus-visible,.et-query-devtools-row-pin--active{opacity:1}.et-query-devtools-row-pin:hover{background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-row-pin--active,.et-query-devtools-row-pin--active:hover{color:var(--_et-qdt-accent)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-row--gone{color:var(--_et-qdt-muted)}.et-query-devtools-row-caret{flex:0 0 auto;inline-size:1rem;color:var(--_et-qdt-subtle);font-size:1rem;line-height:1}.et-query-devtools-row--group>.et-query-devtools-row-select{padding-inline-end:4.4rem}.et-query-devtools-row--nested>.et-query-devtools-row-select{padding-inline-start:2.6rem}.et-query-devtools-row--group{background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent)}.et-query-devtools-row-count{flex:0 0 auto;color:var(--_et-qdt-subtle);font-variant-numeric:tabular-nums;font-size:1.1rem}.et-query-devtools-row-time{flex:0 0 auto;inline-size:8ch;text-align:end;color:var(--_et-qdt-subtle);font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.1rem}.et-query-devtools-sort{flex:0 0 auto;color:var(--_et-qdt-muted)}}\n"] }]
|
|
50360
50558
|
}] });
|
|
50361
50559
|
|
|
50362
50560
|
/** The Sequences tab: registered `QuerySequence` instances, step-by-step, with a split-view drawer. */
|
|
@@ -50365,11 +50563,11 @@ class QueryDevtoolsSequencesTabComponent {
|
|
|
50365
50563
|
this.host = injectQueryDevtoolsHost();
|
|
50366
50564
|
}
|
|
50367
50565
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsSequencesTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50368
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsSequencesTabComponent, isStandalone: true, selector: "et-query-devtools-sequences-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.sequenceEntries(); track entry.id) {\n @let sequence = host.asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\">step {{ sequence.currentStep() }} / {{ sequence.total }}</span>\n </div>\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Traffic</dt>\n <dd>\n @let activity = host.sequenceActivity(sequence);\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n </dl>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of host.queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"host.sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"'step ' + (i + 1)\" />\n </span>\n </button>\n <button\n [attr.aria-expanded]=\"host.isStepExpanded(entry.id, i)\"\n (click)=\"host.toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ host.isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (host.isStepExpanded(entry.id, i)) {\n @let snap = host.stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.sequenceSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.sequenceSelectedQueryId.set(null)\"\n />\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50566
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsSequencesTabComponent, isStandalone: true, selector: "et-query-devtools-sequences-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.sequenceEntries(); track entry.id) {\n @let sequence = host.asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\">step {{ sequence.currentStep() }} / {{ sequence.total }}</span>\n </div>\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Traffic</dt>\n <dd>\n @let activity = host.sequenceActivity(sequence);\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n </dl>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of host.queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"host.sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"'step ' + (i + 1)\" />\n </span>\n </button>\n <button\n [attr.aria-expanded]=\"host.isStepExpanded(entry.id, i)\"\n (click)=\"host.toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ host.isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (host.isStepExpanded(entry.id, i)) {\n @let snap = host.stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.sequenceSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.sequenceSelectedQueryId.set(null)\"\n />\n</div>\n", styles: ["@layer components{.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50369
50567
|
}
|
|
50370
50568
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsSequencesTabComponent, decorators: [{
|
|
50371
50569
|
type: Component,
|
|
50372
|
-
args: [{ selector: 'et-query-devtools-sequences-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDrawerComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.sequenceEntries(); track entry.id) {\n @let sequence = host.asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\">step {{ sequence.currentStep() }} / {{ sequence.total }}</span>\n </div>\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Traffic</dt>\n <dd>\n @let activity = host.sequenceActivity(sequence);\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n </dl>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of host.queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"host.sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"'step ' + (i + 1)\" />\n </span>\n </button>\n <button\n [attr.aria-expanded]=\"host.isStepExpanded(entry.id, i)\"\n (click)=\"host.toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ host.isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (host.isStepExpanded(entry.id, i)) {\n @let snap = host.stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.sequenceSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.sequenceSelectedQueryId.set(null)\"\n />\n</div>\n" }]
|
|
50570
|
+
args: [{ selector: 'et-query-devtools-sequences-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsDrawerComponent, QueryDevtoolsJsonComponent, QueryDevtoolsRouteComponent], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.sequenceEntries(); track entry.id) {\n @let sequence = host.asSequence(entry);\n @if (sequence) {\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">sequence</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ sequence.status() }}</span>\n <span class=\"et-query-devtools-count\">step {{ sequence.currentStep() }} / {{ sequence.total }}</span>\n </div>\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Traffic</dt>\n <dd>\n @let activity = host.sequenceActivity(sequence);\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n </dl>\n\n <ol class=\"et-query-devtools-step-list\">\n @for (link of host.queriesForSequence(sequence); track $index; let i = $index) {\n <li [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\" class=\"et-query-devtools-step-item\">\n <div class=\"et-query-devtools-step-head\">\n <button\n [class.et-query-devtools-inner-row--active]=\"host.sequenceSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.sequenceSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span\n [attr.data-status]=\"host.sequenceStepStatus(sequence, i)\"\n class=\"et-query-devtools-status\"\n ></span>\n <span class=\"et-query-devtools-method\">{{ i + 1 }}. {{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"'step ' + (i + 1)\" />\n </span>\n </button>\n <button\n [attr.aria-expanded]=\"host.isStepExpanded(entry.id, i)\"\n (click)=\"host.toggleStep(entry.id, i)\"\n class=\"et-query-devtools-step-caret-btn\"\n type=\"button\"\n title=\"Toggle in / out\"\n >\n {{ host.isStepExpanded(entry.id, i) ? '\u25BE' : '\u25B8' }}\n </button>\n </div>\n\n @if (host.isStepExpanded(entry.id, i)) {\n @let snap = host.stepSnapshot(sequence, i);\n <div class=\"et-query-devtools-step-io\">\n <h5 class=\"et-query-devtools-section\">In \u00B7 args</h5>\n @if (sequence.stepArgs().length > i) {\n <et-query-devtools-json [value]=\"sequence.stepArgs()[i]\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n\n @if (snap?.error(); as error) {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 error ({{ error.raw.status }})</h5>\n <et-query-devtools-json [value]=\"error.isList ? error.errors : error.error\" />\n } @else {\n <h5 class=\"et-query-devtools-section\">Out \u00B7 response</h5>\n @if (snap) {\n <et-query-devtools-json [value]=\"snap.response()\" />\n } @else {\n <p class=\"et-query-devtools-empty\">Not run yet.</p>\n }\n }\n </div>\n }\n </li>\n }\n </ol>\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No sequences registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.sequenceSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.sequenceSelectedQueryId.set(null)\"\n />\n</div>\n", styles: ["@layer components{.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}}\n"] }]
|
|
50373
50571
|
}] });
|
|
50374
50572
|
|
|
50375
50573
|
/** The Sockets tab: registered `WebSocketDevtoolsHandle`s, their rooms, and a message log per client. */
|
|
@@ -50378,11 +50576,11 @@ class QueryDevtoolsSocketsTabComponent {
|
|
|
50378
50576
|
this.host = injectQueryDevtoolsHost();
|
|
50379
50577
|
}
|
|
50380
50578
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsSocketsTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50381
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsSocketsTabComponent, isStandalone: true, selector: "et-query-devtools-sockets-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @if (host.wsEntries().length) {\n <div class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #socketFilterInput\n [value]=\"host.socketFilter()\"\n (input)=\"host.socketFilter.set(socketFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter event / room / direction\u2026\"\n aria-label=\"Filter socket messages\"\n />\n @if (host.socketFilter()) {\n <button\n (click)=\"host.socketFilter.set('')\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the message filter\"\n aria-label=\"Clear the message filter\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n }\n\n @for (entry of host.wsEntries(); track entry.id) {\n @let ws = host.asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Emit</h5>\n <span class=\"et-query-devtools-hint\">\n Sends as the app would, so a server that only answers a client that asked can be provoked from here.\n </span>\n </div>\n <div class=\"et-query-devtools-emit\">\n <input #emitEvent class=\"et-query-devtools-input\" type=\"text\" placeholder=\"event\" aria-label=\"Event to emit\" />\n <input\n #emitData\n class=\"et-query-devtools-input\"\n type=\"text\"\n placeholder=\"JSON payload (optional)\"\n aria-label=\"Payload to emit\"\n />\n <button\n (click)=\"host.emitSocketMessage({ entry, event: emitEvent.value, data: emitData.value })\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u2191 Send\n </button>\n </div>\n @if (host.socketEmitErrorFor(entry.id); as emitError) {\n <p class=\"et-query-devtools-editor-error\">{{ emitError }}</p>\n }\n\n @let messages = host.socketMessages(ws);\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Messages</h5>\n <span class=\"et-query-devtools-count\">\n @if (host.socketFilter()) {\n {{ messages.length }} of {{ ws.messages().length }}\n } @else {\n {{ messages.length }}\n }\n </span>\n </div>\n @for (message of messages; track message.id) {\n <div [attr.data-direction]=\"message.direction\" class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ host.formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-ws-direction\">{{ host.socketDirectionLabel(message) }}</span>\n @if (message.room) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n }\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n @if (message.data !== undefined) {\n <et-query-devtools-json [value]=\"message.data\" />\n }\n </div>\n } @empty {\n @if (ws.messages().length) {\n <p class=\"et-query-devtools-empty\">No message matches the filter \u00B7 {{ ws.messages().length }} in the log.</p>\n } @else {\n <p class=\"et-query-devtools-empty\">Nothing sent or received yet.</p>\n }\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n</div>\n", dependencies: [{ kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50579
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsSocketsTabComponent, isStandalone: true, selector: "et-query-devtools-sockets-tab", ngImport: i0, template: "<div class=\"et-query-devtools-scroll\">\n @if (host.wsEntries().length) {\n <div class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #socketFilterInput\n [value]=\"host.socketFilter()\"\n (input)=\"host.socketFilter.set(socketFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter event / room / direction\u2026\"\n aria-label=\"Filter socket messages\"\n />\n @if (host.socketFilter()) {\n <button\n (click)=\"host.socketFilter.set('')\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the message filter\"\n aria-label=\"Clear the message filter\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n }\n\n @for (entry of host.wsEntries(); track entry.id) {\n @let ws = host.asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Emit</h5>\n <span class=\"et-query-devtools-hint\">\n Sends as the app would, so a server that only answers a client that asked can be provoked from here.\n </span>\n </div>\n <div class=\"et-query-devtools-emit\">\n <input #emitEvent class=\"et-query-devtools-input\" type=\"text\" placeholder=\"event\" aria-label=\"Event to emit\" />\n <input\n #emitData\n class=\"et-query-devtools-input\"\n type=\"text\"\n placeholder=\"JSON payload (optional)\"\n aria-label=\"Payload to emit\"\n />\n <button\n (click)=\"host.emitSocketMessage({ entry, event: emitEvent.value, data: emitData.value })\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u2191 Send\n </button>\n </div>\n @if (host.socketEmitErrorFor(entry.id); as emitError) {\n <p class=\"et-query-devtools-editor-error\">{{ emitError }}</p>\n }\n\n @let messages = host.socketMessages(ws);\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Messages</h5>\n <span class=\"et-query-devtools-count\">\n @if (host.socketFilter()) {\n {{ messages.length }} of {{ ws.messages().length }}\n } @else {\n {{ messages.length }}\n }\n </span>\n </div>\n @for (message of messages; track message.id) {\n <div [attr.data-direction]=\"message.direction\" class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ host.formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-ws-direction\">{{ host.socketDirectionLabel(message) }}</span>\n @if (message.room) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n }\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n @if (message.data !== undefined) {\n <et-query-devtools-json [value]=\"message.data\" />\n }\n </div>\n } @empty {\n @if (ws.messages().length) {\n <p class=\"et-query-devtools-empty\">No message matches the filter \u00B7 {{ ws.messages().length }} in the log.</p>\n } @else {\n <p class=\"et-query-devtools-empty\">Nothing sent or received yet.</p>\n }\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-ws-message:where([data-direction=out]){border-inline-start:2px solid color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-ws-direction{color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-ws-message:where([data-direction=out]) .et-query-devtools-ws-direction{color:var(--_et-qdt-accent)}.et-query-devtools-emit{display:flex;align-items:center;gap:.4rem;margin-block:.4rem}.et-query-devtools-emit .et-query-devtools-input{flex:0 0 14rem}.et-query-devtools-emit .et-query-devtools-input+.et-query-devtools-input{flex:1 1 auto}.et-query-devtools-emit .et-query-devtools-btn{flex:0 0 auto}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsJsonComponent, selector: "et-query-devtools-json", inputs: ["value", "nodeKey", "depth", "search", "chunk", "path", "expandedPaths", "collapsedPaths", "toggleFn", "jsonPath", "parentKind", "overrides"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50382
50580
|
}
|
|
50383
50581
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsSocketsTabComponent, decorators: [{
|
|
50384
50582
|
type: Component,
|
|
50385
|
-
args: [{ selector: 'et-query-devtools-sockets-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @if (host.wsEntries().length) {\n <div class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #socketFilterInput\n [value]=\"host.socketFilter()\"\n (input)=\"host.socketFilter.set(socketFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter event / room / direction\u2026\"\n aria-label=\"Filter socket messages\"\n />\n @if (host.socketFilter()) {\n <button\n (click)=\"host.socketFilter.set('')\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the message filter\"\n aria-label=\"Clear the message filter\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n }\n\n @for (entry of host.wsEntries(); track entry.id) {\n @let ws = host.asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Emit</h5>\n <span class=\"et-query-devtools-hint\">\n Sends as the app would, so a server that only answers a client that asked can be provoked from here.\n </span>\n </div>\n <div class=\"et-query-devtools-emit\">\n <input #emitEvent class=\"et-query-devtools-input\" type=\"text\" placeholder=\"event\" aria-label=\"Event to emit\" />\n <input\n #emitData\n class=\"et-query-devtools-input\"\n type=\"text\"\n placeholder=\"JSON payload (optional)\"\n aria-label=\"Payload to emit\"\n />\n <button\n (click)=\"host.emitSocketMessage({ entry, event: emitEvent.value, data: emitData.value })\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u2191 Send\n </button>\n </div>\n @if (host.socketEmitErrorFor(entry.id); as emitError) {\n <p class=\"et-query-devtools-editor-error\">{{ emitError }}</p>\n }\n\n @let messages = host.socketMessages(ws);\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Messages</h5>\n <span class=\"et-query-devtools-count\">\n @if (host.socketFilter()) {\n {{ messages.length }} of {{ ws.messages().length }}\n } @else {\n {{ messages.length }}\n }\n </span>\n </div>\n @for (message of messages; track message.id) {\n <div [attr.data-direction]=\"message.direction\" class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ host.formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-ws-direction\">{{ host.socketDirectionLabel(message) }}</span>\n @if (message.room) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n }\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n @if (message.data !== undefined) {\n <et-query-devtools-json [value]=\"message.data\" />\n }\n </div>\n } @empty {\n @if (ws.messages().length) {\n <p class=\"et-query-devtools-empty\">No message matches the filter \u00B7 {{ ws.messages().length }} in the log.</p>\n } @else {\n <p class=\"et-query-devtools-empty\">Nothing sent or received yet.</p>\n }\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n</div>\n" }]
|
|
50583
|
+
args: [{ selector: 'et-query-devtools-sockets-tab', encapsulation: ViewEncapsulation.None, imports: [QueryDevtoolsJsonComponent], template: "<div class=\"et-query-devtools-scroll\">\n @if (host.wsEntries().length) {\n <div class=\"et-query-devtools-toolbar\">\n <div class=\"et-query-devtools-toolbar-row\">\n <input\n #socketFilterInput\n [value]=\"host.socketFilter()\"\n (input)=\"host.socketFilter.set(socketFilterInput.value)\"\n class=\"et-query-devtools-search\"\n type=\"search\"\n placeholder=\"filter event / room / direction\u2026\"\n aria-label=\"Filter socket messages\"\n />\n @if (host.socketFilter()) {\n <button\n (click)=\"host.socketFilter.set('')\"\n class=\"et-query-devtools-filter-clear\"\n type=\"button\"\n title=\"Clear the message filter\"\n aria-label=\"Clear the message filter\"\n >\n <span aria-hidden=\"true\">\u2715</span>\n </button>\n }\n </div>\n </div>\n }\n\n @for (entry of host.wsEntries(); track entry.id) {\n @let ws = host.asWs(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <strong>{{ entry.meta.name || 'socket' }}</strong>\n <span\n [class.et-query-devtools-chip--success]=\"ws.connected()\"\n [class.et-query-devtools-chip--muted]=\"!ws.connected()\"\n class=\"et-query-devtools-chip\"\n >\n {{ ws.connected() ? 'connected' : 'disconnected' }}\n </span>\n </div>\n <dl class=\"et-query-devtools-meta\">\n <dt>URL</dt>\n <dd class=\"et-query-devtools-mono\">{{ entry.meta.url }}</dd>\n <dt>Rooms</dt>\n <dd>\n @if (ws.rooms().length) {\n <div class=\"et-query-devtools-chips\">\n @for (room of ws.rooms(); track room) {\n <span class=\"et-query-devtools-chip\">{{ room }}</span>\n }\n </div>\n } @else {\n none\n }\n </dd>\n </dl>\n\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Emit</h5>\n <span class=\"et-query-devtools-hint\">\n Sends as the app would, so a server that only answers a client that asked can be provoked from here.\n </span>\n </div>\n <div class=\"et-query-devtools-emit\">\n <input #emitEvent class=\"et-query-devtools-input\" type=\"text\" placeholder=\"event\" aria-label=\"Event to emit\" />\n <input\n #emitData\n class=\"et-query-devtools-input\"\n type=\"text\"\n placeholder=\"JSON payload (optional)\"\n aria-label=\"Payload to emit\"\n />\n <button\n (click)=\"host.emitSocketMessage({ entry, event: emitEvent.value, data: emitData.value })\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n \u2191 Send\n </button>\n </div>\n @if (host.socketEmitErrorFor(entry.id); as emitError) {\n <p class=\"et-query-devtools-editor-error\">{{ emitError }}</p>\n }\n\n @let messages = host.socketMessages(ws);\n <div class=\"et-query-devtools-section-row\">\n <h5 class=\"et-query-devtools-section\">Messages</h5>\n <span class=\"et-query-devtools-count\">\n @if (host.socketFilter()) {\n {{ messages.length }} of {{ ws.messages().length }}\n } @else {\n {{ messages.length }}\n }\n </span>\n </div>\n @for (message of messages; track message.id) {\n <div [attr.data-direction]=\"message.direction\" class=\"et-query-devtools-ws-message\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-count\">{{ host.formatTime(message.timestamp) }}</span>\n <span class=\"et-query-devtools-ws-direction\">{{ host.socketDirectionLabel(message) }}</span>\n @if (message.room) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ message.room }}</span>\n }\n <span class=\"et-query-devtools-method\">{{ message.event }}</span>\n </div>\n @if (message.data !== undefined) {\n <et-query-devtools-json [value]=\"message.data\" />\n }\n </div>\n } @empty {\n @if (ws.messages().length) {\n <p class=\"et-query-devtools-empty\">No message matches the filter \u00B7 {{ ws.messages().length }} in the log.</p>\n } @else {\n <p class=\"et-query-devtools-empty\">Nothing sent or received yet.</p>\n }\n }\n </div>\n } @empty {\n <p class=\"et-query-devtools-empty\">No web socket clients registered.</p>\n }\n</div>\n", styles: ["@layer components{.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-ws-message:where([data-direction=out]){border-inline-start:2px solid color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-ws-direction{color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-ws-message:where([data-direction=out]) .et-query-devtools-ws-direction{color:var(--_et-qdt-accent)}.et-query-devtools-emit{display:flex;align-items:center;gap:.4rem;margin-block:.4rem}.et-query-devtools-emit .et-query-devtools-input{flex:0 0 14rem}.et-query-devtools-emit .et-query-devtools-input+.et-query-devtools-input{flex:1 1 auto}.et-query-devtools-emit .et-query-devtools-btn{flex:0 0 auto}}\n"] }]
|
|
50386
50584
|
}] });
|
|
50387
50585
|
|
|
50388
50586
|
/** The Stacks tab: registered `QueryStack`/`PagedQueryStack` instances, each with a split-view drawer. */
|
|
@@ -50396,7 +50594,7 @@ class QueryDevtoolsStacksTabComponent {
|
|
|
50396
50594
|
return { method: first?.method ?? '', segments: first?.segments ?? [], baseUrl: first?.clientBaseUrl ?? '' };
|
|
50397
50595
|
}
|
|
50398
50596
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsStacksTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
50399
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsStacksTabComponent, isStandalone: true, selector: "et-query-devtools-stacks-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = host.asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"pagedId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(paged) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = host.asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"stackId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(stack) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.stackSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.stackSelectedQueryId.set(null)\"\n />\n</div>\n\n<!-- Reusable dt/dd pair for a card's `et-query-devtools-meta` list: what its queries ran and moved. -->\n<ng-template #activityRow let-activity=\"activity\">\n <dt>Traffic</dt>\n <dd>\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n</ng-template>\n\n<!-- Reusable inner-query list \u2014 clicking opens the split-view drawer, not a tab switch. -->\n<ng-template #innerQueries let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query ' + ($index + 1)\" />\n </span>\n @let linkStats = host.linkActivity(link);\n @if (linkStats.hasActivity) {\n <span class=\"et-query-devtools-traffic\">\n {{ host.formatTransferred(linkStats.stats.receivedBytes, linkStats.stats.hasEstimatedBytes) }}\n </span>\n }\n </button>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50597
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsStacksTabComponent, isStandalone: true, selector: "et-query-devtools-stacks-tab", ngImport: i0, template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = host.asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"pagedId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(paged) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = host.asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"stackId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(stack) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.stackSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.stackSelectedQueryId.set(null)\"\n />\n</div>\n\n<!-- Reusable dt/dd pair for a card's `et-query-devtools-meta` list: what its queries ran and moved. -->\n<ng-template #activityRow let-activity=\"activity\">\n <dt>Traffic</dt>\n <dd>\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n</ng-template>\n\n<!-- Reusable inner-query list \u2014 clicking opens the split-view drawer, not a tab switch. -->\n<ng-template #innerQueries let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query ' + ($index + 1)\" />\n </span>\n @let linkStats = host.linkActivity(link);\n @if (linkStats.hasActivity) {\n <span class=\"et-query-devtools-traffic\">\n {{ host.formatTransferred(linkStats.stats.receivedBytes, linkStats.stats.hasEstimatedBytes) }}\n </span>\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: ["@layer components{.et-query-devtools-traffic{margin-inline-start:auto;flex:0 0 auto;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--_et-qdt-subtle)}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QueryDevtoolsDrawerComponent, selector: "et-query-devtools-drawer", inputs: ["sel", "container"], outputs: ["dismiss"] }, { kind: "component", type: QueryDevtoolsFeaturesComponent, selector: "et-query-devtools-features", inputs: ["features"] }, { kind: "component", type: QueryDevtoolsRouteComponent, selector: "et-query-devtools-route", inputs: ["segments", "fallback"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
50400
50598
|
}
|
|
50401
50599
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsStacksTabComponent, decorators: [{
|
|
50402
50600
|
type: Component,
|
|
@@ -50405,7 +50603,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
50405
50603
|
QueryDevtoolsDrawerComponent,
|
|
50406
50604
|
QueryDevtoolsFeaturesComponent,
|
|
50407
50605
|
QueryDevtoolsRouteComponent,
|
|
50408
|
-
], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = host.asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"pagedId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(paged) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = host.asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"stackId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(stack) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.stackSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.stackSelectedQueryId.set(null)\"\n />\n</div>\n\n<!-- Reusable dt/dd pair for a card's `et-query-devtools-meta` list: what its queries ran and moved. -->\n<ng-template #activityRow let-activity=\"activity\">\n <dt>Traffic</dt>\n <dd>\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n</ng-template>\n\n<!-- Reusable inner-query list \u2014 clicking opens the split-view drawer, not a tab switch. -->\n<ng-template #innerQueries let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query ' + ($index + 1)\" />\n </span>\n @let linkStats = host.linkActivity(link);\n @if (linkStats.hasActivity) {\n <span class=\"et-query-devtools-traffic\">\n {{ host.formatTransferred(linkStats.stats.receivedBytes, linkStats.stats.hasEstimatedBytes) }}\n </span>\n }\n </button>\n }\n </div>\n</ng-template>\n" }]
|
|
50606
|
+
], template: "<div #panes class=\"et-query-devtools-split\">\n <div class=\"et-query-devtools-scroll\">\n @for (entry of host.stackEntries(); track entry.id) {\n @if (entry.kind === 'paged-query-stack') {\n @let paged = host.asPagedStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">paged stack</span>\n <span class=\"et-query-devtools-chip et-query-devtools-chip--muted\">{{ paged.direction() }}</span>\n @if (paged.loading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n </div>\n\n @let pagedId = stackIdentity(paged);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ pagedId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"pagedId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ pagedId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Pages loaded</dt>\n <dd>{{ paged.queries().length }}</dd>\n <dt>Items</dt>\n <dd>{{ paged.items().length }}</dd>\n <dt>First page loaded</dt>\n <dd>{{ paged.isFirstPageLoaded() }}</dd>\n <dt>Last page loaded</dt>\n <dd>{{ paged.isLastPageLoaded() }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(paged) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(paged) }\" />\n </div>\n } @else {\n @let stack = host.asStack(entry);\n <div class=\"et-query-devtools-card\">\n <div class=\"et-query-devtools-card-head\">\n <span class=\"et-query-devtools-chip\">stack</span>\n @if (stack.anyLoading()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--loading\">loading</span>\n }\n @if (stack.anyError()) {\n <span class=\"et-query-devtools-chip et-query-devtools-chip--error\">error</span>\n }\n </div>\n\n @let stackId = stackIdentity(stack);\n <div class=\"et-query-devtools-card-title\">\n <span class=\"et-query-devtools-method\">{{ stackId.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"stackId.segments\" />\n </span>\n </div>\n <div class=\"et-query-devtools-card-sub et-query-devtools-mono\">{{ stackId.baseUrl }}</div>\n @if (entry.meta.features?.length) {\n <et-query-devtools-features [features]=\"entry.meta.features ?? []\" />\n }\n\n <dl class=\"et-query-devtools-meta\">\n <dt>Queries</dt>\n <dd>{{ stack.queries().length }}</dd>\n <dt>Loading</dt>\n <dd>{{ stack.loadingProgress().loaded }} / {{ stack.loadingProgress().total }}</dd>\n <dt>Errors</dt>\n <dd>{{ stack.errors().length }}</dd>\n <ng-container *ngTemplateOutlet=\"activityRow; context: { activity: host.stackActivity(stack) }\" />\n </dl>\n <ng-container *ngTemplateOutlet=\"innerQueries; context: { links: host.queriesForStack(stack) }\" />\n </div>\n }\n } @empty {\n <p class=\"et-query-devtools-empty\">No stacks registered.</p>\n }\n </div>\n\n <et-query-devtools-drawer\n [sel]=\"host.stackSelectedQuery()\"\n [container]=\"panes\"\n (dismiss)=\"host.stackSelectedQueryId.set(null)\"\n />\n</div>\n\n<!-- Reusable dt/dd pair for a card's `et-query-devtools-meta` list: what its queries ran and moved. -->\n<ng-template #activityRow let-activity=\"activity\">\n <dt>Traffic</dt>\n <dd>\n @if (activity.hasActivity) {\n {{ activity.stats.requests }} request{{ activity.stats.requests === 1 ? '' : 's' }} \u00B7 \u2193\n {{ host.formatTransferred(activity.stats.receivedBytes, activity.stats.hasEstimatedBytes) }}\n @if (activity.stats.sentBytes) {\n \u00B7 \u2191 {{ host.formatTransferred(activity.stats.sentBytes, activity.stats.hasEstimatedBytes) }}\n }\n @if (activity.cacheServed) {\n \u00B7 {{ activity.cacheServed }} from cache\n }\n @if (activity.stats.errors) {\n \u00B7 {{ activity.stats.errors }} failed\n }\n } @else {\n \u2014\n }\n </dd>\n</ng-template>\n\n<!-- Reusable inner-query list \u2014 clicking opens the split-view drawer, not a tab switch. -->\n<ng-template #innerQueries let-links=\"links\">\n <div class=\"et-query-devtools-inner-queries\">\n @for (link of links; track $index) {\n <button\n [class.et-query-devtools-inner-row--active]=\"host.stackSelectedQueryId() === link.id\"\n [disabled]=\"!link.id\"\n (click)=\"host.stackSelectedQueryId.set(link.id)\"\n class=\"et-query-devtools-inner-row\"\n type=\"button\"\n >\n <span [attr.data-status]=\"host.queryStatus(link.query)\" class=\"et-query-devtools-status\"></span>\n <span class=\"et-query-devtools-method\">{{ link.method }}</span>\n <span class=\"et-query-devtools-route\">\n <et-query-devtools-route [segments]=\"link.segments\" [fallback]=\"link.query.id() || 'query ' + ($index + 1)\" />\n </span>\n @let linkStats = host.linkActivity(link);\n @if (linkStats.hasActivity) {\n <span class=\"et-query-devtools-traffic\">\n {{ host.formatTransferred(linkStats.stats.receivedBytes, linkStats.stats.hasEstimatedBytes) }}\n </span>\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: ["@layer components{.et-query-devtools-traffic{margin-inline-start:auto;flex:0 0 auto;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--_et-qdt-subtle)}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}}\n"] }]
|
|
50409
50607
|
}] });
|
|
50410
50608
|
|
|
50411
50609
|
/** Past this many rows, the timeline keeps the newest and counts the rest instead of drawing them. */
|
|
@@ -50571,6 +50769,8 @@ const buildQueryDevtoolsSessionExport = (options) => ({
|
|
|
50571
50769
|
|
|
50572
50770
|
/** How long a copy button stays ticked after a successful write. */
|
|
50573
50771
|
const COPIED_RESET_MS = 1200;
|
|
50772
|
+
/** How long the locate box stays up. Long enough to outlast a smooth scroll and still be read. */
|
|
50773
|
+
const LOCATE_HOLD_MS = 2500;
|
|
50574
50774
|
const noop = () => undefined;
|
|
50575
50775
|
const STORAGE_KEY = 'ethlete:query:devtools:v4';
|
|
50576
50776
|
/**
|
|
@@ -50633,6 +50833,91 @@ const readPinnedQueryIds = () => {
|
|
|
50633
50833
|
const DEFAULT_TOKEN_MAX_AGE_S = 300;
|
|
50634
50834
|
/** Upper bound for the same, so a token that claims a year of life still gets refreshed hourly. */
|
|
50635
50835
|
const MAX_TOKEN_MAX_AGE_S = 3600;
|
|
50836
|
+
/**
|
|
50837
|
+
* A panel action must never reach the application's `ErrorHandler` - it reports its own failure inside
|
|
50838
|
+
* the panel instead, and this is the text it shows.
|
|
50839
|
+
*/
|
|
50840
|
+
const actionErrorMessage = (error) => (error instanceof Error ? error.message : String(error));
|
|
50841
|
+
/**
|
|
50842
|
+
* What to seed the args editor with for a query that has never run and holds no args anywhere. A
|
|
50843
|
+
* function route cannot execute without its path params, so the editor offers them as blanks to fill.
|
|
50844
|
+
*/
|
|
50845
|
+
const emptyArgsSeed = (entry) => {
|
|
50846
|
+
const params = entry.meta.routeParts?.flatMap((part) => (part.param ? [part.param] : [])) ?? [];
|
|
50847
|
+
if (!params.length)
|
|
50848
|
+
return {};
|
|
50849
|
+
return { pathParams: Object.fromEntries(params.map((name) => [name, ''])) };
|
|
50850
|
+
};
|
|
50851
|
+
/** Marks a value `editableArgs` left out of the draft, for {@link executableArgs} to put back. */
|
|
50852
|
+
const DROPPED = /* @__PURE__ */ Symbol('dropped');
|
|
50853
|
+
const isPlainObject = (value) => {
|
|
50854
|
+
if (!value || typeof value !== 'object')
|
|
50855
|
+
return false;
|
|
50856
|
+
const proto = Object.getPrototypeOf(value);
|
|
50857
|
+
return proto === Object.prototype || proto === null;
|
|
50858
|
+
};
|
|
50859
|
+
/**
|
|
50860
|
+
* Values `JSON.stringify` cannot represent - it writes `{}`, private fields, or omits them outright. A
|
|
50861
|
+
* `Date` is deliberately not one: it survives as an ISO string, which is what the query would send
|
|
50862
|
+
* anyway, so it stays editable.
|
|
50863
|
+
*/
|
|
50864
|
+
const isUneditable = (value) => typeof value === 'function' ||
|
|
50865
|
+
value instanceof Map ||
|
|
50866
|
+
value instanceof Set ||
|
|
50867
|
+
(typeof FormData !== 'undefined' && value instanceof FormData) ||
|
|
50868
|
+
(typeof Blob !== 'undefined' && value instanceof Blob) ||
|
|
50869
|
+
isHeadersValue(value);
|
|
50870
|
+
/**
|
|
50871
|
+
* Args in the shape the JSON editor can carry. `JSON.stringify` writes an `HttpHeaders` as its four
|
|
50872
|
+
* private fields, a `FormData` or a `Map` as `{}`, and a header provider not at all - so an unedited
|
|
50873
|
+
* draft used to replay values the query never had. Headers become a plain `name: value` record, since
|
|
50874
|
+
* one rebuilds them exactly; every other such value is left out of the draft and put back verbatim by
|
|
50875
|
+
* {@link executableArgs}, which beats letting the user edit an empty object over the top of it.
|
|
50876
|
+
*/
|
|
50877
|
+
const editableArgs = (args) => editableValue(args);
|
|
50878
|
+
const editableValue = (value) => {
|
|
50879
|
+
if (isHeadersValue(value))
|
|
50880
|
+
return Object.fromEntries(headerEntries(value).map(({ k, v }) => [k, v]));
|
|
50881
|
+
if (isUneditable(value))
|
|
50882
|
+
return DROPPED;
|
|
50883
|
+
if (Array.isArray(value)) {
|
|
50884
|
+
// `null` rather than a hole, so the indices a user edits still line up with the ones being replayed.
|
|
50885
|
+
return value.map((item) => {
|
|
50886
|
+
const edited = editableValue(item);
|
|
50887
|
+
return edited === DROPPED ? null : edited;
|
|
50888
|
+
});
|
|
50889
|
+
}
|
|
50890
|
+
if (isPlainObject(value)) {
|
|
50891
|
+
const out = {};
|
|
50892
|
+
for (const [key, child] of Object.entries(value)) {
|
|
50893
|
+
const edited = editableValue(child);
|
|
50894
|
+
if (edited !== DROPPED)
|
|
50895
|
+
out[key] = edited;
|
|
50896
|
+
}
|
|
50897
|
+
return out;
|
|
50898
|
+
}
|
|
50899
|
+
return value;
|
|
50900
|
+
};
|
|
50901
|
+
/** The inverse of {@link editableArgs}: records become `HttpHeaders` again, dropped values come back. */
|
|
50902
|
+
const executableArgs = (draft, source) => draft ? executableValue(draft, source) : draft;
|
|
50903
|
+
const executableValue = (draft, source) => {
|
|
50904
|
+
// What the draft could not carry comes back verbatim. A key the user deleted themselves stays deleted,
|
|
50905
|
+
// because only a value `editableArgs` dropped is missing from the draft while present in the source.
|
|
50906
|
+
if (draft === undefined)
|
|
50907
|
+
return isUneditable(source) ? source : undefined;
|
|
50908
|
+
if (isHeadersValue(source) && isPlainObject(draft))
|
|
50909
|
+
return new HttpHeaders(draft);
|
|
50910
|
+
if (isPlainObject(draft) && isPlainObject(source)) {
|
|
50911
|
+
const out = { ...draft };
|
|
50912
|
+
for (const [key, child] of Object.entries(source)) {
|
|
50913
|
+
const restored = executableValue(draft[key], child);
|
|
50914
|
+
if (restored !== undefined)
|
|
50915
|
+
out[key] = restored;
|
|
50916
|
+
}
|
|
50917
|
+
return out;
|
|
50918
|
+
}
|
|
50919
|
+
return draft;
|
|
50920
|
+
};
|
|
50636
50921
|
/**
|
|
50637
50922
|
* The JSONPath of a string value inside a response, or `null`. Used to locate the access token in an
|
|
50638
50923
|
* auth response whose shape only the provider's `extractTokens` knows.
|
|
@@ -50789,6 +51074,12 @@ class QueryDevtoolsComponent {
|
|
|
50789
51074
|
/** The status facets the Queries list is narrowed to. Empty means no status narrowing. */
|
|
50790
51075
|
this.queryFacets = signal(new Set(this.persisted.queryFacets ?? []), /* @ts-ignore */
|
|
50791
51076
|
...(ngDevMode ? [{ debugName: "queryFacets" }] : /* istanbul ignore next */ []));
|
|
51077
|
+
/**
|
|
51078
|
+
* Which way the Queries list sorts by last-executed time. Only the direction is switchable - the field
|
|
51079
|
+
* is not, because "which one just ran" is the question the column exists to answer.
|
|
51080
|
+
*/
|
|
51081
|
+
this.queryRecentFirst = signal(this.persisted.queryRecentFirst ?? true, /* @ts-ignore */
|
|
51082
|
+
...(ngDevMode ? [{ debugName: "queryRecentFirst" }] : /* istanbul ignore next */ []));
|
|
50792
51083
|
/**
|
|
50793
51084
|
* The entry ids sorted to the top of the Queries list. Ids are derived from a stable descriptor plus a
|
|
50794
51085
|
* per-descriptor sequence number, so a pin survives a reload as long as queries are created in the same
|
|
@@ -50822,6 +51113,9 @@ class QueryDevtoolsComponent {
|
|
|
50822
51113
|
/** Keys (`<entryId>:<stepIndex>`) of the sequence steps whose in/out detail is expanded. */
|
|
50823
51114
|
this.expandedSteps = signal(new Set(this.persisted.expandedSteps ?? []), /* @ts-ignore */
|
|
50824
51115
|
...(ngDevMode ? [{ debugName: "expandedSteps" }] : /* istanbul ignore next */ []));
|
|
51116
|
+
/** Keys of the Queries-list groups the user opened - the tab is rebuilt on every switch back. */
|
|
51117
|
+
this.expandedQueryGroups = signal(new Set(this.persisted.expandedQueryGroups ?? []), /* @ts-ignore */
|
|
51118
|
+
...(ngDevMode ? [{ debugName: "expandedQueryGroups" }] : /* istanbul ignore next */ []));
|
|
50825
51119
|
/** Shared value-explorer search term. */
|
|
50826
51120
|
this.jsonSearch = signal(this.persisted.jsonSearch ?? '', /* @ts-ignore */
|
|
50827
51121
|
...(ngDevMode ? [{ debugName: "jsonSearch" }] : /* istanbul ignore next */ []));
|
|
@@ -50863,6 +51157,8 @@ class QueryDevtoolsComponent {
|
|
|
50863
51157
|
this.editorSeed = '';
|
|
50864
51158
|
this.editError = signal(null, /* @ts-ignore */
|
|
50865
51159
|
...(ngDevMode ? [{ debugName: "editError" }] : /* istanbul ignore next */ []));
|
|
51160
|
+
/** The args the open editor was seeded from, so applying can put back what the draft cannot carry. */
|
|
51161
|
+
this.editedArgsSource = null;
|
|
50866
51162
|
/** Transient "Copied!" feedback for the copy-report, copy-as-Insomnia / cURL and copy-document actions. */
|
|
50867
51163
|
this.copiedReport = signal(false, /* @ts-ignore */
|
|
50868
51164
|
...(ngDevMode ? [{ debugName: "copiedReport" }] : /* istanbul ignore next */ []));
|
|
@@ -50872,6 +51168,8 @@ class QueryDevtoolsComponent {
|
|
|
50872
51168
|
...(ngDevMode ? [{ debugName: "copiedCurl" }] : /* istanbul ignore next */ []));
|
|
50873
51169
|
this.copiedGql = signal(false, /* @ts-ignore */
|
|
50874
51170
|
...(ngDevMode ? [{ debugName: "copiedGql" }] : /* istanbul ignore next */ []));
|
|
51171
|
+
this.copiedRoute = signal(false, /* @ts-ignore */
|
|
51172
|
+
...(ngDevMode ? [{ debugName: "copiedRoute" }] : /* istanbul ignore next */ []));
|
|
50875
51173
|
this.copiedReset$ = new Subject();
|
|
50876
51174
|
/** 1-second tick driving the cache freshness countdowns. */
|
|
50877
51175
|
this.clock = toSignal(interval(1000), { initialValue: 0 });
|
|
@@ -50880,6 +51178,12 @@ class QueryDevtoolsComponent {
|
|
|
50880
51178
|
...(ngDevMode ? [{ debugName: "inspectActive" }] : /* istanbul ignore next */ []));
|
|
50881
51179
|
this.inspectHover = signal(null, /* @ts-ignore */
|
|
50882
51180
|
...(ngDevMode ? [{ debugName: "inspectHover" }] : /* istanbul ignore next */ []));
|
|
51181
|
+
/** Inspect run backwards: the box drawn over the element the selected query was created in. */
|
|
51182
|
+
this.locatedRect = signal(null, /* @ts-ignore */
|
|
51183
|
+
...(ngDevMode ? [{ debugName: "locatedRect" }] : /* istanbul ignore next */ []));
|
|
51184
|
+
this.locateState = signal('idle', /* @ts-ignore */
|
|
51185
|
+
...(ngDevMode ? [{ debugName: "locateState" }] : /* istanbul ignore next */ []));
|
|
51186
|
+
this.locate$ = new Subject();
|
|
50883
51187
|
/** When set (via inspect), the Queries list is filtered to exactly these entry ids. */
|
|
50884
51188
|
this.inspectFilterIds = signal(this.persisted.inspectFilterIds ?? null, /* @ts-ignore */
|
|
50885
51189
|
...(ngDevMode ? [{ debugName: "inspectFilterIds" }] : /* istanbul ignore next */ []));
|
|
@@ -51121,6 +51425,22 @@ class QueryDevtoolsComponent {
|
|
|
51121
51425
|
this.copiedInsomnia.set(false);
|
|
51122
51426
|
this.copiedCurl.set(false);
|
|
51123
51427
|
this.copiedGql.set(false);
|
|
51428
|
+
this.copiedRoute.set(false);
|
|
51429
|
+
}), takeUntilDestroyed())
|
|
51430
|
+
.subscribe();
|
|
51431
|
+
// The box has to follow the element for as long as the smooth scroll is moving it, so it tracks per
|
|
51432
|
+
// frame rather than measuring once. Each locate cancels the previous run's frames and its timeout.
|
|
51433
|
+
this.locate$
|
|
51434
|
+
.pipe(switchMap((element) => {
|
|
51435
|
+
// `NEVER` for the not-on-screen case: there is no box to move, but the button's reason has to
|
|
51436
|
+
// stay up for the same beat before `finalize` clears it.
|
|
51437
|
+
const frames = element
|
|
51438
|
+
? animationFrames().pipe(tap(() => this.locatedRect.set(element.getBoundingClientRect())))
|
|
51439
|
+
: NEVER;
|
|
51440
|
+
return frames.pipe(takeUntil(timer(LOCATE_HOLD_MS)), finalize(() => {
|
|
51441
|
+
this.locatedRect.set(null);
|
|
51442
|
+
this.locateState.set('idle');
|
|
51443
|
+
}));
|
|
51124
51444
|
}), takeUntilDestroyed())
|
|
51125
51445
|
.subscribe();
|
|
51126
51446
|
// Merge every live repository's event stream into the rolling log, re-subscribing as the set of
|
|
@@ -51146,11 +51466,13 @@ class QueryDevtoolsComponent {
|
|
|
51146
51466
|
inspectFilterIds: this.inspectFilterIds(),
|
|
51147
51467
|
queryFilter: this.queryFilter(),
|
|
51148
51468
|
queryFacets: [...this.queryFacets()],
|
|
51469
|
+
queryRecentFirst: this.queryRecentFirst(),
|
|
51149
51470
|
eventClient: this.eventClient(),
|
|
51150
51471
|
eventErrorsOnly: this.eventErrorsOnly(),
|
|
51151
51472
|
socketFilter: this.socketFilter(),
|
|
51152
51473
|
jsonSearch: this.jsonSearch(),
|
|
51153
51474
|
expandedSteps: [...this.expandedSteps()],
|
|
51475
|
+
expandedQueryGroups: [...this.expandedQueryGroups()],
|
|
51154
51476
|
jsonExpanded: [...this.jsonExpandedPaths()],
|
|
51155
51477
|
jsonCollapsed: [...this.jsonCollapsedPaths()],
|
|
51156
51478
|
};
|
|
@@ -51182,6 +51504,7 @@ class QueryDevtoolsComponent {
|
|
|
51182
51504
|
this.copiedReport.set(false);
|
|
51183
51505
|
this.copiedInsomnia.set(false);
|
|
51184
51506
|
this.copiedCurl.set(false);
|
|
51507
|
+
this.copiedRoute.set(false);
|
|
51185
51508
|
this.diffRunIndex.set(null);
|
|
51186
51509
|
this.diffBaseRunIndex.set(null);
|
|
51187
51510
|
this.errorRunIndex.set(null);
|
|
@@ -51511,6 +51834,21 @@ class QueryDevtoolsComponent {
|
|
|
51511
51834
|
diff: diffQueryDevtoolsResponses(ends.before.response, ends.after.response),
|
|
51512
51835
|
};
|
|
51513
51836
|
}
|
|
51837
|
+
/** Whether the diff header's older/newer control has a pair to move to. */
|
|
51838
|
+
canStepRunDiff(entry, older) {
|
|
51839
|
+
return !!this.steppedDiffPair(entry, older);
|
|
51840
|
+
}
|
|
51841
|
+
/**
|
|
51842
|
+
* Moves the whole comparison one run older or newer, so re-picking a pair does not mean scrolling back
|
|
51843
|
+
* up to the runs table. Within the handful of retained bodies there are only a few pairs to walk.
|
|
51844
|
+
*/
|
|
51845
|
+
stepRunDiff(entry, older) {
|
|
51846
|
+
const pair = this.steppedDiffPair(entry, older);
|
|
51847
|
+
if (!pair)
|
|
51848
|
+
return;
|
|
51849
|
+
this.diffBaseRunIndex.set(pair.before.index);
|
|
51850
|
+
this.diffRunIndex.set(pair.after.index);
|
|
51851
|
+
}
|
|
51514
51852
|
toggleRunError(run) {
|
|
51515
51853
|
this.errorRunIndex.update((current) => (current === run.index ? null : run.index));
|
|
51516
51854
|
}
|
|
@@ -51547,7 +51885,6 @@ class QueryDevtoolsComponent {
|
|
|
51547
51885
|
return '[unserializable]';
|
|
51548
51886
|
}
|
|
51549
51887
|
}
|
|
51550
|
-
/** A byte count the way a network panel spells one out. */
|
|
51551
51888
|
formatBytes(bytes) {
|
|
51552
51889
|
if (bytes < 1000)
|
|
51553
51890
|
return `${bytes} B`;
|
|
@@ -51571,8 +51908,20 @@ class QueryDevtoolsComponent {
|
|
|
51571
51908
|
return '—';
|
|
51572
51909
|
return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(2)}s`;
|
|
51573
51910
|
}
|
|
51574
|
-
|
|
51575
|
-
|
|
51911
|
+
/**
|
|
51912
|
+
* Replays a query with the args the panel is already showing. `execute()` would otherwise default to
|
|
51913
|
+
* `state.args()`, which only `withArgs` ever writes - so a query executed imperatively, by a sequence
|
|
51914
|
+
* step or as an auth query would replay with no args at all and a function route would throw.
|
|
51915
|
+
*/
|
|
51916
|
+
executeQuery(selection, allowCache) {
|
|
51917
|
+
const { query } = selection;
|
|
51918
|
+
try {
|
|
51919
|
+
query.execute({ args: this.queryArgs(query), options: allowCache ? { allowCache: true } : undefined });
|
|
51920
|
+
}
|
|
51921
|
+
catch (error) {
|
|
51922
|
+
this.openArgsEditor(selection);
|
|
51923
|
+
this.editError.set(actionErrorMessage(error));
|
|
51924
|
+
}
|
|
51576
51925
|
}
|
|
51577
51926
|
resetQuery(query) {
|
|
51578
51927
|
query.reset();
|
|
@@ -51657,6 +52006,23 @@ class QueryDevtoolsComponent {
|
|
|
51657
52006
|
copyGqlDocument(doc) {
|
|
51658
52007
|
this.writeToClipboard({ text: this.gqlDocument(doc) }, this.copiedGql);
|
|
51659
52008
|
}
|
|
52009
|
+
/**
|
|
52010
|
+
* The endpoint of a query as one string: the absolute URL its last request used, or - for a query
|
|
52011
|
+
* that has not run - the rendered route on screen.
|
|
52012
|
+
*/
|
|
52013
|
+
copyableRoute(entry, query) {
|
|
52014
|
+
return this.requestUrl(query) ?? this.queryRoute(entry, query);
|
|
52015
|
+
}
|
|
52016
|
+
/** Names which of the two strings {@link copyableRoute} is offering, so the button says what it copies. */
|
|
52017
|
+
copyableRouteTitle(entry, query) {
|
|
52018
|
+
const route = this.copyableRoute(entry, query);
|
|
52019
|
+
const kind = this.requestUrl(query) ? 'the absolute URL of the last request' : 'the rendered route';
|
|
52020
|
+
return `Copy ${kind}: ${route}`;
|
|
52021
|
+
}
|
|
52022
|
+
/** Copies {@link copyableRoute} - the endpoint on its own, where the exports are a whole document. */
|
|
52023
|
+
copyRoute(entry, query) {
|
|
52024
|
+
this.writeToClipboard({ text: this.copyableRoute(entry, query) }, this.copiedRoute);
|
|
52025
|
+
}
|
|
51660
52026
|
/**
|
|
51661
52027
|
* Downloads the given queries (already scoped/filtered by the caller) as one Insomnia collection,
|
|
51662
52028
|
* filed into a folder per query client.
|
|
@@ -51702,31 +52068,49 @@ class QueryDevtoolsComponent {
|
|
|
51702
52068
|
this.editError.set(null);
|
|
51703
52069
|
this.editorMode.set('response');
|
|
51704
52070
|
}
|
|
51705
|
-
openArgsEditor(query) {
|
|
51706
|
-
const
|
|
52071
|
+
openArgsEditor({ entry, query }) {
|
|
52072
|
+
const args = this.queryArgs(query) ?? emptyArgsSeed(entry);
|
|
52073
|
+
const draft = JSON.stringify(editableArgs(args), null, 2);
|
|
52074
|
+
this.editedArgsSource = args;
|
|
51707
52075
|
this.editorSeed = draft;
|
|
51708
52076
|
this.argsDraft.set(draft);
|
|
51709
52077
|
this.editError.set(null);
|
|
51710
52078
|
this.editorMode.set('args');
|
|
51711
52079
|
}
|
|
51712
52080
|
applyResponse(query) {
|
|
52081
|
+
let response;
|
|
51713
52082
|
try {
|
|
51714
|
-
|
|
51715
|
-
this.editorMode.set('none');
|
|
51716
|
-
this.editError.set(null);
|
|
52083
|
+
response = JSON.parse(this.responseDraft());
|
|
51717
52084
|
}
|
|
51718
52085
|
catch {
|
|
51719
52086
|
this.editError.set('Invalid JSON');
|
|
52087
|
+
return;
|
|
51720
52088
|
}
|
|
51721
|
-
}
|
|
51722
|
-
applyArgs(query) {
|
|
51723
52089
|
try {
|
|
51724
|
-
query.
|
|
52090
|
+
query.subtle.setResponse(response);
|
|
51725
52091
|
this.editorMode.set('none');
|
|
51726
52092
|
this.editError.set(null);
|
|
51727
52093
|
}
|
|
52094
|
+
catch (error) {
|
|
52095
|
+
this.editError.set(actionErrorMessage(error));
|
|
52096
|
+
}
|
|
52097
|
+
}
|
|
52098
|
+
applyArgs(query) {
|
|
52099
|
+
let args;
|
|
52100
|
+
try {
|
|
52101
|
+
args = JSON.parse(this.argsDraft());
|
|
52102
|
+
}
|
|
51728
52103
|
catch {
|
|
51729
52104
|
this.editError.set('Invalid JSON');
|
|
52105
|
+
return;
|
|
52106
|
+
}
|
|
52107
|
+
try {
|
|
52108
|
+
query.execute({ args: executableArgs(args, this.editedArgsSource) });
|
|
52109
|
+
this.editorMode.set('none');
|
|
52110
|
+
this.editError.set(null);
|
|
52111
|
+
}
|
|
52112
|
+
catch (error) {
|
|
52113
|
+
this.editError.set(actionErrorMessage(error));
|
|
51730
52114
|
}
|
|
51731
52115
|
}
|
|
51732
52116
|
cancelEditor() {
|
|
@@ -51966,6 +52350,31 @@ class QueryDevtoolsComponent {
|
|
|
51966
52350
|
authQueryKeys(auth) {
|
|
51967
52351
|
return Object.keys(auth.queries ?? {});
|
|
51968
52352
|
}
|
|
52353
|
+
/**
|
|
52354
|
+
* Which tab refreshes this provider's tokens, as a chip: whether it is this one, how many tabs are
|
|
52355
|
+
* in the election, and - when there is no election - why every tab reads as the leader.
|
|
52356
|
+
*/
|
|
52357
|
+
authLeadership(auth) {
|
|
52358
|
+
const sync = auth.features?.multiTabSync;
|
|
52359
|
+
if (!sync)
|
|
52360
|
+
return null;
|
|
52361
|
+
if (sync.leadership !== 'election') {
|
|
52362
|
+
const reason = sync.leadership === 'off'
|
|
52363
|
+
? 'Leader election is off, so every tab refreshes its own tokens - this one included.'
|
|
52364
|
+
: 'This browser has no Web Locks API, so the election cannot run and every tab refreshes its own tokens.';
|
|
52365
|
+
return { label: 'every tab refreshes', tone: 'muted', title: reason };
|
|
52366
|
+
}
|
|
52367
|
+
const tabs = sync.instanceCount();
|
|
52368
|
+
const isLeader = sync.isLeader();
|
|
52369
|
+
// The count is recounted on announce, goodbye and takeover rather than on a timer, so a tab that
|
|
52370
|
+
// crashed as a follower is still in it. Presenting it as exact would turn that into a bug report.
|
|
52371
|
+
const title = `${isLeader ? 'This tab performs the automatic token refresh.' : 'Another tab performs the automatic token refresh.'} ${tabs} tab${tabs === 1 ? '' : 's'} in the election, counted on the last announce - a tab that crashed as a follower is still counted.`;
|
|
52372
|
+
return {
|
|
52373
|
+
label: `${isLeader ? 'leader' : 'follower'} · ~${tabs} tab${tabs === 1 ? '' : 's'}`,
|
|
52374
|
+
tone: isLeader ? 'success' : 'muted',
|
|
52375
|
+
title,
|
|
52376
|
+
};
|
|
52377
|
+
}
|
|
51969
52378
|
/** Countdown to the access-token's `exp` (the point a refresh becomes due), or `null` if unknown. */
|
|
51970
52379
|
authTokenExpiry(auth) {
|
|
51971
52380
|
this.clock();
|
|
@@ -51990,6 +52399,16 @@ class QueryDevtoolsComponent {
|
|
|
51990
52399
|
stepSnapshot(sequence, index) {
|
|
51991
52400
|
return sequence.snapshots()[index] ?? null;
|
|
51992
52401
|
}
|
|
52402
|
+
toggleQueryGroup(key) {
|
|
52403
|
+
const next = new Set(this.expandedQueryGroups());
|
|
52404
|
+
if (next.has(key)) {
|
|
52405
|
+
next.delete(key);
|
|
52406
|
+
}
|
|
52407
|
+
else {
|
|
52408
|
+
next.add(key);
|
|
52409
|
+
}
|
|
52410
|
+
this.expandedQueryGroups.set(next);
|
|
52411
|
+
}
|
|
51993
52412
|
isStepExpanded(entryId, index) {
|
|
51994
52413
|
return this.expandedSteps().has(this.stepKey(entryId, index));
|
|
51995
52414
|
}
|
|
@@ -52036,6 +52455,35 @@ class QueryDevtoolsComponent {
|
|
|
52036
52455
|
return '-';
|
|
52037
52456
|
return new Date(timestamp).toLocaleTimeString(undefined, { hour12: false });
|
|
52038
52457
|
}
|
|
52458
|
+
/**
|
|
52459
|
+
* The element a query was created in, which is what {@link locateQuery} can point at. `null` for a
|
|
52460
|
+
* query created outside a component or directive injector - a root service, a resolver, a guard.
|
|
52461
|
+
*/
|
|
52462
|
+
locatableElement(entry) {
|
|
52463
|
+
return entry.meta.element ?? null;
|
|
52464
|
+
}
|
|
52465
|
+
/**
|
|
52466
|
+
* Scrolls the element the selected query was created in into view and draws the inspect box over it -
|
|
52467
|
+
* inspect run backwards. Where a query was *created* is not necessarily where its data is rendered,
|
|
52468
|
+
* which is what the button's "created here" wording is for.
|
|
52469
|
+
*/
|
|
52470
|
+
locateQuery(entry) {
|
|
52471
|
+
const element = this.locatableElement(entry);
|
|
52472
|
+
if (!element)
|
|
52473
|
+
return;
|
|
52474
|
+
// Detached, `display: none`, or inside a collapsed panel: scrolling to it lands nowhere and the box
|
|
52475
|
+
// would be drawn over an unrelated strip of the page.
|
|
52476
|
+
const isVisible = typeof element.checkVisibility === 'function' ? element.checkVisibility() : element.isConnected;
|
|
52477
|
+
if (!isVisible) {
|
|
52478
|
+
this.locatedRect.set(null);
|
|
52479
|
+
this.locateState.set('offscreen');
|
|
52480
|
+
this.locate$.next(null);
|
|
52481
|
+
return;
|
|
52482
|
+
}
|
|
52483
|
+
element.scrollIntoView({ block: 'center', inline: 'nearest', behavior: 'smooth' });
|
|
52484
|
+
this.locateState.set('located');
|
|
52485
|
+
this.locate$.next(element);
|
|
52486
|
+
}
|
|
52039
52487
|
/**
|
|
52040
52488
|
* The two runs the diff compares, oldest first - normalised by run index, so picking a pair in either
|
|
52041
52489
|
* order reads the same way round as the `#before → #after` header prints it.
|
|
@@ -52049,6 +52497,21 @@ class QueryDevtoolsComponent {
|
|
|
52049
52497
|
*
|
|
52050
52498
|
* `null` unless a run is armed, so a closed diff costs nothing to walk.
|
|
52051
52499
|
*/
|
|
52500
|
+
/**
|
|
52501
|
+
* The pair one step older or newer than the current comparison, keeping whatever gap it has, or `null`
|
|
52502
|
+
* at either end of the retained bodies.
|
|
52503
|
+
*/
|
|
52504
|
+
steppedDiffPair(entry, older) {
|
|
52505
|
+
const comparison = this.responseDiff(entry);
|
|
52506
|
+
if (!comparison)
|
|
52507
|
+
return null;
|
|
52508
|
+
// `stats.runs()` is oldest-first, so one step older is one index down.
|
|
52509
|
+
const held = (entry.stats?.runs() ?? []).filter((run) => run.hasResponse);
|
|
52510
|
+
const shift = older ? -1 : 1;
|
|
52511
|
+
const before = held[held.findIndex((run) => run.index === comparison.before.index) + shift];
|
|
52512
|
+
const after = held[held.findIndex((run) => run.index === comparison.after.index) + shift];
|
|
52513
|
+
return before && after ? { before, after } : null;
|
|
52514
|
+
}
|
|
52052
52515
|
diffEnds(entry) {
|
|
52053
52516
|
const runs = entry.stats?.runs() ?? [];
|
|
52054
52517
|
const held = (index) => index === null ? undefined : runs.find((run) => run.index === index && run.hasResponse);
|
|
@@ -52681,22 +53144,17 @@ class QueryDevtoolsComponent {
|
|
|
52681
53144
|
this.eventLog.update((log) => [item, ...log].slice(0, MAX_EVENTS));
|
|
52682
53145
|
}
|
|
52683
53146
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
52684
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { properties: { "attr.data-dock": "dock()" }, classAttribute: "et-query-devtools-host" }, providers: [{ provide: QUERY_DEVTOOLS_HOST, useExisting: QueryDevtoolsComponent }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "tabMenuEl", first: true, predicate: ["tabMenu"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (open()) {\n <section\n #panel\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [attr.data-dock]=\"poppedOut() ? 'popout' : dock()\"\n [attr.data-pane-axis]=\"paneAxis()\"\n [style.block-size.px]=\"panelBlockSize()\"\n [style.inline-size.px]=\"panelInlineSize()\"\n [style.--_et-qdt-list-width.px]=\"listWidth()\"\n [style.--_et-qdt-drawer-width.px]=\"drawerWidth()\"\n [style.--_et-qdt-list-height.px]=\"listHeight()\"\n [style.--_et-qdt-drawer-height.px]=\"drawerHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <!-- A pop-out is sized by its window, so there is no edge to drag. -->\n @if (!poppedOut()) {\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n }\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of visibleTabs(); track tab.id) {\n @let badge = tabBadges()[tab.id];\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (badge.count) {\n <span class=\"et-query-devtools-tab-badge\">{{ badge.count }}</span>\n }\n @if (badge.errors) {\n <span\n class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\"\n title=\"{{ badge.errors }} {{ badge.errorNoun ?? 'failing' }}\"\n >\n {{ badge.errors }}\n </span>\n }\n </button>\n }\n\n @if (overflowTabs().length; as overflowCount) {\n <div #tabMenu class=\"et-query-devtools-tab-menu\">\n <button\n [class.et-query-devtools-tab-more--open]=\"tabMenuOpen()\"\n [attr.aria-expanded]=\"tabMenuOpen()\"\n (click)=\"toggleTabMenu()\"\n class=\"et-query-devtools-tab et-query-devtools-tab-more\"\n type=\"button\"\n aria-haspopup=\"true\"\n title=\"{{ overflowCount }} tabs with nothing in them\"\n >\n More\n <span class=\"et-query-devtools-tab-more-caret\" aria-hidden=\"true\">\u25BE</span>\n </button>\n\n @if (tabMenuOpen()) {\n <div class=\"et-query-devtools-tab-menu-list\">\n @for (tab of overflowTabs(); track tab.id) {\n <button (click)=\"selectTab(tab.id)\" class=\"et-query-devtools-tab-menu-item\" type=\"button\">\n {{ tab.label }}\n </button>\n }\n </div>\n }\n </div>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n [attr.aria-pressed]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n <svg\n class=\"et-query-devtools-inspect-icon\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle class=\"et-query-devtools-inspect-icon-ring\" cx=\"8\" cy=\"8\" r=\"4.25\" />\n <circle class=\"et-query-devtools-inspect-icon-dot\" cx=\"8\" cy=\"8\" r=\"1.15\" />\n <path d=\"M8 0.9v2.1M8 13v2.1M0.9 8h2.1M13 8h2.1\" />\n </svg>\n {{ inspectActive() ? 'Inspecting' : 'Inspect' }}\n @if (inspectActive()) {\n <kbd class=\"et-query-devtools-kbd et-query-devtools-kbd--inverse\">Esc</kbd>\n }\n </button>\n <button\n (click)=\"downloadSession()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Download every registered entry, the event log, the cache totals and anything armed as one JSON file - the attachment for a bug report\"\n >\n \u2913 Session\n </button>\n @if (!poppedOut()) {\n <button\n (click)=\"toggleDock()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"{{ dock() === 'bottom' ? 'Dock to the right edge' : 'Dock to the bottom edge' }}\"\n >\n <span aria-hidden=\"true\">{{ dock() === 'bottom' ? '\u25E8' : '\u2B13' }}</span>\n {{ dock() === 'bottom' ? 'Right' : 'Bottom' }}\n </button>\n <button\n (click)=\"popOut()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Move the panel into a window of its own - the same live panel, on your other screen\"\n >\n <span aria-hidden=\"true\">\u29C9</span>\n Pop out\n </button>\n }\n <button\n (click)=\"toggleOpen()\"\n class=\"et-query-devtools-close-panel\"\n type=\"button\"\n title=\"{{ poppedOut() ? 'Bring the panel back into the app window' : 'Close devtools (' + shortcut + ')' }}\"\n >\n @if (poppedOut()) {\n <span aria-hidden=\"true\">\u29C8</span>\n Dock back\n } @else {\n <span aria-hidden=\"true\">\u2715</span>\n Close\n <kbd class=\"et-query-devtools-kbd\">{{ shortcut }}</kbd>\n }\n </button>\n </div>\n </header>\n\n @if (armedFaultClients(); as armed) {\n <div class=\"et-query-devtools-armed-bar\" role=\"status\">\n <span class=\"et-query-devtools-armed-dot\" aria-hidden=\"true\"></span>\n <span class=\"et-query-devtools-armed-text\">\n <strong>Faults armed</strong> on\n <span class=\"et-query-devtools-mono\">{{ armed.join(', ') }}</span>\n \u2014 every failure and delay you see from\n {{ armed.length === 1 ? 'this client' : 'these clients' }} is injected, not the API.\n </span>\n <button\n [disabled]=\"activeTab() === 'faults'\"\n (click)=\"activeTab.set('faults')\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Review\n </button>\n <button (click)=\"CLEAR_FAULTS()\" class=\"et-query-devtools-btn\" type=\"button\">Disarm all</button>\n </div>\n }\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <et-query-devtools-queries-tab />\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <et-query-devtools-stacks-tab />\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <et-query-devtools-sequences-tab />\n }\n\n <!-- FORMS -->\n @case ('forms') {\n <et-query-devtools-forms-tab />\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <et-query-devtools-auth-tab />\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <et-query-devtools-sockets-tab />\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <et-query-devtools-cache-tab />\n }\n\n <!-- TIMELINE -->\n @case ('timeline') {\n <et-query-devtools-timeline-tab />\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <et-query-devtools-events-tab />\n }\n\n <!-- FAULTS -->\n @case ('faults') {\n <et-query-devtools-faults-tab />\n }\n }\n </div>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle [tampered]=\"panelTampered()\" (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-host:where([data-dock=right]){inset-block:0;inset-inline-start:auto}.et-query-devtools-panel:where([data-dock=right]){inline-size:auto;block-size:100%;max-block-size:none;max-inline-size:90vw;border-block-start:0;border-inline-start:1px solid var(--_et-qdt-border);box-shadow:-.4rem 0 2rem #00000059}.et-query-devtools-host:where([data-dock=popout]){position:static;inline-size:100%;block-size:100%}.et-query-devtools-panel:where([data-dock=popout]){block-size:100%;max-block-size:none;border:0;box-shadow:none}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-header{flex-wrap:wrap}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions){flex:1 1 auto;flex-wrap:nowrap;min-inline-size:0;overflow-x:auto}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions)>*{flex:none}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-master-detail,.et-query-devtools-split){flex-direction:column}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-list,.et-query-devtools-detail,.et-query-devtools-drawer,.et-query-devtools-split .et-query-devtools-scroll){flex:1 1 50%;min-inline-size:0;min-block-size:0;max-inline-size:none;border-inline-start:0;border-inline-end:0}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-detail,.et-query-devtools-drawer){border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-master-detail>.et-query-devtools-list{flex:0 1 var(--_et-qdt-list-height, 50%);min-block-size:var(--_et-qdt-list-height, 0);max-block-size:var(--_et-qdt-list-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-split>.et-query-devtools-drawer{flex:0 1 var(--_et-qdt-drawer-height, 50%);min-block-size:var(--_et-qdt-drawer-height, 0);max-block-size:var(--_et-qdt-drawer-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-pane-resize{cursor:ns-resize}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize,.et-query-devtools-pane-resize{touch-action:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize{inset-inline:0 auto;inset-block:0;inline-size:.6rem;block-size:auto;cursor:ew-resize}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize:after{inset-inline:.2rem auto;inset-block:50% auto;inline-size:.2rem;block-size:4rem;margin-inline-start:0;margin-block-start:-2rem}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-armed-bar{display:flex;align-items:center;gap:.8rem;flex:0 0 auto;padding:.6rem .8rem;background:color-mix(in srgb,var(--_et-qdt-error) 14%,transparent);border-block-end:1px solid color-mix(in srgb,var(--_et-qdt-error) 45%,transparent);color:var(--_et-qdt-error);font-size:1.1rem}.et-query-devtools-armed-text{flex:1 1 auto;min-inline-size:0}.et-query-devtools-armed-dot{flex:0 0 auto;inline-size:.8rem;block-size:.8rem;border-radius:50%;background:var(--_et-qdt-error);animation:et-query-devtools-armed-pulse 1.6s ease-in-out infinite}@media(prefers-reduced-motion:reduce){.et-query-devtools-armed-dot{animation:none}}@keyframes et-query-devtools-armed-pulse{50%{opacity:.25}}.et-query-devtools-armed-bar .et-query-devtools-btn{flex:0 0 auto;border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);color:var(--_et-qdt-error)}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-tab-badge{display:inline-block;margin-inline-start:.5rem;padding-inline:.45rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-interaction) 12%,transparent);color:var(--_et-qdt-muted);font-size:1rem;font-variant-numeric:tabular-nums}.et-query-devtools-tab-badge--error{background:color-mix(in srgb,var(--_et-qdt-error) 25%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-tab-menu{position:relative;display:flex}.et-query-devtools-tab-more-caret{margin-inline-start:.4rem}.et-query-devtools-tab-more--open{color:var(--_et-qdt-fg);background:var(--_et-qdt-hover)}.et-query-devtools-tab-menu-list{position:absolute;inset-block-start:100%;inset-inline-start:0;z-index:2;display:flex;flex-direction:column;min-inline-size:14rem;padding:.4rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-bg);box-shadow:0 .4rem 2rem #00000059}.et-query-devtools-tab-menu-item{appearance:none;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-muted);padding:.6rem .8rem;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-tab-menu-item:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;position:relative;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit;transition:color .12s ease,background-color .12s ease,border-color .12s ease}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-inspect-btn:focus-visible{outline:2px solid var(--_et-qdt-accent);outline-offset:2px}.et-query-devtools-inspect-icon{inline-size:1.4rem;block-size:1.4rem;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round}.et-query-devtools-inspect-icon-dot{fill:currentColor;stroke:none}.et-query-devtools-inspect-btn--active,.et-query-devtools-inspect-btn--active:hover{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-inspect-btn--active:after{content:\"\";position:absolute;inset:-.3rem;border:1px solid var(--_et-qdt-accent);border-radius:.6rem;pointer-events:none;animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}@keyframes et-query-devtools-inspect-pulse{0%,to{opacity:.2}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.et-query-devtools-inspect-btn{transition:none}.et-query-devtools-inspect-btn--active:after,.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:none;opacity:1}}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-close-panel{appearance:none;display:inline-flex;align-items:center;gap:.6rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-hover);color:var(--_et-qdt-fg);cursor:pointer;padding:.4rem .6rem .4rem .8rem;font:inherit}.et-query-devtools-close-panel:hover{border-color:var(--_et-qdt-error);color:var(--_et-qdt-error)}.et-query-devtools-kbd{border-radius:.3rem;background:var(--_et-qdt-hover);box-shadow:inset 0 0 0 1px var(--_et-qdt-border);color:var(--_et-qdt-muted);padding:.15rem .4rem;font:inherit;font-size:1.1rem;line-height:1.2;white-space:nowrap}.et-query-devtools-kbd--inverse{background:#00000026;box-shadow:inset 0 0 0 1px #00000040;color:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 var(--_et-qdt-list-width, 34%);min-inline-size:var(--_et-qdt-list-width, 22rem);max-inline-size:var(--_et-qdt-list-width, 40rem);overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;gap:.6rem;padding:.3rem .35rem .3rem .7rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_et-qdt-accent) 45%,transparent);color:var(--_et-qdt-accent);font-size:1.1rem;font-weight:600;letter-spacing:.02em}.et-query-devtools-filter-icon{font-size:1.3rem;line-height:1}.et-query-devtools-filter-count{border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;min-inline-size:1.8rem;padding:0 .5rem;text-align:center}.et-query-devtools-filter-clear{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-filter-clear:hover{border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-pane{display:flex;flex-direction:column;flex:1 1 auto;block-size:100%;min-inline-size:0;min-block-size:0;overflow:hidden}.et-query-devtools-pane>.et-query-devtools-scroll{padding-block:0 1rem}.et-query-devtools-drawer{flex:0 0 var(--_et-qdt-drawer-width, 42%);min-inline-size:var(--_et-qdt-drawer-width, 26rem);max-inline-size:var(--_et-qdt-drawer-width, 48rem);overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-pane-resize{flex:0 0 .5rem;align-self:stretch;cursor:ew-resize;background:transparent;transition:background .12s ease}.et-query-devtools-pane-resize:hover,.et-query-devtools-pane-resize:active{background:var(--_et-qdt-accent)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;flex:1 1 100%;gap:.8rem}.et-query-devtools-list .et-query-devtools-toolbar-row .et-query-devtools-search{flex:1 1 100%}.et-query-devtools-toolbar--filtered{background:linear-gradient(to right,color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent),transparent 65%),var(--_et-qdt-bg);box-shadow:inset .2rem 0 0 var(--_et-qdt-accent),inset 0 -1px color-mix(in srgb,var(--_et-qdt-accent) 30%,transparent)}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:stretch;inline-size:100%;min-block-size:3.6rem;border-block-end:1px solid var(--_et-qdt-border);color:var(--_et-qdt-fg)}.et-query-devtools-row-select{display:flex;flex:1 1 auto;align-items:center;gap:.8rem;min-inline-size:0;text-align:start;appearance:none;border:none;background:transparent;color:inherit;padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row-select>.et-query-devtools-chip{padding-block:.1rem;line-height:1.2}.et-query-devtools-row-pin{display:flex;flex:0 0 auto;align-self:center;align-items:center;justify-content:center;inline-size:3.2rem;block-size:3.2rem;margin-inline-end:.4rem;appearance:none;border:none;border-radius:.4rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font-family:inherit;font-size:1.8rem;line-height:1;opacity:0}.et-query-devtools-row:hover .et-query-devtools-row-pin,.et-query-devtools-row-pin:focus-visible,.et-query-devtools-row-pin--active{opacity:1}.et-query-devtools-row-pin:hover{background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-row-pin--active,.et-query-devtools-row-pin--active:hover{color:var(--_et-qdt-accent)}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-row--gone{color:var(--_et-qdt-muted)}.et-query-devtools-dropped{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none;color:var(--_et-qdt-muted)}.et-query-devtools-dropped li{display:flex;align-items:center;gap:.8rem}.et-query-devtools-gone-note{margin:0 0 .8rem;color:var(--_et-qdt-muted);font-size:1.1rem}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-route-param{color:var(--_et-qdt-accent)}.et-query-devtools-route-query{color:var(--_et-qdt-muted)}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-live{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-live-note{color:var(--_et-qdt-muted);font-size:1.15rem}.et-query-devtools-progress{display:block;flex:1 1 12rem;min-inline-size:8rem;max-inline-size:24rem;block-size:.5rem;border-radius:999px;overflow:hidden;background:var(--_et-qdt-border)}.et-query-devtools-progress-bar{display:block;block-size:100%;border-radius:inherit;background:var(--_et-qdt-accent)}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-btn:disabled{color:var(--_et-qdt-subtle);cursor:default;background:transparent}.et-query-devtools-toolbar-btn{margin-inline-start:auto;flex:0 0 auto}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));gap:.6rem;margin:0 0 1rem}.et-query-devtools-stat{padding:.6rem .8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-stat dt{font-size:1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat dd{margin:0;font-size:1.5rem;font-variant-numeric:tabular-nums}.et-query-devtools-stat-value--sm{font-size:1.2rem}.et-query-devtools-stat-sub{display:block;font-size:1rem;color:var(--_et-qdt-subtle)}.et-query-devtools-traffic{margin-inline-start:auto;flex:0 0 auto;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--_et-qdt-subtle)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-ws-message:where([data-direction=out]){border-inline-start:2px solid color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-ws-direction{color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-ws-message:where([data-direction=out]) .et-query-devtools-ws-direction{color:var(--_et-qdt-accent)}.et-query-devtools-emit{display:flex;align-items:center;gap:.4rem;margin-block:.4rem}.et-query-devtools-emit .et-query-devtools-input{flex:0 0 14rem}.et-query-devtools-emit .et-query-devtools-input+.et-query-devtools-input{flex:1 1 auto}.et-query-devtools-emit .et-query-devtools-btn{flex:0 0 auto}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-features{display:grid;grid-template-columns:max-content minmax(0,1fr);align-items:center;gap:.4rem .8rem;margin:0 0 .8rem;padding:0;list-style:none}.et-query-devtools-meta .et-query-devtools-features{margin-block-end:0}.et-query-devtools-feature{display:contents}.et-query-devtools-feature>.et-query-devtools-chip{justify-self:start}.et-query-devtools-feature-details{display:flex;flex-wrap:wrap;gap:.3rem}.et-query-devtools-feature-detail{display:inline-flex;align-items:baseline;gap:.4rem;padding:.2rem .5rem;border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent);font-size:1.1rem}.et-query-devtools-feature-label{color:var(--_et-qdt-muted)}.et-query-devtools-feature-value{color:var(--_et-qdt-fg);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-retry-glyph{font-size:.7em;line-height:1}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}button.et-query-devtools-chip--button{appearance:none;cursor:pointer;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}button.et-query-devtools-chip--button:hover{border-color:var(--_et-qdt-accent);color:var(--_et-qdt-accent)}.et-query-devtools-caret{display:inline-block;width:1.2rem;color:var(--_et-qdt-muted)}.et-query-devtools-facet{appearance:none;cursor:pointer;color:var(--_et-qdt-muted);font:inherit;font-size:1.1rem;line-height:1.4}.et-query-devtools-facet:hover:not(:disabled){color:var(--_et-qdt-fg);border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent)}.et-query-devtools-facet:disabled{color:var(--_et-qdt-subtle);cursor:default}.et-query-devtools-facet--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 14%,transparent)}.et-query-devtools-facet-count{font-variant-numeric:tabular-nums;color:inherit;opacity:.75}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table td .et-query-devtools-chip{padding-block:0;line-height:1.4}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-cell-actions{display:inline-flex;gap:.4rem;white-space:nowrap}.et-query-devtools-cell-value{padding-inline-start:1.6rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-row-link{display:inline-flex;align-items:center;gap:.6rem;appearance:none;border:0;background:none;padding:0;color:inherit;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-row-link:hover .et-query-devtools-url,.et-query-devtools-row-link:focus-visible .et-query-devtools-url{color:var(--_et-qdt-accent);text-decoration:underline}.et-query-devtools-hint{flex:1 1 24rem;color:var(--_et-qdt-muted);font-size:1.1rem;margin:0}.et-query-devtools-card--armed{border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-error) 6%,transparent)}.et-query-devtools-faults{display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:.8rem 1.6rem}.et-query-devtools-faults .et-query-devtools-field{display:grid;grid-template-columns:8rem minmax(0,1fr);align-items:baseline;row-gap:.2rem;color:var(--_et-qdt-fg)}.et-query-devtools-faults .et-query-devtools-field small{grid-column:2;color:var(--_et-qdt-subtle);font-size:1.1rem}.et-query-devtools-input{inline-size:100%;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-input--number{inline-size:8rem;font-variant-numeric:tabular-nums}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-subtabs{display:flex;flex-wrap:wrap;gap:.2rem;border-block-end:1px solid var(--_et-qdt-border);margin-block:.8rem}.et-query-devtools-subtabs+.et-query-devtools-section-row{padding-block-start:0;border-block-start:0}.et-query-devtools-subtab{appearance:none;display:inline-flex;align-items:center;gap:.4rem;border:0;border-block-end:2px solid transparent;background:transparent;color:var(--_et-qdt-muted);font:inherit;font-size:1.15rem;padding:.4rem .6rem;margin-block-end:-1px;cursor:pointer}.et-query-devtools-subtab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-subtab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-run-cell{display:inline-flex;align-items:center;gap:.5rem}.et-query-devtools-btn--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent)}.et-query-devtools-diff td{max-inline-size:28rem;overflow-wrap:anywhere}.et-query-devtools-diff-before{color:var(--_et-qdt-muted)}.et-query-devtools-diff tr[data-kind=removed] .et-query-devtools-diff-before{color:var(--_et-qdt-error)}.et-query-devtools-diff tr[data-kind=added] .et-query-devtools-diff-after{color:var(--_et-qdt-success)}.et-query-devtools-diff tr[data-kind=changed] .et-query-devtools-diff-after{color:var(--_et-qdt-accent)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsAuthTabComponent, selector: "et-query-devtools-auth-tab" }, { kind: "component", type: QueryDevtoolsCacheTabComponent, selector: "et-query-devtools-cache-tab" }, { kind: "component", type: QueryDevtoolsEventsTabComponent, selector: "et-query-devtools-events-tab" }, { kind: "component", type: QueryDevtoolsFaultsTabComponent, selector: "et-query-devtools-faults-tab" }, { kind: "component", type: QueryDevtoolsFormsTabComponent, selector: "et-query-devtools-forms-tab" }, { kind: "component", type: QueryDevtoolsQueriesTabComponent, selector: "et-query-devtools-queries-tab" }, { kind: "component", type: QueryDevtoolsSequencesTabComponent, selector: "et-query-devtools-sequences-tab" }, { kind: "component", type: QueryDevtoolsSocketsTabComponent, selector: "et-query-devtools-sockets-tab" }, { kind: "component", type: QueryDevtoolsStacksTabComponent, selector: "et-query-devtools-stacks-tab" }, { kind: "component", type: QueryDevtoolsTimelineTabComponent, selector: "et-query-devtools-timeline-tab" }, { kind: "component", type: QueryDevtoolsToggleComponent, selector: "et-query-devtools-toggle", inputs: ["tampered"], outputs: ["openChange"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
53147
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { properties: { "attr.data-dock": "dock()" }, classAttribute: "et-query-devtools-host" }, providers: [{ provide: QUERY_DEVTOOLS_HOST, useExisting: QueryDevtoolsComponent }], viewQueries: [{ propertyName: "panelEl", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "tabMenuEl", first: true, predicate: ["tabMenu"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (open()) {\n <section\n #panel\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [attr.data-dock]=\"poppedOut() ? 'popout' : dock()\"\n [attr.data-pane-axis]=\"paneAxis()\"\n [style.block-size.px]=\"panelBlockSize()\"\n [style.inline-size.px]=\"panelInlineSize()\"\n [style.--_et-qdt-list-width.px]=\"listWidth()\"\n [style.--_et-qdt-drawer-width.px]=\"drawerWidth()\"\n [style.--_et-qdt-list-height.px]=\"listHeight()\"\n [style.--_et-qdt-drawer-height.px]=\"drawerHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <!-- A pop-out is sized by its window, so there is no edge to drag. -->\n @if (!poppedOut()) {\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n }\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of visibleTabs(); track tab.id) {\n @let badge = tabBadges()[tab.id];\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (badge.count) {\n <span class=\"et-query-devtools-tab-badge\">{{ badge.count }}</span>\n }\n @if (badge.errors) {\n <span\n class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\"\n title=\"{{ badge.errors }} {{ badge.errorNoun ?? 'failing' }}\"\n >\n {{ badge.errors }}\n </span>\n }\n </button>\n }\n\n @if (overflowTabs().length; as overflowCount) {\n <div #tabMenu class=\"et-query-devtools-tab-menu\">\n <button\n [class.et-query-devtools-tab-more--open]=\"tabMenuOpen()\"\n [attr.aria-expanded]=\"tabMenuOpen()\"\n (click)=\"toggleTabMenu()\"\n class=\"et-query-devtools-tab et-query-devtools-tab-more\"\n type=\"button\"\n aria-haspopup=\"true\"\n title=\"{{ overflowCount }} tabs with nothing in them\"\n >\n More\n <span class=\"et-query-devtools-tab-more-caret\" aria-hidden=\"true\">\u25BE</span>\n </button>\n\n @if (tabMenuOpen()) {\n <div class=\"et-query-devtools-tab-menu-list\">\n @for (tab of overflowTabs(); track tab.id) {\n <button (click)=\"selectTab(tab.id)\" class=\"et-query-devtools-tab-menu-item\" type=\"button\">\n {{ tab.label }}\n </button>\n }\n </div>\n }\n </div>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n [attr.aria-pressed]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n <svg\n class=\"et-query-devtools-inspect-icon\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle class=\"et-query-devtools-inspect-icon-ring\" cx=\"8\" cy=\"8\" r=\"4.25\" />\n <circle class=\"et-query-devtools-inspect-icon-dot\" cx=\"8\" cy=\"8\" r=\"1.15\" />\n <path d=\"M8 0.9v2.1M8 13v2.1M0.9 8h2.1M13 8h2.1\" />\n </svg>\n {{ inspectActive() ? 'Inspecting' : 'Inspect' }}\n @if (inspectActive()) {\n <kbd class=\"et-query-devtools-kbd et-query-devtools-kbd--inverse\">Esc</kbd>\n }\n </button>\n <button\n (click)=\"downloadSession()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Download every registered entry, the event log, the cache totals and anything armed as one JSON file - the attachment for a bug report\"\n >\n \u2913 Session\n </button>\n @if (!poppedOut()) {\n <button\n (click)=\"toggleDock()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"{{ dock() === 'bottom' ? 'Dock to the right edge' : 'Dock to the bottom edge' }}\"\n >\n <span aria-hidden=\"true\">{{ dock() === 'bottom' ? '\u25E8' : '\u2B13' }}</span>\n {{ dock() === 'bottom' ? 'Right' : 'Bottom' }}\n </button>\n <button\n (click)=\"popOut()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Move the panel into a window of its own - the same live panel, on your other screen\"\n >\n <span aria-hidden=\"true\">\u29C9</span>\n Pop out\n </button>\n }\n <button\n (click)=\"toggleOpen()\"\n class=\"et-query-devtools-close-panel\"\n type=\"button\"\n title=\"{{ poppedOut() ? 'Bring the panel back into the app window' : 'Close devtools (' + shortcut + ')' }}\"\n >\n @if (poppedOut()) {\n <span aria-hidden=\"true\">\u29C8</span>\n Dock back\n } @else {\n <span aria-hidden=\"true\">\u2715</span>\n Close\n <kbd class=\"et-query-devtools-kbd\">{{ shortcut }}</kbd>\n }\n </button>\n </div>\n </header>\n\n @if (armedFaultClients(); as armed) {\n <div class=\"et-query-devtools-armed-bar\" role=\"status\">\n <span class=\"et-query-devtools-armed-dot\" aria-hidden=\"true\"></span>\n <span class=\"et-query-devtools-armed-text\">\n <strong>Faults armed</strong> on\n <span class=\"et-query-devtools-mono\">{{ armed.join(', ') }}</span>\n \u2014 every failure and delay you see from\n {{ armed.length === 1 ? 'this client' : 'these clients' }} is injected, not the API.\n </span>\n <button\n [disabled]=\"activeTab() === 'faults'\"\n (click)=\"activeTab.set('faults')\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Review\n </button>\n <button (click)=\"CLEAR_FAULTS()\" class=\"et-query-devtools-btn\" type=\"button\">Disarm all</button>\n </div>\n }\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <et-query-devtools-queries-tab />\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <et-query-devtools-stacks-tab />\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <et-query-devtools-sequences-tab />\n }\n\n <!-- FORMS -->\n @case ('forms') {\n <et-query-devtools-forms-tab />\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <et-query-devtools-auth-tab />\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <et-query-devtools-sockets-tab />\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <et-query-devtools-cache-tab />\n }\n\n <!-- TIMELINE -->\n @case ('timeline') {\n <et-query-devtools-timeline-tab />\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <et-query-devtools-events-tab />\n }\n\n <!-- FAULTS -->\n @case ('faults') {\n <et-query-devtools-faults-tab />\n }\n }\n </div>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle [tampered]=\"panelTampered()\" (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n\n@if (locatedRect(); as rect) {\n <div\n [style.left.px]=\"rect.left\"\n [style.top.px]=\"rect.top\"\n [style.width.px]=\"rect.width\"\n [style.height.px]=\"rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">created here</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-host:where([data-dock=right]){inset-block:0;inset-inline-start:auto}.et-query-devtools-panel:where([data-dock=right]){inline-size:auto;block-size:100%;max-block-size:none;max-inline-size:90vw;border-block-start:0;border-inline-start:1px solid var(--_et-qdt-border);box-shadow:-.4rem 0 2rem #00000059}.et-query-devtools-host:where([data-dock=popout]){position:static;inline-size:100%;block-size:100%}.et-query-devtools-panel:where([data-dock=popout]){block-size:100%;max-block-size:none;border:0;box-shadow:none}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-header{flex-wrap:wrap}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions){flex:1 1 auto;flex-wrap:nowrap;min-inline-size:0;overflow-x:auto}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions)>*{flex:none}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-master-detail,.et-query-devtools-split){flex-direction:column}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-list,.et-query-devtools-detail,.et-query-devtools-drawer,.et-query-devtools-split .et-query-devtools-scroll){flex:1 1 50%;min-inline-size:0;min-block-size:0;max-inline-size:none;border-inline-start:0;border-inline-end:0}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-detail,.et-query-devtools-drawer){border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-master-detail>.et-query-devtools-list{flex:0 1 var(--_et-qdt-list-height, 50%);min-block-size:var(--_et-qdt-list-height, 0);max-block-size:var(--_et-qdt-list-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-split>.et-query-devtools-drawer{flex:0 1 var(--_et-qdt-drawer-height, 50%);min-block-size:var(--_et-qdt-drawer-height, 0);max-block-size:var(--_et-qdt-drawer-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-pane-resize{cursor:ns-resize}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize,.et-query-devtools-pane-resize{touch-action:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize{inset-inline:0 auto;inset-block:0;inline-size:.6rem;block-size:auto;cursor:ew-resize}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize:after{inset-inline:.2rem auto;inset-block:50% auto;inline-size:.2rem;block-size:4rem;margin-inline-start:0;margin-block-start:-2rem}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-armed-bar{display:flex;align-items:center;gap:.8rem;flex:0 0 auto;padding:.6rem .8rem;background:color-mix(in srgb,var(--_et-qdt-error) 14%,transparent);border-block-end:1px solid color-mix(in srgb,var(--_et-qdt-error) 45%,transparent);color:var(--_et-qdt-error);font-size:1.1rem}.et-query-devtools-armed-text{flex:1 1 auto;min-inline-size:0}.et-query-devtools-armed-dot{flex:0 0 auto;inline-size:.8rem;block-size:.8rem;border-radius:50%;background:var(--_et-qdt-error);animation:et-query-devtools-armed-pulse 1.6s ease-in-out infinite}@media(prefers-reduced-motion:reduce){.et-query-devtools-armed-dot{animation:none}}@keyframes et-query-devtools-armed-pulse{50%{opacity:.25}}.et-query-devtools-armed-bar .et-query-devtools-btn{flex:0 0 auto;border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);color:var(--_et-qdt-error)}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-tab-badge{display:inline-block;margin-inline-start:.5rem;padding-inline:.45rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-interaction) 12%,transparent);color:var(--_et-qdt-muted);font-size:1rem;font-variant-numeric:tabular-nums}.et-query-devtools-tab-badge--error{background:color-mix(in srgb,var(--_et-qdt-error) 25%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-tab-menu{position:relative;display:flex}.et-query-devtools-tab-more-caret{margin-inline-start:.4rem}.et-query-devtools-tab-more--open{color:var(--_et-qdt-fg);background:var(--_et-qdt-hover)}.et-query-devtools-tab-menu-list{position:absolute;inset-block-start:100%;inset-inline-start:0;z-index:2;display:flex;flex-direction:column;min-inline-size:14rem;padding:.4rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-bg);box-shadow:0 .4rem 2rem #00000059}.et-query-devtools-tab-menu-item{appearance:none;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-muted);padding:.6rem .8rem;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-tab-menu-item:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;position:relative;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit;transition:color .12s ease,background-color .12s ease,border-color .12s ease}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-inspect-btn:focus-visible{outline:2px solid var(--_et-qdt-accent);outline-offset:2px}.et-query-devtools-inspect-icon{inline-size:1.4rem;block-size:1.4rem;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round}.et-query-devtools-inspect-icon-dot{fill:currentColor;stroke:none}.et-query-devtools-inspect-btn--active,.et-query-devtools-inspect-btn--active:hover{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-inspect-btn--active:after{content:\"\";position:absolute;inset:-.3rem;border:1px solid var(--_et-qdt-accent);border-radius:.6rem;pointer-events:none;animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}@keyframes et-query-devtools-inspect-pulse{0%,to{opacity:.2}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.et-query-devtools-inspect-btn{transition:none}.et-query-devtools-inspect-btn--active:after,.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:none;opacity:1}}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-close-panel{appearance:none;display:inline-flex;align-items:center;gap:.6rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-hover);color:var(--_et-qdt-fg);cursor:pointer;padding:.4rem .6rem .4rem .8rem;font:inherit}.et-query-devtools-close-panel:hover{border-color:var(--_et-qdt-error);color:var(--_et-qdt-error)}.et-query-devtools-kbd{border-radius:.3rem;background:var(--_et-qdt-hover);box-shadow:inset 0 0 0 1px var(--_et-qdt-border);color:var(--_et-qdt-muted);padding:.15rem .4rem;font:inherit;font-size:1.1rem;line-height:1.2;white-space:nowrap}.et-query-devtools-kbd--inverse{background:#00000026;box-shadow:inset 0 0 0 1px #00000040;color:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;gap:.6rem;padding:.3rem .35rem .3rem .7rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_et-qdt-accent) 45%,transparent);color:var(--_et-qdt-accent);font-size:1.1rem;font-weight:600;letter-spacing:.02em}.et-query-devtools-filter-icon{font-size:1.3rem;line-height:1}.et-query-devtools-filter-count{border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;min-inline-size:1.8rem;padding:0 .5rem;text-align:center}.et-query-devtools-filter-clear{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-filter-clear:hover{border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-pane{display:flex;flex-direction:column;flex:1 1 auto;block-size:100%;min-inline-size:0;min-block-size:0;overflow:hidden}.et-query-devtools-pane>.et-query-devtools-scroll{padding-block:0 1rem}.et-query-devtools-pane-resize{flex:0 0 .5rem;align-self:stretch;cursor:ew-resize;background:transparent;transition:background .12s ease}.et-query-devtools-pane-resize:hover,.et-query-devtools-pane-resize:active{background:var(--_et-qdt-accent)}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;flex:1 1 100%;gap:.8rem}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:stretch;inline-size:100%;min-block-size:3.6rem;border-block-end:1px solid var(--_et-qdt-border);color:var(--_et-qdt-fg)}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-btn:disabled{color:var(--_et-qdt-subtle);cursor:default;background:transparent}.et-query-devtools-toolbar-btn{margin-inline-start:auto;flex:0 0 auto}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat{padding:.6rem .8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-stat dt{font-size:1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat dd{margin:0;font-size:1.5rem;font-variant-numeric:tabular-nums}.et-query-devtools-stat-sub{display:block;font-size:1rem;color:var(--_et-qdt-subtle)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-retry-glyph{font-size:.7em;line-height:1}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}button.et-query-devtools-chip--button{appearance:none;cursor:pointer;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}button.et-query-devtools-chip--button:hover{border-color:var(--_et-qdt-accent);color:var(--_et-qdt-accent)}.et-query-devtools-facet{appearance:none;cursor:pointer;color:var(--_et-qdt-muted);font:inherit;font-size:1.1rem;line-height:1.4}.et-query-devtools-facet:hover:not(:disabled){color:var(--_et-qdt-fg);border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent)}.et-query-devtools-facet:disabled{color:var(--_et-qdt-subtle);cursor:default}.et-query-devtools-facet--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 14%,transparent)}.et-query-devtools-facet-count{font-variant-numeric:tabular-nums;color:inherit;opacity:.75}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table td .et-query-devtools-chip{padding-block:0;line-height:1.4}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-cell-actions{display:inline-flex;gap:.4rem;white-space:nowrap}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-row-link{display:inline-flex;align-items:center;gap:.6rem;appearance:none;border:0;background:none;padding:0;color:inherit;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-row-link:hover .et-query-devtools-url,.et-query-devtools-row-link:focus-visible .et-query-devtools-url{color:var(--_et-qdt-accent);text-decoration:underline}.et-query-devtools-hint{flex:1 1 24rem;color:var(--_et-qdt-muted);font-size:1.1rem;margin:0}.et-query-devtools-input{inline-size:100%;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-btn--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent)}}\n"], dependencies: [{ kind: "component", type: QueryDevtoolsAuthTabComponent, selector: "et-query-devtools-auth-tab" }, { kind: "component", type: QueryDevtoolsCacheTabComponent, selector: "et-query-devtools-cache-tab" }, { kind: "component", type: QueryDevtoolsEventsTabComponent, selector: "et-query-devtools-events-tab" }, { kind: "component", type: QueryDevtoolsFaultsTabComponent, selector: "et-query-devtools-faults-tab" }, { kind: "component", type: QueryDevtoolsFormsTabComponent, selector: "et-query-devtools-forms-tab" }, { kind: "component", type: QueryDevtoolsQueriesTabComponent, selector: "et-query-devtools-queries-tab" }, { kind: "component", type: QueryDevtoolsSequencesTabComponent, selector: "et-query-devtools-sequences-tab" }, { kind: "component", type: QueryDevtoolsSocketsTabComponent, selector: "et-query-devtools-sockets-tab" }, { kind: "component", type: QueryDevtoolsStacksTabComponent, selector: "et-query-devtools-stacks-tab" }, { kind: "component", type: QueryDevtoolsTimelineTabComponent, selector: "et-query-devtools-timeline-tab" }, { kind: "component", type: QueryDevtoolsToggleComponent, selector: "et-query-devtools-toggle", inputs: ["tampered"], outputs: ["openChange"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
52685
53148
|
}
|
|
52686
53149
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
52687
53150
|
type: Component,
|
|
52688
53151
|
args: [{ selector: 'et-query-devtools', encapsulation: ViewEncapsulation.None, imports: [
|
|
52689
53152
|
QueryDevtoolsAuthTabComponent,
|
|
52690
53153
|
QueryDevtoolsCacheTabComponent,
|
|
52691
|
-
QueryDevtoolsDetailComponent,
|
|
52692
|
-
QueryDevtoolsDrawerComponent,
|
|
52693
53154
|
QueryDevtoolsEventsTabComponent,
|
|
52694
53155
|
QueryDevtoolsFaultsTabComponent,
|
|
52695
|
-
QueryDevtoolsFeaturesComponent,
|
|
52696
53156
|
QueryDevtoolsFormsTabComponent,
|
|
52697
|
-
QueryDevtoolsJsonComponent,
|
|
52698
53157
|
QueryDevtoolsQueriesTabComponent,
|
|
52699
|
-
QueryDevtoolsRouteComponent,
|
|
52700
53158
|
QueryDevtoolsSequencesTabComponent,
|
|
52701
53159
|
QueryDevtoolsSocketsTabComponent,
|
|
52702
53160
|
QueryDevtoolsStacksTabComponent,
|
|
@@ -52705,7 +53163,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
52705
53163
|
], providers: [{ provide: QUERY_DEVTOOLS_HOST, useExisting: QueryDevtoolsComponent }], host: {
|
|
52706
53164
|
class: 'et-query-devtools-host',
|
|
52707
53165
|
'[attr.data-dock]': 'dock()',
|
|
52708
|
-
}, template: "@if (open()) {\n <section\n #panel\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [attr.data-dock]=\"poppedOut() ? 'popout' : dock()\"\n [attr.data-pane-axis]=\"paneAxis()\"\n [style.block-size.px]=\"panelBlockSize()\"\n [style.inline-size.px]=\"panelInlineSize()\"\n [style.--_et-qdt-list-width.px]=\"listWidth()\"\n [style.--_et-qdt-drawer-width.px]=\"drawerWidth()\"\n [style.--_et-qdt-list-height.px]=\"listHeight()\"\n [style.--_et-qdt-drawer-height.px]=\"drawerHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <!-- A pop-out is sized by its window, so there is no edge to drag. -->\n @if (!poppedOut()) {\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n }\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of visibleTabs(); track tab.id) {\n @let badge = tabBadges()[tab.id];\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (badge.count) {\n <span class=\"et-query-devtools-tab-badge\">{{ badge.count }}</span>\n }\n @if (badge.errors) {\n <span\n class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\"\n title=\"{{ badge.errors }} {{ badge.errorNoun ?? 'failing' }}\"\n >\n {{ badge.errors }}\n </span>\n }\n </button>\n }\n\n @if (overflowTabs().length; as overflowCount) {\n <div #tabMenu class=\"et-query-devtools-tab-menu\">\n <button\n [class.et-query-devtools-tab-more--open]=\"tabMenuOpen()\"\n [attr.aria-expanded]=\"tabMenuOpen()\"\n (click)=\"toggleTabMenu()\"\n class=\"et-query-devtools-tab et-query-devtools-tab-more\"\n type=\"button\"\n aria-haspopup=\"true\"\n title=\"{{ overflowCount }} tabs with nothing in them\"\n >\n More\n <span class=\"et-query-devtools-tab-more-caret\" aria-hidden=\"true\">\u25BE</span>\n </button>\n\n @if (tabMenuOpen()) {\n <div class=\"et-query-devtools-tab-menu-list\">\n @for (tab of overflowTabs(); track tab.id) {\n <button (click)=\"selectTab(tab.id)\" class=\"et-query-devtools-tab-menu-item\" type=\"button\">\n {{ tab.label }}\n </button>\n }\n </div>\n }\n </div>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n [attr.aria-pressed]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n <svg\n class=\"et-query-devtools-inspect-icon\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle class=\"et-query-devtools-inspect-icon-ring\" cx=\"8\" cy=\"8\" r=\"4.25\" />\n <circle class=\"et-query-devtools-inspect-icon-dot\" cx=\"8\" cy=\"8\" r=\"1.15\" />\n <path d=\"M8 0.9v2.1M8 13v2.1M0.9 8h2.1M13 8h2.1\" />\n </svg>\n {{ inspectActive() ? 'Inspecting' : 'Inspect' }}\n @if (inspectActive()) {\n <kbd class=\"et-query-devtools-kbd et-query-devtools-kbd--inverse\">Esc</kbd>\n }\n </button>\n <button\n (click)=\"downloadSession()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Download every registered entry, the event log, the cache totals and anything armed as one JSON file - the attachment for a bug report\"\n >\n \u2913 Session\n </button>\n @if (!poppedOut()) {\n <button\n (click)=\"toggleDock()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"{{ dock() === 'bottom' ? 'Dock to the right edge' : 'Dock to the bottom edge' }}\"\n >\n <span aria-hidden=\"true\">{{ dock() === 'bottom' ? '\u25E8' : '\u2B13' }}</span>\n {{ dock() === 'bottom' ? 'Right' : 'Bottom' }}\n </button>\n <button\n (click)=\"popOut()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Move the panel into a window of its own - the same live panel, on your other screen\"\n >\n <span aria-hidden=\"true\">\u29C9</span>\n Pop out\n </button>\n }\n <button\n (click)=\"toggleOpen()\"\n class=\"et-query-devtools-close-panel\"\n type=\"button\"\n title=\"{{ poppedOut() ? 'Bring the panel back into the app window' : 'Close devtools (' + shortcut + ')' }}\"\n >\n @if (poppedOut()) {\n <span aria-hidden=\"true\">\u29C8</span>\n Dock back\n } @else {\n <span aria-hidden=\"true\">\u2715</span>\n Close\n <kbd class=\"et-query-devtools-kbd\">{{ shortcut }}</kbd>\n }\n </button>\n </div>\n </header>\n\n @if (armedFaultClients(); as armed) {\n <div class=\"et-query-devtools-armed-bar\" role=\"status\">\n <span class=\"et-query-devtools-armed-dot\" aria-hidden=\"true\"></span>\n <span class=\"et-query-devtools-armed-text\">\n <strong>Faults armed</strong> on\n <span class=\"et-query-devtools-mono\">{{ armed.join(', ') }}</span>\n \u2014 every failure and delay you see from\n {{ armed.length === 1 ? 'this client' : 'these clients' }} is injected, not the API.\n </span>\n <button\n [disabled]=\"activeTab() === 'faults'\"\n (click)=\"activeTab.set('faults')\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Review\n </button>\n <button (click)=\"CLEAR_FAULTS()\" class=\"et-query-devtools-btn\" type=\"button\">Disarm all</button>\n </div>\n }\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <et-query-devtools-queries-tab />\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <et-query-devtools-stacks-tab />\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <et-query-devtools-sequences-tab />\n }\n\n <!-- FORMS -->\n @case ('forms') {\n <et-query-devtools-forms-tab />\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <et-query-devtools-auth-tab />\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <et-query-devtools-sockets-tab />\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <et-query-devtools-cache-tab />\n }\n\n <!-- TIMELINE -->\n @case ('timeline') {\n <et-query-devtools-timeline-tab />\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <et-query-devtools-events-tab />\n }\n\n <!-- FAULTS -->\n @case ('faults') {\n <et-query-devtools-faults-tab />\n }\n }\n </div>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle [tampered]=\"panelTampered()\" (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-host:where([data-dock=right]){inset-block:0;inset-inline-start:auto}.et-query-devtools-panel:where([data-dock=right]){inline-size:auto;block-size:100%;max-block-size:none;max-inline-size:90vw;border-block-start:0;border-inline-start:1px solid var(--_et-qdt-border);box-shadow:-.4rem 0 2rem #00000059}.et-query-devtools-host:where([data-dock=popout]){position:static;inline-size:100%;block-size:100%}.et-query-devtools-panel:where([data-dock=popout]){block-size:100%;max-block-size:none;border:0;box-shadow:none}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-header{flex-wrap:wrap}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions){flex:1 1 auto;flex-wrap:nowrap;min-inline-size:0;overflow-x:auto}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions)>*{flex:none}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-master-detail,.et-query-devtools-split){flex-direction:column}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-list,.et-query-devtools-detail,.et-query-devtools-drawer,.et-query-devtools-split .et-query-devtools-scroll){flex:1 1 50%;min-inline-size:0;min-block-size:0;max-inline-size:none;border-inline-start:0;border-inline-end:0}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-detail,.et-query-devtools-drawer){border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-master-detail>.et-query-devtools-list{flex:0 1 var(--_et-qdt-list-height, 50%);min-block-size:var(--_et-qdt-list-height, 0);max-block-size:var(--_et-qdt-list-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-split>.et-query-devtools-drawer{flex:0 1 var(--_et-qdt-drawer-height, 50%);min-block-size:var(--_et-qdt-drawer-height, 0);max-block-size:var(--_et-qdt-drawer-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-pane-resize{cursor:ns-resize}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize,.et-query-devtools-pane-resize{touch-action:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize{inset-inline:0 auto;inset-block:0;inline-size:.6rem;block-size:auto;cursor:ew-resize}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize:after{inset-inline:.2rem auto;inset-block:50% auto;inline-size:.2rem;block-size:4rem;margin-inline-start:0;margin-block-start:-2rem}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-armed-bar{display:flex;align-items:center;gap:.8rem;flex:0 0 auto;padding:.6rem .8rem;background:color-mix(in srgb,var(--_et-qdt-error) 14%,transparent);border-block-end:1px solid color-mix(in srgb,var(--_et-qdt-error) 45%,transparent);color:var(--_et-qdt-error);font-size:1.1rem}.et-query-devtools-armed-text{flex:1 1 auto;min-inline-size:0}.et-query-devtools-armed-dot{flex:0 0 auto;inline-size:.8rem;block-size:.8rem;border-radius:50%;background:var(--_et-qdt-error);animation:et-query-devtools-armed-pulse 1.6s ease-in-out infinite}@media(prefers-reduced-motion:reduce){.et-query-devtools-armed-dot{animation:none}}@keyframes et-query-devtools-armed-pulse{50%{opacity:.25}}.et-query-devtools-armed-bar .et-query-devtools-btn{flex:0 0 auto;border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);color:var(--_et-qdt-error)}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-tab-badge{display:inline-block;margin-inline-start:.5rem;padding-inline:.45rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-interaction) 12%,transparent);color:var(--_et-qdt-muted);font-size:1rem;font-variant-numeric:tabular-nums}.et-query-devtools-tab-badge--error{background:color-mix(in srgb,var(--_et-qdt-error) 25%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-tab-menu{position:relative;display:flex}.et-query-devtools-tab-more-caret{margin-inline-start:.4rem}.et-query-devtools-tab-more--open{color:var(--_et-qdt-fg);background:var(--_et-qdt-hover)}.et-query-devtools-tab-menu-list{position:absolute;inset-block-start:100%;inset-inline-start:0;z-index:2;display:flex;flex-direction:column;min-inline-size:14rem;padding:.4rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-bg);box-shadow:0 .4rem 2rem #00000059}.et-query-devtools-tab-menu-item{appearance:none;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-muted);padding:.6rem .8rem;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-tab-menu-item:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;position:relative;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit;transition:color .12s ease,background-color .12s ease,border-color .12s ease}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-inspect-btn:focus-visible{outline:2px solid var(--_et-qdt-accent);outline-offset:2px}.et-query-devtools-inspect-icon{inline-size:1.4rem;block-size:1.4rem;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round}.et-query-devtools-inspect-icon-dot{fill:currentColor;stroke:none}.et-query-devtools-inspect-btn--active,.et-query-devtools-inspect-btn--active:hover{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-inspect-btn--active:after{content:\"\";position:absolute;inset:-.3rem;border:1px solid var(--_et-qdt-accent);border-radius:.6rem;pointer-events:none;animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}@keyframes et-query-devtools-inspect-pulse{0%,to{opacity:.2}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.et-query-devtools-inspect-btn{transition:none}.et-query-devtools-inspect-btn--active:after,.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:none;opacity:1}}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-close-panel{appearance:none;display:inline-flex;align-items:center;gap:.6rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-hover);color:var(--_et-qdt-fg);cursor:pointer;padding:.4rem .6rem .4rem .8rem;font:inherit}.et-query-devtools-close-panel:hover{border-color:var(--_et-qdt-error);color:var(--_et-qdt-error)}.et-query-devtools-kbd{border-radius:.3rem;background:var(--_et-qdt-hover);box-shadow:inset 0 0 0 1px var(--_et-qdt-border);color:var(--_et-qdt-muted);padding:.15rem .4rem;font:inherit;font-size:1.1rem;line-height:1.2;white-space:nowrap}.et-query-devtools-kbd--inverse{background:#00000026;box-shadow:inset 0 0 0 1px #00000040;color:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-master-detail{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-list{flex:0 0 var(--_et-qdt-list-width, 34%);min-inline-size:var(--_et-qdt-list-width, 22rem);max-inline-size:var(--_et-qdt-list-width, 40rem);overflow-y:auto;border-inline-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-detail-head,.et-query-devtools-drawer .et-query-devtools-detail-head{padding-block-end:.8rem;border-block-end:1px solid var(--_et-qdt-border)}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;gap:.6rem;padding:.3rem .35rem .3rem .7rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_et-qdt-accent) 45%,transparent);color:var(--_et-qdt-accent);font-size:1.1rem;font-weight:600;letter-spacing:.02em}.et-query-devtools-filter-icon{font-size:1.3rem;line-height:1}.et-query-devtools-filter-count{border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;min-inline-size:1.8rem;padding:0 .5rem;text-align:center}.et-query-devtools-filter-clear{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-filter-clear:hover{border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-pane{display:flex;flex-direction:column;flex:1 1 auto;block-size:100%;min-inline-size:0;min-block-size:0;overflow:hidden}.et-query-devtools-pane>.et-query-devtools-scroll{padding-block:0 1rem}.et-query-devtools-drawer{flex:0 0 var(--_et-qdt-drawer-width, 42%);min-inline-size:var(--_et-qdt-drawer-width, 26rem);max-inline-size:var(--_et-qdt-drawer-width, 48rem);overflow-y:auto;padding:0 1rem 1rem;border-inline-start:1px solid var(--_et-qdt-border)}.et-query-devtools-pane-resize{flex:0 0 .5rem;align-self:stretch;cursor:ew-resize;background:transparent;transition:background .12s ease}.et-query-devtools-pane-resize:hover,.et-query-devtools-pane-resize:active{background:var(--_et-qdt-accent)}.et-query-devtools-drawer-head{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding:.8rem 0;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg);color:var(--_et-qdt-muted);border-block-end:1px solid var(--_et-qdt-border);margin-block-end:.8rem}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;flex:1 1 100%;gap:.8rem}.et-query-devtools-list .et-query-devtools-toolbar-row .et-query-devtools-search{flex:1 1 100%}.et-query-devtools-toolbar--filtered{background:linear-gradient(to right,color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent),transparent 65%),var(--_et-qdt-bg);box-shadow:inset .2rem 0 0 var(--_et-qdt-accent),inset 0 -1px color-mix(in srgb,var(--_et-qdt-accent) 30%,transparent)}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:stretch;inline-size:100%;min-block-size:3.6rem;border-block-end:1px solid var(--_et-qdt-border);color:var(--_et-qdt-fg)}.et-query-devtools-row-select{display:flex;flex:1 1 auto;align-items:center;gap:.8rem;min-inline-size:0;text-align:start;appearance:none;border:none;background:transparent;color:inherit;padding:.8rem;cursor:pointer;font:inherit}.et-query-devtools-row-select>.et-query-devtools-chip{padding-block:.1rem;line-height:1.2}.et-query-devtools-row-pin{display:flex;flex:0 0 auto;align-self:center;align-items:center;justify-content:center;inline-size:3.2rem;block-size:3.2rem;margin-inline-end:.4rem;appearance:none;border:none;border-radius:.4rem;background:transparent;color:var(--_et-qdt-subtle);cursor:pointer;font-family:inherit;font-size:1.8rem;line-height:1;opacity:0}.et-query-devtools-row:hover .et-query-devtools-row-pin,.et-query-devtools-row-pin:focus-visible,.et-query-devtools-row-pin--active{opacity:1}.et-query-devtools-row-pin:hover{background:var(--_et-qdt-active);color:var(--_et-qdt-fg)}.et-query-devtools-row-pin--active,.et-query-devtools-row-pin--active:hover{color:var(--_et-qdt-accent)}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-row--active{background:var(--_et-qdt-active)}.et-query-devtools-row--gone{color:var(--_et-qdt-muted)}.et-query-devtools-dropped{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none;color:var(--_et-qdt-muted)}.et-query-devtools-dropped li{display:flex;align-items:center;gap:.8rem}.et-query-devtools-gone-note{margin:0 0 .8rem;color:var(--_et-qdt-muted);font-size:1.1rem}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-route-param{color:var(--_et-qdt-accent)}.et-query-devtools-route-query{color:var(--_et-qdt-muted)}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-detail-head{display:flex;align-items:center;gap:.8rem;margin-block-end:.8rem}.et-query-devtools-live{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-live-note{color:var(--_et-qdt-muted);font-size:1.15rem}.et-query-devtools-progress{display:block;flex:1 1 12rem;min-inline-size:8rem;max-inline-size:24rem;block-size:.5rem;border-radius:999px;overflow:hidden;background:var(--_et-qdt-border)}.et-query-devtools-progress-bar{display:block;block-size:100%;border-radius:inherit;background:var(--_et-qdt-accent)}.et-query-devtools-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;margin-block-end:.8rem}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-btn:disabled{color:var(--_et-qdt-subtle);cursor:default;background:transparent}.et-query-devtools-toolbar-btn{margin-inline-start:auto;flex:0 0 auto}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(12rem,1fr));gap:.6rem;margin:0 0 1rem}.et-query-devtools-stat{padding:.6rem .8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-stat dt{font-size:1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat dd{margin:0;font-size:1.5rem;font-variant-numeric:tabular-nums}.et-query-devtools-stat-value--sm{font-size:1.2rem}.et-query-devtools-stat-sub{display:block;font-size:1rem;color:var(--_et-qdt-subtle)}.et-query-devtools-traffic{margin-inline-start:auto;flex:0 0 auto;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--_et-qdt-subtle)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-code{margin:0 0 .8rem;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:1.15rem;max-block-size:20rem}.et-query-devtools-ws-message{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;margin-block-end:.4rem}.et-query-devtools-ws-message:where([data-direction=out]){border-inline-start:2px solid color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-ws-direction{color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-ws-message:where([data-direction=out]) .et-query-devtools-ws-direction{color:var(--_et-qdt-accent)}.et-query-devtools-emit{display:flex;align-items:center;gap:.4rem;margin-block:.4rem}.et-query-devtools-emit .et-query-devtools-input{flex:0 0 14rem}.et-query-devtools-emit .et-query-devtools-input+.et-query-devtools-input{flex:1 1 auto}.et-query-devtools-emit .et-query-devtools-btn{flex:0 0 auto}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-features{display:grid;grid-template-columns:max-content minmax(0,1fr);align-items:center;gap:.4rem .8rem;margin:0 0 .8rem;padding:0;list-style:none}.et-query-devtools-meta .et-query-devtools-features{margin-block-end:0}.et-query-devtools-feature{display:contents}.et-query-devtools-feature>.et-query-devtools-chip{justify-self:start}.et-query-devtools-feature-details{display:flex;flex-wrap:wrap;gap:.3rem}.et-query-devtools-feature-detail{display:inline-flex;align-items:baseline;gap:.4rem;padding:.2rem .5rem;border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 5%,transparent);font-size:1.1rem}.et-query-devtools-feature-label{color:var(--_et-qdt-muted)}.et-query-devtools-feature-value{color:var(--_et-qdt-fg);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-retry-glyph{font-size:.7em;line-height:1}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}button.et-query-devtools-chip--button{appearance:none;cursor:pointer;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}button.et-query-devtools-chip--button:hover{border-color:var(--_et-qdt-accent);color:var(--_et-qdt-accent)}.et-query-devtools-caret{display:inline-block;width:1.2rem;color:var(--_et-qdt-muted)}.et-query-devtools-facet{appearance:none;cursor:pointer;color:var(--_et-qdt-muted);font:inherit;font-size:1.1rem;line-height:1.4}.et-query-devtools-facet:hover:not(:disabled){color:var(--_et-qdt-fg);border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent)}.et-query-devtools-facet:disabled{color:var(--_et-qdt-subtle);cursor:default}.et-query-devtools-facet--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 14%,transparent)}.et-query-devtools-facet-count{font-variant-numeric:tabular-nums;color:inherit;opacity:.75}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-card-title{display:flex;align-items:baseline;gap:.5rem;margin-block-end:.2rem}.et-query-devtools-card-sub{color:var(--_et-qdt-subtle);font-size:1.1rem;margin-block-end:.6rem;overflow-wrap:anywhere}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-list{display:flex;flex-direction:column;gap:.4rem;margin:0;padding:0;list-style:none}.et-query-devtools-step-item{border:1px solid var(--_et-qdt-border);border-radius:.4rem;overflow:hidden}.et-query-devtools-step-item[data-status=error]{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-step-head{display:flex;align-items:stretch}.et-query-devtools-step-head .et-query-devtools-inner-row{border:none;border-radius:0;flex:1 1 auto}.et-query-devtools-step-caret-btn{appearance:none;border:none;border-inline-start:1px solid var(--_et-qdt-border);background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:0 .7rem;font:inherit}.et-query-devtools-step-caret-btn:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-step-io{padding:0 .8rem .8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table td .et-query-devtools-chip{padding-block:0;line-height:1.4}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-actions-label{color:var(--_et-qdt-subtle);align-self:center;text-transform:uppercase;font-size:1rem;letter-spacing:.05em}.et-query-devtools-actions-label:not(:first-child){margin-inline-start:.7rem}.et-query-devtools-cell-actions{display:inline-flex;gap:.4rem;white-space:nowrap}.et-query-devtools-cell-value{padding-inline-start:1.6rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-row-link{display:inline-flex;align-items:center;gap:.6rem;appearance:none;border:0;background:none;padding:0;color:inherit;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-row-link:hover .et-query-devtools-url,.et-query-devtools-row-link:focus-visible .et-query-devtools-url{color:var(--_et-qdt-accent);text-decoration:underline}.et-query-devtools-hint{flex:1 1 24rem;color:var(--_et-qdt-muted);font-size:1.1rem;margin:0}.et-query-devtools-card--armed{border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-error) 6%,transparent)}.et-query-devtools-faults{display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:.8rem 1.6rem}.et-query-devtools-faults .et-query-devtools-field{display:grid;grid-template-columns:8rem minmax(0,1fr);align-items:baseline;row-gap:.2rem;color:var(--_et-qdt-fg)}.et-query-devtools-faults .et-query-devtools-field small{grid-column:2;color:var(--_et-qdt-subtle);font-size:1.1rem}.et-query-devtools-input{inline-size:100%;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-input--number{inline-size:8rem;font-variant-numeric:tabular-nums}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-textarea{inline-size:100%;min-block-size:12rem;resize:vertical;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.6rem;font-family:inherit;font-size:1.2rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-subtabs{display:flex;flex-wrap:wrap;gap:.2rem;border-block-end:1px solid var(--_et-qdt-border);margin-block:.8rem}.et-query-devtools-subtabs+.et-query-devtools-section-row{padding-block-start:0;border-block-start:0}.et-query-devtools-subtab{appearance:none;display:inline-flex;align-items:center;gap:.4rem;border:0;border-block-end:2px solid transparent;background:transparent;color:var(--_et-qdt-muted);font:inherit;font-size:1.15rem;padding:.4rem .6rem;margin-block-end:-1px;cursor:pointer}.et-query-devtools-subtab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-subtab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-run-cell{display:inline-flex;align-items:center;gap:.5rem}.et-query-devtools-btn--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent)}.et-query-devtools-diff td{max-inline-size:28rem;overflow-wrap:anywhere}.et-query-devtools-diff-before{color:var(--_et-qdt-muted)}.et-query-devtools-diff tr[data-kind=removed] .et-query-devtools-diff-before{color:var(--_et-qdt-error)}.et-query-devtools-diff tr[data-kind=added] .et-query-devtools-diff-after{color:var(--_et-qdt-success)}.et-query-devtools-diff tr[data-kind=changed] .et-query-devtools-diff-after{color:var(--_et-qdt-accent)}}\n"] }]
|
|
53166
|
+
}, template: "@if (open()) {\n <section\n #panel\n [class.et-query-devtools-panel--resizing]=\"resizing()\"\n [attr.data-dock]=\"poppedOut() ? 'popout' : dock()\"\n [attr.data-pane-axis]=\"paneAxis()\"\n [style.block-size.px]=\"panelBlockSize()\"\n [style.inline-size.px]=\"panelInlineSize()\"\n [style.--_et-qdt-list-width.px]=\"listWidth()\"\n [style.--_et-qdt-drawer-width.px]=\"drawerWidth()\"\n [style.--_et-qdt-list-height.px]=\"listHeight()\"\n [style.--_et-qdt-drawer-height.px]=\"drawerHeight()\"\n class=\"et-query-devtools-panel\"\n >\n <!-- A pop-out is sized by its window, so there is no edge to drag. -->\n @if (!poppedOut()) {\n <div\n (pointerdown)=\"startResize($event)\"\n class=\"et-query-devtools-resize\"\n title=\"Drag to resize\"\n aria-hidden=\"true\"\n ></div>\n }\n <header class=\"et-query-devtools-header\">\n <nav class=\"et-query-devtools-tabs\" role=\"tablist\">\n @for (tab of visibleTabs(); track tab.id) {\n @let badge = tabBadges()[tab.id];\n <button\n [class.et-query-devtools-tab--active]=\"activeTab() === tab.id\"\n [attr.aria-selected]=\"activeTab() === tab.id\"\n (click)=\"activeTab.set(tab.id)\"\n class=\"et-query-devtools-tab\"\n type=\"button\"\n role=\"tab\"\n >\n {{ tab.label }}\n @if (badge.count) {\n <span class=\"et-query-devtools-tab-badge\">{{ badge.count }}</span>\n }\n @if (badge.errors) {\n <span\n class=\"et-query-devtools-tab-badge et-query-devtools-tab-badge--error\"\n title=\"{{ badge.errors }} {{ badge.errorNoun ?? 'failing' }}\"\n >\n {{ badge.errors }}\n </span>\n }\n </button>\n }\n\n @if (overflowTabs().length; as overflowCount) {\n <div #tabMenu class=\"et-query-devtools-tab-menu\">\n <button\n [class.et-query-devtools-tab-more--open]=\"tabMenuOpen()\"\n [attr.aria-expanded]=\"tabMenuOpen()\"\n (click)=\"toggleTabMenu()\"\n class=\"et-query-devtools-tab et-query-devtools-tab-more\"\n type=\"button\"\n aria-haspopup=\"true\"\n title=\"{{ overflowCount }} tabs with nothing in them\"\n >\n More\n <span class=\"et-query-devtools-tab-more-caret\" aria-hidden=\"true\">\u25BE</span>\n </button>\n\n @if (tabMenuOpen()) {\n <div class=\"et-query-devtools-tab-menu-list\">\n @for (tab of overflowTabs(); track tab.id) {\n <button (click)=\"selectTab(tab.id)\" class=\"et-query-devtools-tab-menu-item\" type=\"button\">\n {{ tab.label }}\n </button>\n }\n </div>\n }\n </div>\n }\n </nav>\n\n <div class=\"et-query-devtools-header-actions\">\n <button\n [class.et-query-devtools-inspect-btn--active]=\"inspectActive()\"\n [attr.aria-pressed]=\"inspectActive()\"\n (click)=\"toggleInspect()\"\n class=\"et-query-devtools-inspect-btn\"\n type=\"button\"\n title=\"Inspect: hover the UI to find its query\"\n >\n <svg\n class=\"et-query-devtools-inspect-icon\"\n viewBox=\"0 0 16 16\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle class=\"et-query-devtools-inspect-icon-ring\" cx=\"8\" cy=\"8\" r=\"4.25\" />\n <circle class=\"et-query-devtools-inspect-icon-dot\" cx=\"8\" cy=\"8\" r=\"1.15\" />\n <path d=\"M8 0.9v2.1M8 13v2.1M0.9 8h2.1M13 8h2.1\" />\n </svg>\n {{ inspectActive() ? 'Inspecting' : 'Inspect' }}\n @if (inspectActive()) {\n <kbd class=\"et-query-devtools-kbd et-query-devtools-kbd--inverse\">Esc</kbd>\n }\n </button>\n <button\n (click)=\"downloadSession()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Download every registered entry, the event log, the cache totals and anything armed as one JSON file - the attachment for a bug report\"\n >\n \u2913 Session\n </button>\n @if (!poppedOut()) {\n <button\n (click)=\"toggleDock()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"{{ dock() === 'bottom' ? 'Dock to the right edge' : 'Dock to the bottom edge' }}\"\n >\n <span aria-hidden=\"true\">{{ dock() === 'bottom' ? '\u25E8' : '\u2B13' }}</span>\n {{ dock() === 'bottom' ? 'Right' : 'Bottom' }}\n </button>\n <button\n (click)=\"popOut()\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n title=\"Move the panel into a window of its own - the same live panel, on your other screen\"\n >\n <span aria-hidden=\"true\">\u29C9</span>\n Pop out\n </button>\n }\n <button\n (click)=\"toggleOpen()\"\n class=\"et-query-devtools-close-panel\"\n type=\"button\"\n title=\"{{ poppedOut() ? 'Bring the panel back into the app window' : 'Close devtools (' + shortcut + ')' }}\"\n >\n @if (poppedOut()) {\n <span aria-hidden=\"true\">\u29C8</span>\n Dock back\n } @else {\n <span aria-hidden=\"true\">\u2715</span>\n Close\n <kbd class=\"et-query-devtools-kbd\">{{ shortcut }}</kbd>\n }\n </button>\n </div>\n </header>\n\n @if (armedFaultClients(); as armed) {\n <div class=\"et-query-devtools-armed-bar\" role=\"status\">\n <span class=\"et-query-devtools-armed-dot\" aria-hidden=\"true\"></span>\n <span class=\"et-query-devtools-armed-text\">\n <strong>Faults armed</strong> on\n <span class=\"et-query-devtools-mono\">{{ armed.join(', ') }}</span>\n \u2014 every failure and delay you see from\n {{ armed.length === 1 ? 'this client' : 'these clients' }} is injected, not the API.\n </span>\n <button\n [disabled]=\"activeTab() === 'faults'\"\n (click)=\"activeTab.set('faults')\"\n class=\"et-query-devtools-btn\"\n type=\"button\"\n >\n Review\n </button>\n <button (click)=\"CLEAR_FAULTS()\" class=\"et-query-devtools-btn\" type=\"button\">Disarm all</button>\n </div>\n }\n\n <div class=\"et-query-devtools-body\">\n @switch (activeTab()) {\n <!-- QUERIES -->\n @case ('queries') {\n <et-query-devtools-queries-tab />\n }\n\n <!-- STACKS -->\n @case ('stacks') {\n <et-query-devtools-stacks-tab />\n }\n\n <!-- SEQUENCES -->\n @case ('sequences') {\n <et-query-devtools-sequences-tab />\n }\n\n <!-- FORMS -->\n @case ('forms') {\n <et-query-devtools-forms-tab />\n }\n\n <!-- AUTH -->\n @case ('auth') {\n <et-query-devtools-auth-tab />\n }\n\n <!-- SOCKETS -->\n @case ('ws') {\n <et-query-devtools-sockets-tab />\n }\n\n <!-- CACHE -->\n @case ('cache') {\n <et-query-devtools-cache-tab />\n }\n\n <!-- TIMELINE -->\n @case ('timeline') {\n <et-query-devtools-timeline-tab />\n }\n\n <!-- EVENTS -->\n @case ('events') {\n <et-query-devtools-events-tab />\n }\n\n <!-- FAULTS -->\n @case ('faults') {\n <et-query-devtools-faults-tab />\n }\n }\n </div>\n </section>\n}\n\n@if (!open()) {\n <et-query-devtools-toggle [tampered]=\"panelTampered()\" (openChange)=\"toggleOpen()\" />\n}\n\n@if (inspectActive() && inspectHover(); as hover) {\n <div\n [style.left.px]=\"hover.rect.left\"\n [style.top.px]=\"hover.rect.top\"\n [style.width.px]=\"hover.rect.width\"\n [style.height.px]=\"hover.rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">{{ inspectLabel(hover.entries) }}</span>\n </div>\n}\n\n@if (locatedRect(); as rect) {\n <div\n [style.left.px]=\"rect.left\"\n [style.top.px]=\"rect.top\"\n [style.width.px]=\"rect.width\"\n [style.height.px]=\"rect.height\"\n class=\"et-query-devtools-inspect-box\"\n >\n <span class=\"et-query-devtools-inspect-tag\">created here</span>\n </div>\n}\n", styles: ["@layer components{.et-query-devtools-host{--_et-qdt-bg: var(--et-surface-background-solid, rgb(24 24 27));--_et-qdt-fg: var(--et-surface-color-solid, rgb(244 244 245));--_et-qdt-muted: var(--et-surface-color-muted-solid, rgb(161 161 170));--_et-qdt-subtle: var(--et-surface-color-subtle-solid, rgb(113 113 122));--_et-qdt-border: var(--et-surface-border-solid, rgb(255 255 255 / .12));--_et-qdt-interaction: var(--et-surface-interaction-solid, rgb(255 255 255));--_et-qdt-accent: var(--et-theme-color-primary-solid, rgb(96 165 250));--_et-qdt-hover: color-mix(in srgb, var(--_et-qdt-interaction) 10%, transparent);--_et-qdt-active: color-mix(in srgb, var(--_et-qdt-interaction) 18%, transparent);--_et-qdt-success: rgb(34 197 94);--_et-qdt-error: rgb(239 68 68);--_et-qdt-loading: rgb(234 179 8);position:fixed;inset-inline:0;inset-block-end:0;z-index:2147483000;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,Liberation Mono,monospace;font-size:1.2rem;line-height:1.4;pointer-events:none}.et-query-devtools-host>*{pointer-events:auto}.et-query-devtools-panel{position:relative;display:flex;flex-direction:column;inline-size:100%;min-block-size:20rem;max-block-size:90vh;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border-block-start:1px solid var(--_et-qdt-border);box-shadow:0 -.4rem 2rem #00000059}.et-query-devtools-host:where([data-dock=right]){inset-block:0;inset-inline-start:auto}.et-query-devtools-panel:where([data-dock=right]){inline-size:auto;block-size:100%;max-block-size:none;max-inline-size:90vw;border-block-start:0;border-inline-start:1px solid var(--_et-qdt-border);box-shadow:-.4rem 0 2rem #00000059}.et-query-devtools-host:where([data-dock=popout]){position:static;inline-size:100%;block-size:100%}.et-query-devtools-panel:where([data-dock=popout]){block-size:100%;max-block-size:none;border:0;box-shadow:none}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-header{flex-wrap:wrap}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions){flex:1 1 auto;flex-wrap:nowrap;min-inline-size:0;overflow-x:auto}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-tabs,.et-query-devtools-header-actions)>*{flex:none}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-master-detail,.et-query-devtools-split){flex-direction:column}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-list,.et-query-devtools-detail,.et-query-devtools-drawer,.et-query-devtools-split .et-query-devtools-scroll){flex:1 1 50%;min-inline-size:0;min-block-size:0;max-inline-size:none;border-inline-start:0;border-inline-end:0}.et-query-devtools-panel:where([data-pane-axis=block]) :is(.et-query-devtools-detail,.et-query-devtools-drawer){border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-master-detail>.et-query-devtools-list{flex:0 1 var(--_et-qdt-list-height, 50%);min-block-size:var(--_et-qdt-list-height, 0);max-block-size:var(--_et-qdt-list-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-split>.et-query-devtools-drawer{flex:0 1 var(--_et-qdt-drawer-height, 50%);min-block-size:var(--_et-qdt-drawer-height, 0);max-block-size:var(--_et-qdt-drawer-height, none)}.et-query-devtools-panel:where([data-pane-axis=block]) .et-query-devtools-pane-resize{cursor:ns-resize}.et-query-devtools-panel--resizing{-webkit-user-select:none;user-select:none}.et-query-devtools-resize,.et-query-devtools-pane-resize{touch-action:none}.et-query-devtools-resize{position:absolute;inset-inline:0;inset-block-start:0;block-size:.6rem;cursor:ns-resize;z-index:1}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize{inset-inline:0 auto;inset-block:0;inline-size:.6rem;block-size:auto;cursor:ew-resize}.et-query-devtools-resize:after{content:\"\";position:absolute;inset-inline:50%;inset-block-start:.2rem;inline-size:4rem;margin-inline-start:-2rem;block-size:.2rem;border-radius:999px;background:var(--_et-qdt-border)}.et-query-devtools-panel:where([data-dock=right]) .et-query-devtools-resize:after{inset-inline:.2rem auto;inset-block:50% auto;inline-size:.2rem;block-size:4rem;margin-inline-start:0;margin-block-start:-2rem}.et-query-devtools-resize:hover:after{background:var(--_et-qdt-accent)}.et-query-devtools-header{display:flex;align-items:center;justify-content:space-between;gap:.8rem;padding-inline:.8rem;border-block-end:1px solid var(--_et-qdt-border);flex:0 0 auto}.et-query-devtools-armed-bar{display:flex;align-items:center;gap:.8rem;flex:0 0 auto;padding:.6rem .8rem;background:color-mix(in srgb,var(--_et-qdt-error) 14%,transparent);border-block-end:1px solid color-mix(in srgb,var(--_et-qdt-error) 45%,transparent);color:var(--_et-qdt-error);font-size:1.1rem}.et-query-devtools-armed-text{flex:1 1 auto;min-inline-size:0}.et-query-devtools-armed-dot{flex:0 0 auto;inline-size:.8rem;block-size:.8rem;border-radius:50%;background:var(--_et-qdt-error);animation:et-query-devtools-armed-pulse 1.6s ease-in-out infinite}@media(prefers-reduced-motion:reduce){.et-query-devtools-armed-dot{animation:none}}@keyframes et-query-devtools-armed-pulse{50%{opacity:.25}}.et-query-devtools-armed-bar .et-query-devtools-btn{flex:0 0 auto;border-color:color-mix(in srgb,var(--_et-qdt-error) 55%,transparent);color:var(--_et-qdt-error)}.et-query-devtools-tabs{display:flex;flex-wrap:wrap;gap:.2rem}.et-query-devtools-tab{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);padding:.9rem 1rem;cursor:pointer;border-block-end:2px solid transparent;font:inherit}.et-query-devtools-tab:hover{color:var(--_et-qdt-fg)}.et-query-devtools-tab--active{color:var(--_et-qdt-fg);border-block-end-color:var(--_et-qdt-accent)}.et-query-devtools-tab-badge{display:inline-block;margin-inline-start:.5rem;padding-inline:.45rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-interaction) 12%,transparent);color:var(--_et-qdt-muted);font-size:1rem;font-variant-numeric:tabular-nums}.et-query-devtools-tab-badge--error{background:color-mix(in srgb,var(--_et-qdt-error) 25%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-tab-menu{position:relative;display:flex}.et-query-devtools-tab-more-caret{margin-inline-start:.4rem}.et-query-devtools-tab-more--open{color:var(--_et-qdt-fg);background:var(--_et-qdt-hover)}.et-query-devtools-tab-menu-list{position:absolute;inset-block-start:100%;inset-inline-start:0;z-index:2;display:flex;flex-direction:column;min-inline-size:14rem;padding:.4rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-bg);box-shadow:0 .4rem 2rem #00000059}.et-query-devtools-tab-menu-item{appearance:none;border:none;border-radius:.3rem;background:transparent;color:var(--_et-qdt-muted);padding:.6rem .8rem;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-tab-menu-item:hover{background:var(--_et-qdt-hover);color:var(--_et-qdt-fg)}.et-query-devtools-header-actions{display:flex;align-items:center;gap:.4rem;flex:0 0 auto}.et-query-devtools-inspect-btn{appearance:none;position:relative;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.4rem .8rem;font:inherit;transition:color .12s ease,background-color .12s ease,border-color .12s ease}.et-query-devtools-inspect-btn:hover{color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent)}.et-query-devtools-inspect-btn:focus-visible{outline:2px solid var(--_et-qdt-accent);outline-offset:2px}.et-query-devtools-inspect-icon{inline-size:1.4rem;block-size:1.4rem;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.25;stroke-linecap:round}.et-query-devtools-inspect-icon-dot{fill:currentColor;stroke:none}.et-query-devtools-inspect-btn--active,.et-query-devtools-inspect-btn--active:hover{color:#09090b;background:var(--_et-qdt-accent);border-color:var(--_et-qdt-accent)}.et-query-devtools-inspect-btn--active:after{content:\"\";position:absolute;inset:-.3rem;border:1px solid var(--_et-qdt-accent);border-radius:.6rem;pointer-events:none;animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:et-query-devtools-inspect-pulse 1.4s ease-in-out infinite}@keyframes et-query-devtools-inspect-pulse{0%,to{opacity:.2}50%{opacity:1}}@media(prefers-reduced-motion:reduce){.et-query-devtools-inspect-btn{transition:none}.et-query-devtools-inspect-btn--active:after,.et-query-devtools-inspect-btn--active .et-query-devtools-inspect-icon-ring{animation:none;opacity:1}}.et-query-devtools-close{appearance:none;border:none;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.6rem;font:inherit}.et-query-devtools-close-panel{appearance:none;display:inline-flex;align-items:center;gap:.6rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:var(--_et-qdt-hover);color:var(--_et-qdt-fg);cursor:pointer;padding:.4rem .6rem .4rem .8rem;font:inherit}.et-query-devtools-close-panel:hover{border-color:var(--_et-qdt-error);color:var(--_et-qdt-error)}.et-query-devtools-kbd{border-radius:.3rem;background:var(--_et-qdt-hover);box-shadow:inset 0 0 0 1px var(--_et-qdt-border);color:var(--_et-qdt-muted);padding:.15rem .4rem;font:inherit;font-size:1.1rem;line-height:1.2;white-space:nowrap}.et-query-devtools-kbd--inverse{background:#00000026;box-shadow:inset 0 0 0 1px #00000040;color:inherit}.et-query-devtools-inspect-box{position:fixed;z-index:2147483002;pointer-events:none;border:2px solid var(--_et-qdt-accent);background:color-mix(in srgb,var(--_et-qdt-accent) 15%,transparent);border-radius:.2rem}.et-query-devtools-inspect-tag{position:absolute;inset-block-start:100%;inset-inline-start:0;margin-block-start:.2rem;padding:.2rem .5rem;border-radius:.3rem;background:var(--_et-qdt-accent);color:#09090b;font-family:ui-monospace,monospace;font-size:1.1rem;font-weight:600;white-space:nowrap}.et-query-devtools-close:hover{color:var(--_et-qdt-fg)}.et-query-devtools-body{flex:1 1 auto;min-block-size:0;overflow:hidden}.et-query-devtools-detail{flex:1 1 auto;min-inline-size:0;overflow-y:auto;padding:1rem}.et-query-devtools-detail .et-query-devtools-meta,.et-query-devtools-drawer .et-query-devtools-meta{padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-detail .et-query-devtools-section-row,.et-query-devtools-drawer .et-query-devtools-section-row{padding-block-start:.8rem;border-block-start:1px solid var(--_et-qdt-border)}.et-query-devtools-filter-chip{display:inline-flex;align-items:center;gap:.6rem;padding:.3rem .35rem .3rem .7rem;border-radius:999px;background:color-mix(in srgb,var(--_et-qdt-accent) 16%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--_et-qdt-accent) 45%,transparent);color:var(--_et-qdt-accent);font-size:1.1rem;font-weight:600;letter-spacing:.02em}.et-query-devtools-filter-icon{font-size:1.3rem;line-height:1}.et-query-devtools-filter-count{border-radius:999px;background:var(--_et-qdt-accent);color:#09090b;min-inline-size:1.8rem;padding:0 .5rem;text-align:center}.et-query-devtools-filter-clear{appearance:none;display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-muted);cursor:pointer;padding:.3rem .6rem;font:inherit;font-size:1.15rem;line-height:1.4}.et-query-devtools-filter-clear:hover{border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent);color:var(--_et-qdt-fg)}.et-query-devtools-scroll{block-size:100%;overflow:auto;padding:1rem;display:flex;flex-direction:column;gap:1rem}.et-query-devtools-split{display:flex;block-size:100%;min-block-size:0}.et-query-devtools-split .et-query-devtools-scroll{flex:1 1 auto;min-inline-size:0}.et-query-devtools-pane{display:flex;flex-direction:column;flex:1 1 auto;block-size:100%;min-inline-size:0;min-block-size:0;overflow:hidden}.et-query-devtools-pane>.et-query-devtools-scroll{padding-block:0 1rem}.et-query-devtools-pane-resize{flex:0 0 .5rem;align-self:stretch;cursor:ew-resize;background:transparent;transition:background .12s ease}.et-query-devtools-pane-resize:hover,.et-query-devtools-pane-resize:active{background:var(--_et-qdt-accent)}.et-query-devtools-toolbar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.8rem;padding:.8rem;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;flex:1 1 100%;gap:.8rem}.et-query-devtools-field{display:inline-flex;align-items:center;gap:.6rem;color:var(--_et-qdt-muted)}.et-query-devtools-select{background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-count{color:var(--_et-qdt-subtle)}.et-query-devtools-row{display:flex;align-items:stretch;inline-size:100%;min-block-size:3.6rem;border-block-end:1px solid var(--_et-qdt-border);color:var(--_et-qdt-fg)}.et-query-devtools-row:hover{background:var(--_et-qdt-hover)}.et-query-devtools-method{font-weight:700;font-size:1.1rem;color:var(--_et-qdt-muted);white-space:nowrap}.et-query-devtools-route{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto;min-inline-size:0}.et-query-devtools-status{inline-size:.8rem;block-size:.8rem;border-radius:999px;flex:0 0 auto;background:var(--_et-qdt-subtle)}.et-query-devtools-status[data-status=success]{background:var(--_et-qdt-success)}.et-query-devtools-status[data-status=error]{background:var(--_et-qdt-error)}.et-query-devtools-status[data-status=loading],.et-query-devtools-status[data-status=running]{background:var(--_et-qdt-loading)}.et-query-devtools-btn{appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.3rem;background:transparent;color:var(--_et-qdt-fg);padding:.25rem .55rem;font-size:1.15rem;line-height:1.4;cursor:pointer}.et-query-devtools-btn:hover{background:var(--_et-qdt-hover)}.et-query-devtools-btn:disabled{color:var(--_et-qdt-subtle);cursor:default;background:transparent}.et-query-devtools-toolbar-btn{margin-inline-start:auto;flex:0 0 auto}.et-query-devtools-meta{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:0 0 1rem}.et-query-devtools-meta dt{color:var(--_et-qdt-muted)}.et-query-devtools-meta dd{margin:0;overflow-wrap:anywhere}.et-query-devtools-section{margin:1rem 0 .4rem;font-size:1.1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat{padding:.6rem .8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 3%,transparent)}.et-query-devtools-stat dt{font-size:1rem;text-transform:uppercase;letter-spacing:.05em;color:var(--_et-qdt-muted)}.et-query-devtools-stat dd{margin:0;font-size:1.5rem;font-variant-numeric:tabular-nums}.et-query-devtools-stat-sub{display:block;font-size:1rem;color:var(--_et-qdt-subtle)}.et-query-devtools-json{margin:0;padding:.8rem;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:color-mix(in srgb,var(--_et-qdt-interaction) 4%,transparent);overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;max-block-size:24rem;overflow-y:auto}.et-query-devtools-json--error{border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-mono{font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.et-query-devtools-url{display:inline-block;max-inline-size:32rem;margin-inline-start:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.et-query-devtools-chips,.et-query-devtools-chip-row{display:flex;flex-wrap:wrap;gap:.4rem;margin-block-end:.8rem}.et-query-devtools-chip{display:inline-flex;align-items:center;gap:.3rem;padding:.2rem .6rem;border-radius:999px;border:1px solid var(--_et-qdt-border);font-size:1.1rem;color:var(--_et-qdt-fg);background:color-mix(in srgb,var(--_et-qdt-interaction) 6%,transparent)}.et-query-devtools-chip--muted{color:var(--_et-qdt-muted)}.et-query-devtools-retry-glyph{font-size:.7em;line-height:1}.et-query-devtools-chip--loading{color:var(--_et-qdt-loading);border-color:color-mix(in srgb,var(--_et-qdt-loading) 50%,transparent)}.et-query-devtools-chip--error{color:var(--_et-qdt-error);border-color:color-mix(in srgb,var(--_et-qdt-error) 50%,transparent)}.et-query-devtools-chip--success{color:var(--_et-qdt-success);border-color:color-mix(in srgb,var(--_et-qdt-success) 50%,transparent)}button.et-query-devtools-chip--button{appearance:none;cursor:pointer;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}button.et-query-devtools-chip--button:hover{border-color:var(--_et-qdt-accent);color:var(--_et-qdt-accent)}.et-query-devtools-facet{appearance:none;cursor:pointer;color:var(--_et-qdt-muted);font:inherit;font-size:1.1rem;line-height:1.4}.et-query-devtools-facet:hover:not(:disabled){color:var(--_et-qdt-fg);border-color:color-mix(in srgb,var(--_et-qdt-accent) 60%,transparent)}.et-query-devtools-facet:disabled{color:var(--_et-qdt-subtle);cursor:default}.et-query-devtools-facet--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 14%,transparent)}.et-query-devtools-facet-count{font-variant-numeric:tabular-nums;color:inherit;opacity:.75}.et-query-devtools-card{border:1px solid var(--_et-qdt-border);border-radius:.6rem;padding:1rem}.et-query-devtools-card-head{display:flex;align-items:center;gap:.6rem;margin-block-end:.8rem}.et-query-devtools-inner-queries{display:flex;flex-direction:column;gap:.3rem}.et-query-devtools-inner-row{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:1px solid var(--_et-qdt-border);border-radius:.4rem;background:transparent;color:var(--_et-qdt-fg);padding:.4rem .6rem;cursor:pointer;font:inherit}.et-query-devtools-inner-row:hover:not([disabled]){background:var(--_et-qdt-hover)}.et-query-devtools-inner-row--active{background:var(--_et-qdt-active);border-color:var(--_et-qdt-accent)}.et-query-devtools-inner-row[disabled]{cursor:default;opacity:.6}.et-query-devtools-step-toggle{display:flex;align-items:center;gap:.6rem;inline-size:100%;text-align:start;appearance:none;border:none;background:transparent;color:var(--_et-qdt-fg);padding:.6rem;cursor:pointer;font:inherit}.et-query-devtools-step-toggle:hover{background:var(--_et-qdt-hover)}.et-query-devtools-step-index{flex:1 1 auto;min-inline-size:0}.et-query-devtools-step-caret{color:var(--_et-qdt-muted)}.et-query-devtools-table{inline-size:100%;border-collapse:collapse}.et-query-devtools-table th,.et-query-devtools-table td{text-align:start;padding:.5rem .6rem;border-block-end:1px solid var(--_et-qdt-border);vertical-align:top}.et-query-devtools-table td .et-query-devtools-chip{padding-block:0;line-height:1.4}.et-query-devtools-table th{color:var(--_et-qdt-muted);font-weight:600;position:sticky;inset-block-start:0;background:var(--_et-qdt-bg)}.et-query-devtools-table tr[data-status=error] td{color:var(--_et-qdt-error)}.et-query-devtools-empty{color:var(--_et-qdt-subtle);padding:1.2rem;text-align:center}.et-query-devtools-cell-actions{display:inline-flex;gap:.4rem;white-space:nowrap}.et-query-devtools-section-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-block-start:1rem}.et-query-devtools-search{flex:0 1 20rem;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-row-link{display:inline-flex;align-items:center;gap:.6rem;appearance:none;border:0;background:none;padding:0;color:inherit;font:inherit;text-align:start;cursor:pointer}.et-query-devtools-row-link:hover .et-query-devtools-url,.et-query-devtools-row-link:focus-visible .et-query-devtools-url{color:var(--_et-qdt-accent);text-decoration:underline}.et-query-devtools-hint{flex:1 1 24rem;color:var(--_et-qdt-muted);font-size:1.1rem;margin:0}.et-query-devtools-input{inline-size:100%;background:var(--_et-qdt-bg);color:var(--_et-qdt-fg);border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.4rem .6rem;font:inherit}.et-query-devtools-editor{border:1px solid var(--_et-qdt-border);border-radius:.4rem;padding:.8rem;margin-block-end:1rem}.et-query-devtools-editor-error{color:var(--_et-qdt-error);margin:.4rem 0 0}.et-query-devtools-btn--active{color:var(--_et-qdt-accent);border-color:color-mix(in srgb,var(--_et-qdt-accent) 55%,transparent);background:color-mix(in srgb,var(--_et-qdt-accent) 12%,transparent)}}\n"] }]
|
|
52709
53167
|
}], ctorParameters: () => [], propDecorators: { panelEl: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], tabMenuEl: [{ type: i0.ViewChild, args: ['tabMenu', { isSignal: true }] }] } });
|
|
52710
53168
|
|
|
52711
53169
|
const QUERY_DEVTOOLS_IMPORTS = [QueryDevtoolsComponent];
|
|
@@ -53041,6 +53499,8 @@ const SCHEDULER_ERROR_CODES = {
|
|
|
53041
53499
|
VIEW_OUTSIDE_SCHEDULER: 4501,
|
|
53042
53500
|
/** An edit-surface feature (e.g. an edit field or appointment action) was used outside an `<et-scheduler-edit-surface>`. */
|
|
53043
53501
|
EDIT_SURFACE_FEATURE_OUTSIDE_SURFACE: 4502,
|
|
53502
|
+
/** `[etSchedulerSwipeNavigation]` was placed on an element that is not an `[etScheduler]`. */
|
|
53503
|
+
SWIPE_NAVIGATION_OUTSIDE_SCHEDULER: 4503,
|
|
53044
53504
|
};
|
|
53045
53505
|
|
|
53046
53506
|
/** The built-in English labels. */
|
|
@@ -53250,10 +53710,15 @@ class SchedulerDirective {
|
|
|
53250
53710
|
const end = forward ? to : anchor;
|
|
53251
53711
|
this.draftRange.set({ start, end, phase: 'dragging' });
|
|
53252
53712
|
}
|
|
53253
|
-
/**
|
|
53713
|
+
/**
|
|
53714
|
+
* Releases the drag, leaving the range in place for the host to open its create surface over.
|
|
53715
|
+
* Only a range still being dragged commits: a pointer released on an already committed range -
|
|
53716
|
+
* a click on the drawn selection while its surface is open - must not re-commit it and reopen
|
|
53717
|
+
* that surface.
|
|
53718
|
+
*/
|
|
53254
53719
|
commitDraftRange() {
|
|
53255
53720
|
this.draftAnchor = null;
|
|
53256
|
-
this.draftRange.update((range) => (range ? { ...range, phase: 'committed' } :
|
|
53721
|
+
this.draftRange.update((range) => (range?.phase === 'dragging' ? { ...range, phase: 'committed' } : range));
|
|
53257
53722
|
}
|
|
53258
53723
|
/** Drops the drag-to-create range - a cancelled gesture, or a create surface that closed. */
|
|
53259
53724
|
clearDraftRange() {
|
|
@@ -54797,7 +55262,22 @@ const SCHEDULER_EDIT_SURFACE_OVERLAY = /* @__PURE__ */ defineOverlay({
|
|
|
54797
55262
|
const anchoredDialogStrategy = injectAnchoredDialogStrategy();
|
|
54798
55263
|
return [
|
|
54799
55264
|
{ strategy: fullscreenDialogStrategy.build() },
|
|
54800
|
-
{
|
|
55265
|
+
{
|
|
55266
|
+
breakpoint: 'md',
|
|
55267
|
+
strategy: anchoredDialogStrategy.build({
|
|
55268
|
+
maxWidth: '520px',
|
|
55269
|
+
// centered rather than the anchored dialog's edge-aligned default: the origin is as often
|
|
55270
|
+
// a dragged-out range as a single appointment, and a range wants its surface over its middle
|
|
55271
|
+
positionStrategy: buildAnchoredRuntimePositionStrategy({
|
|
55272
|
+
placement: 'bottom',
|
|
55273
|
+
fallbackPlacements: ['top', 'bottom-end', 'top-end'],
|
|
55274
|
+
offset: 10,
|
|
55275
|
+
arrowPadding: 16,
|
|
55276
|
+
shift: true,
|
|
55277
|
+
autoResize: true,
|
|
55278
|
+
}),
|
|
55279
|
+
}),
|
|
55280
|
+
},
|
|
54801
55281
|
];
|
|
54802
55282
|
},
|
|
54803
55283
|
panelClass: 'et-scheduler-edit-surface-panel',
|
|
@@ -54820,6 +55300,119 @@ const SCHEDULER_ADD_SURFACE_OVERLAY = /* @__PURE__ */ defineOverlay({
|
|
|
54820
55300
|
panelClass: 'et-scheduler-edit-surface-panel',
|
|
54821
55301
|
});
|
|
54822
55302
|
|
|
55303
|
+
/** Distance along the inline axis at which the gesture stops being a tap and becomes the scheduler's. */
|
|
55304
|
+
const COMMIT_THRESHOLD_PX = 16;
|
|
55305
|
+
/** How far a deliberate, unhurried swipe has to travel to step a period. */
|
|
55306
|
+
const MIN_SWIPE_DISTANCE_PX = 56;
|
|
55307
|
+
/** A flick steps a period on speed instead of distance, but still has to be a stroke rather than a twitch. */
|
|
55308
|
+
const MIN_FLICK_DISTANCE_PX = 32;
|
|
55309
|
+
const MIN_FLICK_VELOCITY = 300;
|
|
55310
|
+
/**
|
|
55311
|
+
* Swipe left for the next period, right for the previous one - the same steps the toolbar's
|
|
55312
|
+
* prev/next buttons take. Touch only: a horizontal mouse drag on a view draws a range instead.
|
|
55313
|
+
*
|
|
55314
|
+
* One of the default pieces `<et-scheduler>` bundles; add it to a bare `[etScheduler]` composition
|
|
55315
|
+
* to get the same gesture.
|
|
55316
|
+
*
|
|
55317
|
+
* @example
|
|
55318
|
+
* <et-scheduler [etSchedulerSwipeNavigation]="{ enabled: false }" … />
|
|
55319
|
+
*/
|
|
55320
|
+
class SchedulerSwipeNavigationDirective {
|
|
55321
|
+
constructor() {
|
|
55322
|
+
this.elementRef = inject(ElementRef);
|
|
55323
|
+
this.renderer = injectRenderer();
|
|
55324
|
+
this.destroyRef = inject(DestroyRef);
|
|
55325
|
+
this.scheduler = inject(SchedulerDirective, { optional: true });
|
|
55326
|
+
/** See {@link SchedulerSwipeNavigationConfig}. */
|
|
55327
|
+
this.config = input({}, { ...(ngDevMode ? { debugName: "config" } : /* istanbul ignore next */ {}), alias: 'etSchedulerSwipeNavigation',
|
|
55328
|
+
transform: (schedulerFeatureConfig) });
|
|
55329
|
+
this.isEnabled = computed(() => this.config().enabled ?? true, /* @ts-ignore */
|
|
55330
|
+
...(ngDevMode ? [{ debugName: "isEnabled" }] : /* istanbul ignore next */ []));
|
|
55331
|
+
this.tracker = null;
|
|
55332
|
+
this.isCommitted = false;
|
|
55333
|
+
if (!this.scheduler) {
|
|
55334
|
+
throw new RuntimeError(SCHEDULER_ERROR_CODES.SWIPE_NAVIGATION_OUTSIDE_SCHEDULER, '[etSchedulerSwipeNavigation] must be used on an <et-scheduler> or an [etScheduler] element.', { element: this.elementRef.nativeElement });
|
|
55335
|
+
}
|
|
55336
|
+
this.listen();
|
|
55337
|
+
}
|
|
55338
|
+
listen() {
|
|
55339
|
+
const element = this.elementRef.nativeElement;
|
|
55340
|
+
const unlisten = [
|
|
55341
|
+
this.renderer.listen(element, 'touchstart', (event) => this.startGesture(event)),
|
|
55342
|
+
this.renderer.listen(element, 'touchmove', (event) => this.trackGesture(event)),
|
|
55343
|
+
this.renderer.listen(element, 'touchend', (event) => this.endGesture(event)),
|
|
55344
|
+
this.renderer.listen(element, 'touchcancel', () => this.forgetGesture()),
|
|
55345
|
+
];
|
|
55346
|
+
this.destroyRef.onDestroy(() => unlisten.forEach((stop) => stop()));
|
|
55347
|
+
}
|
|
55348
|
+
startGesture(event) {
|
|
55349
|
+
if (!this.isEnabled() || this.tracker)
|
|
55350
|
+
return;
|
|
55351
|
+
// A second finger is a pinch or a zoom, neither of which is a period step.
|
|
55352
|
+
if (event.touches.length !== 1)
|
|
55353
|
+
return;
|
|
55354
|
+
this.tracker = createSwipeTracker(event);
|
|
55355
|
+
this.isCommitted = false;
|
|
55356
|
+
}
|
|
55357
|
+
trackGesture(event) {
|
|
55358
|
+
const tracker = this.tracker;
|
|
55359
|
+
if (!tracker)
|
|
55360
|
+
return;
|
|
55361
|
+
// A long press has armed the view's own drag-to-create, so this finger is drawing a range.
|
|
55362
|
+
if (this.scheduler?.draftRange())
|
|
55363
|
+
return this.forgetGesture();
|
|
55364
|
+
const { positiveMovementX, isScrolling } = tracker.update(event);
|
|
55365
|
+
if (isScrolling)
|
|
55366
|
+
return this.forgetGesture();
|
|
55367
|
+
if (!this.isCommitted) {
|
|
55368
|
+
if (positiveMovementX < COMMIT_THRESHOLD_PX)
|
|
55369
|
+
return;
|
|
55370
|
+
this.isCommitted = true;
|
|
55371
|
+
}
|
|
55372
|
+
// Preventing the move both stops the page panning under the gesture and stops the tap the
|
|
55373
|
+
// browser would otherwise synthesize on release - which, over an appointment, opens it.
|
|
55374
|
+
if (event.cancelable)
|
|
55375
|
+
event.preventDefault();
|
|
55376
|
+
}
|
|
55377
|
+
endGesture(event) {
|
|
55378
|
+
const tracker = this.tracker;
|
|
55379
|
+
const wasCommitted = this.isCommitted;
|
|
55380
|
+
this.forgetGesture();
|
|
55381
|
+
if (!tracker || !wasCommitted)
|
|
55382
|
+
return;
|
|
55383
|
+
if (event.cancelable)
|
|
55384
|
+
event.preventDefault();
|
|
55385
|
+
const { movementX, positiveMovementX, positivePixelPerSecondX } = tracker.end();
|
|
55386
|
+
const isSwipe = positiveMovementX >= MIN_SWIPE_DISTANCE_PX ||
|
|
55387
|
+
(positiveMovementX >= MIN_FLICK_DISTANCE_PX && positivePixelPerSecondX >= MIN_FLICK_VELOCITY);
|
|
55388
|
+
if (!isSwipe)
|
|
55389
|
+
return;
|
|
55390
|
+
// Dragging the period away to the inline start pulls the next one in, so the physical direction
|
|
55391
|
+
// flips with the writing direction.
|
|
55392
|
+
const isRtl = getComputedStyle(this.elementRef.nativeElement).direction === 'rtl';
|
|
55393
|
+
const isForwards = isRtl ? movementX > 0 : movementX < 0;
|
|
55394
|
+
if (isForwards) {
|
|
55395
|
+
this.scheduler?.next();
|
|
55396
|
+
}
|
|
55397
|
+
else {
|
|
55398
|
+
this.scheduler?.previous();
|
|
55399
|
+
}
|
|
55400
|
+
}
|
|
55401
|
+
forgetGesture() {
|
|
55402
|
+
this.tracker = null;
|
|
55403
|
+
this.isCommitted = false;
|
|
55404
|
+
}
|
|
55405
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerSwipeNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
55406
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: SchedulerSwipeNavigationDirective, isStandalone: true, selector: "[etSchedulerSwipeNavigation]", inputs: { config: { classPropertyName: "config", publicName: "etSchedulerSwipeNavigation", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["etSchedulerSwipeNavigation"], ngImport: i0 }); }
|
|
55407
|
+
}
|
|
55408
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerSwipeNavigationDirective, decorators: [{
|
|
55409
|
+
type: Directive,
|
|
55410
|
+
args: [{
|
|
55411
|
+
selector: '[etSchedulerSwipeNavigation]',
|
|
55412
|
+
exportAs: 'etSchedulerSwipeNavigation',
|
|
55413
|
+
}]
|
|
55414
|
+
}], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "etSchedulerSwipeNavigation", required: false }] }] } });
|
|
55415
|
+
|
|
54823
55416
|
/**
|
|
54824
55417
|
* How long a finger has to stay still before it draws instead of scrolls. Long enough that the
|
|
54825
55418
|
* browser has not started panning yet, short enough not to feel stuck.
|
|
@@ -54886,6 +55479,8 @@ class SchedulerMonthViewComponent {
|
|
|
54886
55479
|
...(ngDevMode ? [{ debugName: "weekRows" }] : /* istanbul ignore next */ []));
|
|
54887
55480
|
this.cells = viewChildren('cell', /* @ts-ignore */
|
|
54888
55481
|
...(ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []));
|
|
55482
|
+
this.draftAnchor = viewChild('draftAnchor', /* @ts-ignore */
|
|
55483
|
+
...(ngDevMode ? [{ debugName: "draftAnchor" }] : /* istanbul ignore next */ []));
|
|
54889
55484
|
injectStyleManager().mount(SchedulerAppointmentStylesComponent);
|
|
54890
55485
|
}
|
|
54891
55486
|
/** UI contributed by badge features (title, time range, …) - see `registerBadgeAdornment`. */
|
|
@@ -54929,19 +55524,46 @@ class SchedulerMonthViewComponent {
|
|
|
54929
55524
|
},
|
|
54930
55525
|
settle: () => {
|
|
54931
55526
|
const draft = scheduler.draftRange();
|
|
54932
|
-
|
|
55527
|
+
// a click made while a surface is open is dismissing it, not asking for another appointment
|
|
55528
|
+
if (!draft && !scheduler.selectedAppointmentId()) {
|
|
55529
|
+
scheduler.setDraftRange({ start: startOfDay(anchor), end: endOfDay(anchor), allDay: true });
|
|
55530
|
+
}
|
|
55531
|
+
else if (draft?.phase !== 'dragging') {
|
|
54933
55532
|
return;
|
|
54934
|
-
|
|
54935
|
-
|
|
54936
|
-
.weeks()
|
|
54937
|
-
.flat()
|
|
54938
|
-
.findIndex((cell) => isSameDay(cell.date, draft.start));
|
|
54939
|
-
scheduler.surfaceAnchor.set(this.cells()[index]?.nativeElement ?? null);
|
|
55533
|
+
}
|
|
55534
|
+
scheduler.surfaceAnchor.set(this.coverDraftRange(weeks));
|
|
54940
55535
|
scheduler.commitDraftRange();
|
|
54941
55536
|
},
|
|
54942
55537
|
cancel: () => scheduler.clearDraftRange(),
|
|
54943
55538
|
});
|
|
54944
55539
|
}
|
|
55540
|
+
coverDraftRange(weeks) {
|
|
55541
|
+
const anchor = this.draftAnchor()?.nativeElement;
|
|
55542
|
+
const rows = this.month.weeks();
|
|
55543
|
+
// only the first week row the range touches: a range that wraps spans every column, so covering
|
|
55544
|
+
// all of it would center the surface on the grid rather than on what was drawn
|
|
55545
|
+
const rowIndex = rows.findIndex((week) => week.some((cell) => this.isDrafted(cell.date)));
|
|
55546
|
+
const row = rows[rowIndex];
|
|
55547
|
+
if (!anchor || !row)
|
|
55548
|
+
return null;
|
|
55549
|
+
const offset = rows.slice(0, rowIndex).reduce((count, week) => count + week.length, 0);
|
|
55550
|
+
const drafted = row
|
|
55551
|
+
.map((cell, index) => (this.isDrafted(cell.date) ? this.cells()[offset + index]?.nativeElement : null))
|
|
55552
|
+
.filter((element) => !!element)
|
|
55553
|
+
.map((element) => element.getBoundingClientRect());
|
|
55554
|
+
if (!drafted.length)
|
|
55555
|
+
return null;
|
|
55556
|
+
const host = weeks.getBoundingClientRect();
|
|
55557
|
+
const left = Math.min(...drafted.map((rect) => rect.left));
|
|
55558
|
+
const top = Math.min(...drafted.map((rect) => rect.top));
|
|
55559
|
+
this.renderer.setStyle(anchor, {
|
|
55560
|
+
left: `${left - host.left}px`,
|
|
55561
|
+
top: `${top - host.top}px`,
|
|
55562
|
+
width: `${Math.max(...drafted.map((rect) => rect.right)) - left}px`,
|
|
55563
|
+
height: `${Math.max(...drafted.map((rect) => rect.bottom)) - top}px`,
|
|
55564
|
+
});
|
|
55565
|
+
return anchor;
|
|
55566
|
+
}
|
|
54945
55567
|
/**
|
|
54946
55568
|
* The day cell under a pointer position. Columns are a uniform seventh of the row, but week rows
|
|
54947
55569
|
* grow with their busiest cell, so the row is found by hit-testing the rendered rows rather than
|
|
@@ -54961,19 +55583,22 @@ class SchedulerMonthViewComponent {
|
|
|
54961
55583
|
return week[column]?.date ?? null;
|
|
54962
55584
|
}
|
|
54963
55585
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerMonthViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
54964
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SchedulerMonthViewComponent, isStandalone: true, selector: "et-scheduler-month-view", host: { classAttribute: "et-scheduler-month-view" }, viewQueries: [{ propertyName: "weekRows", predicate: ["weekRow"], descendants: true, isSignal: true }, { propertyName: "cells", predicate: ["cell"], descendants: true, isSignal: true }], hostDirectives: [{ directive: SchedulerMonthDirective }], ngImport: i0, template: "<div class=\"et-scheduler-month-view-weekdays\" role=\"row\">\n @for (weekday of weekdays(); track weekday.long) {\n <span [attr.aria-label]=\"weekday.long\" class=\"et-scheduler-month-view-weekday\" role=\"columnheader\">{{\n weekday.short\n }}</span>\n }\n</div>\n\n<div #weeks (pointerdown)=\"startDraftRange($event, weeks)\" class=\"et-scheduler-month-view-weeks\" role=\"rowgroup\">\n @for (week of month.weeks(); track $index) {\n <div #weekRow class=\"et-scheduler-month-view-week\" role=\"row\">\n @for (cell of week; track cell.date.getTime()) {\n <div\n #cell\n [attr.data-outside-month]=\"cell.outsideMonth ? '' : null\"\n [attr.data-today]=\"cell.today ? '' : null\"\n [attr.data-draft]=\"isDrafted(cell.date) ? '' : null\"\n class=\"et-scheduler-month-view-cell\"\n role=\"gridcell\"\n >\n <span class=\"et-scheduler-month-view-cell-date\">{{ cell.date.getDate() }}</span>\n\n <!-- pointerdown is stopped on everything interactive below so a press that starts on an\n appointment or the overflow trigger does not also draw a range across the grid -->\n <div class=\"et-scheduler-month-view-cell-appointments\">\n @for (node of cell.visible; track node.appointment.id) {\n <button\n #appointmentButton\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [attr.title]=\"node.appointment.title\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment, appointmentButton)\"\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-appointment\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n\n @if (cell.overflow.length > 0) {\n <div class=\"et-scheduler-month-view-overflow\" etMenu>\n <button\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-month-view-overflow-trigger\"\n etMenuTrigger\n type=\"button\"\n >\n {{ labels().moreAppointments(cell.overflow.length) }}\n </button>\n\n <ng-template etMenuSurface>\n <et-menu>\n @for (node of cell.overflow; track node.appointment.id) {\n <button\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment)\"\n et-menu-item\n type=\"button\"\n >\n {{ node.appointment.title }}\n </button>\n }\n </et-menu>\n </ng-template>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["@layer components{@property --et-scheduler-month-view-cell-min-size{syntax: \"<length>\"; inherits: true; initial-value: 96px;}.et-scheduler-month-view{display:flex;flex-direction:column}.et-scheduler-month-view-weekdays,.et-scheduler-month-view-week{display:grid;grid-template-columns:repeat(7,1fr)}.et-scheduler-month-view-weekday{padding-block:6px;text-align:center;font-size:12px;font-weight:600;color:var(--et-surface-color-muted-solid)}.et-scheduler-month-view-weeks{display:flex;flex-direction:column;flex:1;border-inline-start:1px solid var(--et-surface-border-solid);border-block-start:1px solid var(--et-surface-border-solid)}.et-scheduler-month-view-week{flex:1;min-block-size:var(--et-scheduler-month-view-cell-min-size)}.et-scheduler-month-view-cell{display:flex;flex-direction:column;gap:2px;min-inline-size:0;padding:4px;overflow:hidden;border-inline-end:1px solid var(--et-surface-border-solid);border-block-end:1px solid var(--et-surface-border-solid);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-month-view-cell:where([data-draft]){background:color-mix(in srgb,var(--et-theme-color-primary-solid) 12%,transparent);box-shadow:inset 0 0 0 1px var(--et-theme-color-primary-solid)}.et-scheduler-month-view-cell:where([data-outside-month]){color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell:where([data-outside-month]) .et-scheduler-month-view-cell-date{color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell-date{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;inline-size:22px;block-size:22px;border-radius:999px;font-size:12px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-solid)}.et-scheduler-month-view-cell:where([data-today]) .et-scheduler-month-view-cell-date{background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary);font-weight:600}.et-scheduler-month-view-cell-appointments{display:flex;flex-direction:column;min-block-size:0;min-inline-size:0;gap:2px;overflow:hidden}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment{gap:4px;min-inline-size:0;padding:2px 4px}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-dot,.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-location{display:none}.et-scheduler-month-view-overflow-trigger{padding:2px 6px;border:none;background:transparent;color:var(--et-surface-color-muted-solid);font:inherit;font-size:12px;font-weight:500;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}@media(hover:hover){.et-scheduler-month-view-overflow-trigger:hover{color:var(--et-surface-color-solid)}}.et-scheduler-month-view-overflow-trigger:focus-visible{border-radius:4px;outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}}\n"], dependencies: [{ kind: "directive", type: MenuDirective, selector: "[etMenu]", inputs: ["placement", "fallbackPlacements", "offset", "viewportPadding", "arrow", "arrowPadding", "autoFocus", "hoverOpen", "loop", "hoverOpenDelay", "hoverCloseDelay", "disabled", "open"], outputs: ["openChange"], exportAs: ["etMenu"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[etMenuTrigger]", exportAs: ["etMenuTrigger"] }, { kind: "directive", type: MenuSurfaceDirective, selector: "ng-template[etMenuSurface]", exportAs: ["etMenuSurface"] }, { kind: "component", type: MenuComponent, selector: "et-menu" }, { kind: "component", type: MenuItemComponent, selector: "button[et-menu-item], a[et-menu-item]", inputs: ["variant"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
55586
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SchedulerMonthViewComponent, isStandalone: true, selector: "et-scheduler-month-view", host: { classAttribute: "et-scheduler-month-view" }, viewQueries: [{ propertyName: "weekRows", predicate: ["weekRow"], descendants: true, isSignal: true }, { propertyName: "cells", predicate: ["cell"], descendants: true, isSignal: true }, { propertyName: "draftAnchor", first: true, predicate: ["draftAnchor"], descendants: true, isSignal: true }], hostDirectives: [{ directive: SchedulerMonthDirective }], ngImport: i0, template: "<div class=\"et-scheduler-month-view-weekdays\" role=\"row\">\n @for (weekday of weekdays(); track weekday.long) {\n <span [attr.aria-label]=\"weekday.long\" class=\"et-scheduler-month-view-weekday\" role=\"columnheader\">{{\n weekday.short\n }}</span>\n }\n</div>\n\n<div #weeks (pointerdown)=\"startDraftRange($event, weeks)\" class=\"et-scheduler-month-view-weeks\" role=\"rowgroup\">\n <!-- stretched over the drawn range on release, so the create surface can anchor to the whole of it -->\n <div #draftAnchor class=\"et-scheduler-month-view-draft-anchor\" aria-hidden=\"true\"></div>\n\n @for (week of month.weeks(); track $index) {\n <div #weekRow class=\"et-scheduler-month-view-week\" role=\"row\">\n @for (cell of week; track cell.date.getTime()) {\n <div\n #cell\n [attr.data-outside-month]=\"cell.outsideMonth ? '' : null\"\n [attr.data-today]=\"cell.today ? '' : null\"\n [attr.data-draft]=\"isDrafted(cell.date) ? '' : null\"\n class=\"et-scheduler-month-view-cell\"\n role=\"gridcell\"\n >\n <span class=\"et-scheduler-month-view-cell-date\">{{ cell.date.getDate() }}</span>\n\n <!-- pointerdown is stopped on everything interactive below so a press that starts on an\n appointment or the overflow trigger does not also draw a range across the grid -->\n <div class=\"et-scheduler-month-view-cell-appointments\">\n @for (node of cell.visible; track node.appointment.id) {\n <button\n #appointmentButton\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [attr.title]=\"node.appointment.title\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment, appointmentButton)\"\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-appointment\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n\n @if (cell.overflow.length > 0) {\n <div class=\"et-scheduler-month-view-overflow\" etMenu>\n <button\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-month-view-overflow-trigger\"\n etMenuTrigger\n type=\"button\"\n >\n {{ labels().moreAppointments(cell.overflow.length) }}\n </button>\n\n <ng-template etMenuSurface>\n <et-menu>\n @for (node of cell.overflow; track node.appointment.id) {\n <button\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment)\"\n et-menu-item\n type=\"button\"\n >\n {{ node.appointment.title }}\n </button>\n }\n </et-menu>\n </ng-template>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["@layer components{@property --et-scheduler-month-view-cell-min-size{syntax: \"<length>\"; inherits: true; initial-value: 96px;}.et-scheduler-month-view{display:flex;flex-direction:column}.et-scheduler-month-view-weekdays,.et-scheduler-month-view-week{display:grid;grid-template-columns:repeat(7,1fr)}.et-scheduler-month-view-weekday{padding-block:6px;text-align:center;font-size:12px;font-weight:600;color:var(--et-surface-color-muted-solid)}.et-scheduler-month-view-weeks{position:relative;display:flex;flex-direction:column;flex:1;border-inline-start:1px solid var(--et-surface-border-solid);border-block-start:1px solid var(--et-surface-border-solid)}.et-scheduler-month-view-draft-anchor{position:absolute;pointer-events:none}.et-scheduler-month-view-week{flex:1;min-block-size:var(--et-scheduler-month-view-cell-min-size)}.et-scheduler-month-view-cell{display:flex;flex-direction:column;gap:2px;min-inline-size:0;padding:4px;overflow:hidden;border-inline-end:1px solid var(--et-surface-border-solid);border-block-end:1px solid var(--et-surface-border-solid);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-month-view-cell:where([data-draft]){background:color-mix(in srgb,var(--et-theme-color-primary-solid) 12%,transparent);box-shadow:inset 0 0 0 1px var(--et-theme-color-primary-solid)}.et-scheduler-month-view-cell:where([data-outside-month]){color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell:where([data-outside-month]) .et-scheduler-month-view-cell-date{color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell-date{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;inline-size:22px;block-size:22px;border-radius:999px;font-size:12px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-solid)}.et-scheduler-month-view-cell:where([data-today]) .et-scheduler-month-view-cell-date{background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary);font-weight:600}.et-scheduler-month-view-cell-appointments{display:flex;flex-direction:column;min-block-size:0;min-inline-size:0;gap:2px;overflow:hidden}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment{gap:4px;min-inline-size:0;padding:2px 4px}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-dot,.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-location{display:none}.et-scheduler-month-view-overflow-trigger{padding:2px 6px;border:none;background:transparent;color:var(--et-surface-color-muted-solid);font:inherit;font-size:12px;font-weight:500;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}@media(hover:hover){.et-scheduler-month-view-overflow-trigger:hover{color:var(--et-surface-color-solid)}}.et-scheduler-month-view-overflow-trigger:focus-visible{border-radius:4px;outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}}\n"], dependencies: [{ kind: "directive", type: MenuDirective, selector: "[etMenu]", inputs: ["placement", "fallbackPlacements", "offset", "viewportPadding", "arrow", "arrowPadding", "autoFocus", "hoverOpen", "loop", "hoverOpenDelay", "hoverCloseDelay", "disabled", "open"], outputs: ["openChange"], exportAs: ["etMenu"] }, { kind: "directive", type: MenuTriggerDirective, selector: "[etMenuTrigger]", exportAs: ["etMenuTrigger"] }, { kind: "directive", type: MenuSurfaceDirective, selector: "ng-template[etMenuSurface]", exportAs: ["etMenuSurface"] }, { kind: "component", type: MenuComponent, selector: "et-menu" }, { kind: "component", type: MenuItemComponent, selector: "button[et-menu-item], a[et-menu-item]", inputs: ["variant"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
54965
55587
|
}
|
|
54966
55588
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerMonthViewComponent, decorators: [{
|
|
54967
55589
|
type: Component,
|
|
54968
55590
|
args: [{ selector: 'et-scheduler-month-view', encapsulation: ViewEncapsulation.None, imports: [...MENU_IMPORTS, ProvideColorDirective, NgComponentOutlet], hostDirectives: [SchedulerMonthDirective], host: {
|
|
54969
55591
|
class: 'et-scheduler-month-view',
|
|
54970
|
-
}, template: "<div class=\"et-scheduler-month-view-weekdays\" role=\"row\">\n @for (weekday of weekdays(); track weekday.long) {\n <span [attr.aria-label]=\"weekday.long\" class=\"et-scheduler-month-view-weekday\" role=\"columnheader\">{{\n weekday.short\n }}</span>\n }\n</div>\n\n<div #weeks (pointerdown)=\"startDraftRange($event, weeks)\" class=\"et-scheduler-month-view-weeks\" role=\"rowgroup\">\n @for (week of month.weeks(); track $index) {\n <div #weekRow class=\"et-scheduler-month-view-week\" role=\"row\">\n @for (cell of week; track cell.date.getTime()) {\n <div\n #cell\n [attr.data-outside-month]=\"cell.outsideMonth ? '' : null\"\n [attr.data-today]=\"cell.today ? '' : null\"\n [attr.data-draft]=\"isDrafted(cell.date) ? '' : null\"\n class=\"et-scheduler-month-view-cell\"\n role=\"gridcell\"\n >\n <span class=\"et-scheduler-month-view-cell-date\">{{ cell.date.getDate() }}</span>\n\n <!-- pointerdown is stopped on everything interactive below so a press that starts on an\n appointment or the overflow trigger does not also draw a range across the grid -->\n <div class=\"et-scheduler-month-view-cell-appointments\">\n @for (node of cell.visible; track node.appointment.id) {\n <button\n #appointmentButton\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [attr.title]=\"node.appointment.title\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment, appointmentButton)\"\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-appointment\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n\n @if (cell.overflow.length > 0) {\n <div class=\"et-scheduler-month-view-overflow\" etMenu>\n <button\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-month-view-overflow-trigger\"\n etMenuTrigger\n type=\"button\"\n >\n {{ labels().moreAppointments(cell.overflow.length) }}\n </button>\n\n <ng-template etMenuSurface>\n <et-menu>\n @for (node of cell.overflow; track node.appointment.id) {\n <button\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment)\"\n et-menu-item\n type=\"button\"\n >\n {{ node.appointment.title }}\n </button>\n }\n </et-menu>\n </ng-template>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["@layer components{@property --et-scheduler-month-view-cell-min-size{syntax: \"<length>\"; inherits: true; initial-value: 96px;}.et-scheduler-month-view{display:flex;flex-direction:column}.et-scheduler-month-view-weekdays,.et-scheduler-month-view-week{display:grid;grid-template-columns:repeat(7,1fr)}.et-scheduler-month-view-weekday{padding-block:6px;text-align:center;font-size:12px;font-weight:600;color:var(--et-surface-color-muted-solid)}.et-scheduler-month-view-weeks{display:flex;flex-direction:column;flex:1;border-inline-start:1px solid var(--et-surface-border-solid);border-block-start:1px solid var(--et-surface-border-solid)}.et-scheduler-month-view-week{flex:1;min-block-size:var(--et-scheduler-month-view-cell-min-size)}.et-scheduler-month-view-cell{display:flex;flex-direction:column;gap:2px;min-inline-size:0;padding:4px;overflow:hidden;border-inline-end:1px solid var(--et-surface-border-solid);border-block-end:1px solid var(--et-surface-border-solid);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-month-view-cell:where([data-draft]){background:color-mix(in srgb,var(--et-theme-color-primary-solid) 12%,transparent);box-shadow:inset 0 0 0 1px var(--et-theme-color-primary-solid)}.et-scheduler-month-view-cell:where([data-outside-month]){color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell:where([data-outside-month]) .et-scheduler-month-view-cell-date{color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell-date{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;inline-size:22px;block-size:22px;border-radius:999px;font-size:12px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-solid)}.et-scheduler-month-view-cell:where([data-today]) .et-scheduler-month-view-cell-date{background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary);font-weight:600}.et-scheduler-month-view-cell-appointments{display:flex;flex-direction:column;min-block-size:0;min-inline-size:0;gap:2px;overflow:hidden}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment{gap:4px;min-inline-size:0;padding:2px 4px}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-dot,.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-location{display:none}.et-scheduler-month-view-overflow-trigger{padding:2px 6px;border:none;background:transparent;color:var(--et-surface-color-muted-solid);font:inherit;font-size:12px;font-weight:500;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}@media(hover:hover){.et-scheduler-month-view-overflow-trigger:hover{color:var(--et-surface-color-solid)}}.et-scheduler-month-view-overflow-trigger:focus-visible{border-radius:4px;outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}}\n"] }]
|
|
54971
|
-
}], ctorParameters: () => [], propDecorators: { weekRows: [{ type: i0.ViewChildren, args: ['weekRow', { isSignal: true }] }], cells: [{ type: i0.ViewChildren, args: ['cell', { isSignal: true }] }] } });
|
|
55592
|
+
}, template: "<div class=\"et-scheduler-month-view-weekdays\" role=\"row\">\n @for (weekday of weekdays(); track weekday.long) {\n <span [attr.aria-label]=\"weekday.long\" class=\"et-scheduler-month-view-weekday\" role=\"columnheader\">{{\n weekday.short\n }}</span>\n }\n</div>\n\n<div #weeks (pointerdown)=\"startDraftRange($event, weeks)\" class=\"et-scheduler-month-view-weeks\" role=\"rowgroup\">\n <!-- stretched over the drawn range on release, so the create surface can anchor to the whole of it -->\n <div #draftAnchor class=\"et-scheduler-month-view-draft-anchor\" aria-hidden=\"true\"></div>\n\n @for (week of month.weeks(); track $index) {\n <div #weekRow class=\"et-scheduler-month-view-week\" role=\"row\">\n @for (cell of week; track cell.date.getTime()) {\n <div\n #cell\n [attr.data-outside-month]=\"cell.outsideMonth ? '' : null\"\n [attr.data-today]=\"cell.today ? '' : null\"\n [attr.data-draft]=\"isDrafted(cell.date) ? '' : null\"\n class=\"et-scheduler-month-view-cell\"\n role=\"gridcell\"\n >\n <span class=\"et-scheduler-month-view-cell-date\">{{ cell.date.getDate() }}</span>\n\n <!-- pointerdown is stopped on everything interactive below so a press that starts on an\n appointment or the overflow trigger does not also draw a range across the grid -->\n <div class=\"et-scheduler-month-view-cell-appointments\">\n @for (node of cell.visible; track node.appointment.id) {\n <button\n #appointmentButton\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [attr.title]=\"node.appointment.title\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment, appointmentButton)\"\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-appointment\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n\n @if (cell.overflow.length > 0) {\n <div class=\"et-scheduler-month-view-overflow\" etMenu>\n <button\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-month-view-overflow-trigger\"\n etMenuTrigger\n type=\"button\"\n >\n {{ labels().moreAppointments(cell.overflow.length) }}\n </button>\n\n <ng-template etMenuSurface>\n <et-menu>\n @for (node of cell.overflow; track node.appointment.id) {\n <button\n [attr.data-selected]=\"isSelected(node.appointment) ? '' : null\"\n [etProvideColor]=\"node.appointment.colorToken ?? null\"\n (click)=\"select(node.appointment)\"\n et-menu-item\n type=\"button\"\n >\n {{ node.appointment.title }}\n </button>\n }\n </et-menu>\n </ng-template>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: ["@layer components{@property --et-scheduler-month-view-cell-min-size{syntax: \"<length>\"; inherits: true; initial-value: 96px;}.et-scheduler-month-view{display:flex;flex-direction:column}.et-scheduler-month-view-weekdays,.et-scheduler-month-view-week{display:grid;grid-template-columns:repeat(7,1fr)}.et-scheduler-month-view-weekday{padding-block:6px;text-align:center;font-size:12px;font-weight:600;color:var(--et-surface-color-muted-solid)}.et-scheduler-month-view-weeks{position:relative;display:flex;flex-direction:column;flex:1;border-inline-start:1px solid var(--et-surface-border-solid);border-block-start:1px solid var(--et-surface-border-solid)}.et-scheduler-month-view-draft-anchor{position:absolute;pointer-events:none}.et-scheduler-month-view-week{flex:1;min-block-size:var(--et-scheduler-month-view-cell-min-size)}.et-scheduler-month-view-cell{display:flex;flex-direction:column;gap:2px;min-inline-size:0;padding:4px;overflow:hidden;border-inline-end:1px solid var(--et-surface-border-solid);border-block-end:1px solid var(--et-surface-border-solid);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-month-view-cell:where([data-draft]){background:color-mix(in srgb,var(--et-theme-color-primary-solid) 12%,transparent);box-shadow:inset 0 0 0 1px var(--et-theme-color-primary-solid)}.et-scheduler-month-view-cell:where([data-outside-month]){color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell:where([data-outside-month]) .et-scheduler-month-view-cell-date{color:var(--et-surface-color-subtle-solid)}.et-scheduler-month-view-cell-date{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;inline-size:22px;block-size:22px;border-radius:999px;font-size:12px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-solid)}.et-scheduler-month-view-cell:where([data-today]) .et-scheduler-month-view-cell-date{background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary);font-weight:600}.et-scheduler-month-view-cell-appointments{display:flex;flex-direction:column;min-block-size:0;min-inline-size:0;gap:2px;overflow:hidden}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment{gap:4px;min-inline-size:0;padding:2px 4px}.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-dot,.et-scheduler-month-view-cell-appointments .et-scheduler-appointment .et-scheduler-appointment-location{display:none}.et-scheduler-month-view-overflow-trigger{padding:2px 6px;border:none;background:transparent;color:var(--et-surface-color-muted-solid);font:inherit;font-size:12px;font-weight:500;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}@media(hover:hover){.et-scheduler-month-view-overflow-trigger:hover{color:var(--et-surface-color-solid)}}.et-scheduler-month-view-overflow-trigger:focus-visible{border-radius:4px;outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}}\n"] }]
|
|
55593
|
+
}], ctorParameters: () => [], propDecorators: { weekRows: [{ type: i0.ViewChildren, args: ['weekRow', { isSignal: true }] }], cells: [{ type: i0.ViewChildren, args: ['cell', { isSignal: true }] }], draftAnchor: [{ type: i0.ViewChild, args: ['draftAnchor', { isSignal: true }] }] } });
|
|
54972
55594
|
|
|
54973
55595
|
const HOURS = /* @__PURE__ */ Array.from({ length: 24 }, (_, hour) => hour);
|
|
54974
55596
|
const MINUTES_PER_DAY = 24 * 60;
|
|
54975
55597
|
const DRAFT_SLOT_MINUTES = 15;
|
|
54976
55598
|
const DRAFT_MINIMUM_DURATION = DRAFT_SLOT_MINUTES * 60 * 1000;
|
|
55599
|
+
/** What a press that never drags creates - a click, or a long press released where it landed. */
|
|
55600
|
+
const DEFAULT_DRAFT_MINUTES = 60;
|
|
55601
|
+
const DEFAULT_DRAFT_DURATION = DEFAULT_DRAFT_MINUTES * 60 * 1000;
|
|
54977
55602
|
/**
|
|
54978
55603
|
* The default time grid: an hour axis, an all-day strip, and appointments packed into
|
|
54979
55604
|
* overlap-free columns. Backs both the week and day views - the day view is this same component
|
|
@@ -54985,6 +55610,7 @@ class SchedulerTimeGridViewComponent {
|
|
|
54985
55610
|
this.grid = inject(SchedulerTimeGridDirective);
|
|
54986
55611
|
this.featureHost = inject(SCHEDULER_FEATURE_HOST, { optional: true });
|
|
54987
55612
|
this.destroyRef = inject(DestroyRef);
|
|
55613
|
+
this.hostInjector = inject(Injector);
|
|
54988
55614
|
this.renderer = injectRenderer();
|
|
54989
55615
|
this.timeGridBody = viewChild('timeGridBody', /* @ts-ignore */
|
|
54990
55616
|
...(ngDevMode ? [{ debugName: "timeGridBody" }] : /* istanbul ignore next */ []));
|
|
@@ -55030,8 +55656,9 @@ class SchedulerTimeGridViewComponent {
|
|
|
55030
55656
|
}
|
|
55031
55657
|
/**
|
|
55032
55658
|
* Drags a new appointment's time range out of an empty part of a day column. With a mouse the
|
|
55033
|
-
* gesture's own commit threshold separates a drag from a click, so
|
|
55034
|
-
*
|
|
55659
|
+
* gesture's own commit threshold separates a drag from a click, so a click on empty grid drafts
|
|
55660
|
+
* an hour instead of a drawn range; a finger has to long-press first - see
|
|
55661
|
+
* `startSchedulerDraftGesture`.
|
|
55035
55662
|
*/
|
|
55036
55663
|
startDraftRange(event, column) {
|
|
55037
55664
|
const scheduler = this.scheduler;
|
|
@@ -55044,12 +55671,17 @@ class SchedulerTimeGridViewComponent {
|
|
|
55044
55671
|
destroyRef: this.destroyRef,
|
|
55045
55672
|
draw: (_, clientY) => {
|
|
55046
55673
|
const at = this.draftTimeAt(column, clientY);
|
|
55674
|
+
// the first unit is the full default: a long press released without moving has to land on
|
|
55675
|
+
// the same hour a click does, and the first drag move recomputes from the anchor anyway
|
|
55047
55676
|
return scheduler.draftRange()
|
|
55048
55677
|
? scheduler.extendDraftRange(at, DRAFT_MINIMUM_DURATION)
|
|
55049
|
-
: scheduler.beginDraftRange(at,
|
|
55678
|
+
: scheduler.beginDraftRange(at, DEFAULT_DRAFT_DURATION);
|
|
55050
55679
|
},
|
|
55051
55680
|
settle: () => {
|
|
55052
|
-
|
|
55681
|
+
const draft = scheduler.draftRange();
|
|
55682
|
+
if (!draft)
|
|
55683
|
+
return this.draftHourAt(column, event.clientY);
|
|
55684
|
+
if (draft.phase !== 'dragging')
|
|
55053
55685
|
return;
|
|
55054
55686
|
// the preview is what the create surface anchors to, so hand it over before committing
|
|
55055
55687
|
scheduler.surfaceAnchor.set(this.draftBlock()?.nativeElement ?? null);
|
|
@@ -55058,6 +55690,19 @@ class SchedulerTimeGridViewComponent {
|
|
|
55058
55690
|
cancel: () => scheduler.clearDraftRange(),
|
|
55059
55691
|
});
|
|
55060
55692
|
}
|
|
55693
|
+
/** A click on empty grid: an hour starting where it landed, snapped like a drawn range is. */
|
|
55694
|
+
draftHourAt(column, clientY) {
|
|
55695
|
+
const scheduler = this.scheduler;
|
|
55696
|
+
// a click made while a surface is open is dismissing it, not asking for another appointment
|
|
55697
|
+
if (!scheduler || scheduler.selectedAppointmentId())
|
|
55698
|
+
return;
|
|
55699
|
+
scheduler.beginDraftRange(this.draftTimeAt(column, clientY), DEFAULT_DRAFT_DURATION);
|
|
55700
|
+
// unlike a drag, nothing has drawn the preview yet - it is only there to anchor to a pass later
|
|
55701
|
+
afterNextRender(() => {
|
|
55702
|
+
scheduler.surfaceAnchor.set(this.draftBlock()?.nativeElement ?? null);
|
|
55703
|
+
scheduler.commitDraftRange();
|
|
55704
|
+
}, { injector: this.hostInjector });
|
|
55705
|
+
}
|
|
55061
55706
|
/** The time a pointer at `clientY` sits at in `column`, snapped to the draft's slot size. */
|
|
55062
55707
|
draftTimeAt(column, clientY) {
|
|
55063
55708
|
const { top, height } = column.element.getBoundingClientRect();
|
|
@@ -55075,6 +55720,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
55075
55720
|
}, template: "<div class=\"et-scheduler-time-grid-row et-scheduler-time-grid-header\" role=\"row\">\n <div class=\"et-scheduler-time-grid-gutter\"></div>\n\n <div class=\"et-scheduler-time-grid-days\">\n @for (day of grid.days(); track day.date.getTime()) {\n <div [attr.data-today]=\"day.today ? '' : null\" class=\"et-scheduler-time-grid-header-day\" role=\"columnheader\">\n <span class=\"et-scheduler-time-grid-header-weekday\">{{ weekdayLabel(day.date) }}</span>\n <span class=\"et-scheduler-time-grid-header-date\">{{ day.date.getDate() }}</span>\n </div>\n }\n </div>\n</div>\n\n@if (grid.allDayRowCount() > 0) {\n <div class=\"et-scheduler-time-grid-row et-scheduler-time-grid-all-day\" role=\"row\">\n <div class=\"et-scheduler-time-grid-gutter\"></div>\n\n <div\n [style.--_et-scheduler-time-grid-all-day-row-count]=\"grid.allDayRowCount()\"\n class=\"et-scheduler-time-grid-all-day-lane\"\n role=\"gridcell\"\n >\n @for (entry of grid.allDay(); track entry.node.appointment.id) {\n <button\n #appointmentButton\n [style.--_et-scheduler-time-grid-all-day-offset]=\"entry.inlineOffset\"\n [style.--_et-scheduler-time-grid-all-day-size]=\"entry.inlineSize\"\n [style.--_et-scheduler-time-grid-all-day-row]=\"entry.row\"\n [attr.data-selected]=\"isSelected(entry.node.appointment) ? '' : null\"\n [attr.title]=\"entry.node.appointment.title\"\n [etProvideColor]=\"entry.node.appointment.colorToken ?? null\"\n (click)=\"select(entry.node.appointment, appointmentButton)\"\n class=\"et-scheduler-appointment et-scheduler-time-grid-all-day-entry\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node: entry.node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n </div>\n </div>\n}\n\n<div #timeGridBody class=\"et-scheduler-time-grid-row et-scheduler-time-grid-body\">\n <div class=\"et-scheduler-time-grid-gutter\" role=\"presentation\">\n @for (hour of hours(); track hour.hour) {\n <div #hourRow class=\"et-scheduler-time-grid-hour-row\">\n <span class=\"et-scheduler-time-grid-hour-label\">{{ hour.label }}</span>\n </div>\n }\n </div>\n\n <div class=\"et-scheduler-time-grid-days\">\n @for (day of grid.days(); track day.date.getTime(); let dayIndex = $index) {\n <div\n #dayColumn\n [attr.data-today]=\"day.today ? '' : null\"\n (pointerdown)=\"startDraftRange($event, { element: dayColumn, day: day.date })\"\n class=\"et-scheduler-time-grid-day\"\n role=\"gridcell\"\n >\n @for (hour of hours(); track hour.hour) {\n <div class=\"et-scheduler-time-grid-hour-row\" role=\"presentation\"></div>\n }\n\n @if (grid.draftBlock(); as draft) {\n @if (draft.dayIndex === dayIndex) {\n <div\n #draftBlock\n [style.--_et-scheduler-time-grid-block-offset]=\"draft.offset\"\n [style.--_et-scheduler-time-grid-block-span]=\"draft.span\"\n [attr.data-committed]=\"draft.phase === 'committed' ? '' : null\"\n class=\"et-scheduler-time-grid-draft\"\n role=\"presentation\"\n ></div>\n }\n }\n\n <!-- pointerdown is stopped below so a press that starts on an appointment does not reach the\n column's drag-to-create and lay a new range over the one already there -->\n @for (block of day.blocks; track block.node.appointment.id) {\n <button\n #appointmentButton\n [style.--_et-scheduler-time-grid-block-offset]=\"block.offset\"\n [style.--_et-scheduler-time-grid-block-span]=\"block.span\"\n [style.--_et-scheduler-time-grid-block-inline-offset]=\"block.inlineOffset\"\n [style.--_et-scheduler-time-grid-block-inline-size]=\"block.inlineSize\"\n [style.--_et-scheduler-time-grid-block-depth]=\"block.node.depth\"\n [attr.data-selected]=\"isSelected(block.node.appointment) ? '' : null\"\n [attr.data-nested]=\"block.node.depth > 0 ? '' : null\"\n [attr.title]=\"block.node.appointment.title\"\n [etProvideColor]=\"block.node.appointment.colorToken ?? null\"\n (click)=\"select(block.node.appointment, appointmentButton)\"\n (pointerdown)=\"$event.stopPropagation()\"\n class=\"et-scheduler-time-grid-block\"\n type=\"button\"\n >\n @for (adornment of badgeAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { node: block.node }; injector: adornment.injector\"\n />\n }\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: ["@layer components{@property --et-scheduler-time-grid-hour-size{syntax: \"<length>\"; inherits: true; initial-value: 48px;}@property --et-scheduler-time-grid-gutter-size{syntax: \"<length>\"; inherits: true; initial-value: 56px;}@property --et-scheduler-time-grid-all-day-row-size{syntax: \"<length>\"; inherits: true; initial-value: 24px;}@property --et-scheduler-time-grid-body-max-height{syntax: \"<length>\"; inherits: true; initial-value: 600px;}.et-scheduler-time-grid-view{display:flex;flex-direction:column}.et-scheduler-time-grid-row{display:flex}.et-scheduler-time-grid-body{overflow-y:auto;max-block-size:var(--et-scheduler-time-grid-body-max-height)}.et-scheduler-time-grid-gutter{flex-shrink:0;inline-size:var(--et-scheduler-time-grid-gutter-size)}.et-scheduler-time-grid-days{display:grid;flex:1;grid-auto-flow:column;grid-auto-columns:1fr}.et-scheduler-time-grid-header{padding-block-end:6px;border-block-end:1px solid var(--et-surface-border-solid)}.et-scheduler-time-grid-header-day{display:flex;flex-direction:column;align-items:center;gap:2px;padding-block:4px}.et-scheduler-time-grid-header-day:where([data-today]) .et-scheduler-time-grid-header-date{background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary)}.et-scheduler-time-grid-header-weekday{font-size:12px;font-weight:600;color:var(--et-surface-color-muted-solid)}.et-scheduler-time-grid-header-date{display:inline-flex;align-items:center;justify-content:center;inline-size:22px;block-size:22px;border-radius:999px;font-size:13px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-solid)}.et-scheduler-time-grid-all-day{padding-block:4px;border-block-end:1px solid var(--et-surface-border-solid)}.et-scheduler-time-grid-all-day-lane{position:relative;flex:1;min-block-size:calc(var(--_et-scheduler-time-grid-all-day-row-count, 0) * var(--et-scheduler-time-grid-all-day-row-size))}.et-scheduler-time-grid-all-day-entry{position:absolute;inset-block-start:calc(var(--_et-scheduler-time-grid-all-day-row, 0) * var(--et-scheduler-time-grid-all-day-row-size));inset-inline-start:calc(var(--_et-scheduler-time-grid-all-day-offset, 0) * 1%);inline-size:calc(var(--_et-scheduler-time-grid-all-day-size, 100) * 1% - 4px);block-size:calc(var(--et-scheduler-time-grid-all-day-row-size) - 2px)}.et-scheduler-time-grid-hour-row{box-sizing:border-box;block-size:var(--et-scheduler-time-grid-hour-size);border-block-end:1px solid var(--et-surface-border-solid)}.et-scheduler-time-grid-body .et-scheduler-time-grid-gutter .et-scheduler-time-grid-hour-row{display:flex;align-items:flex-start;justify-content:flex-end;padding-inline-end:8px;border-block-end:none}.et-scheduler-time-grid-hour-label{inline-size:max-content;transform:translateY(-50%);font-size:11px;font-variant-numeric:tabular-nums;color:var(--et-surface-color-muted-solid)}.et-scheduler-time-grid-body .et-scheduler-time-grid-days{border-inline-start:1px solid var(--et-surface-border-solid)}.et-scheduler-time-grid-day{position:relative;border-inline-end:1px solid var(--et-surface-border-solid);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-time-grid-day:where([data-today]){background:color-mix(in srgb,var(--et-theme-color-primary-solid) 6%,transparent)}.et-scheduler-time-grid-draft{position:absolute;inset-block-start:calc(var(--_et-scheduler-time-grid-block-offset, 0) * 1%);inset-inline:0 2px;block-size:calc(var(--_et-scheduler-time-grid-block-span, 0) * 1%);min-block-size:16px;border-radius:4px;border:1px dashed var(--et-theme-color-primary-solid);background:color-mix(in srgb,var(--et-theme-color-primary-solid) 10%,transparent);pointer-events:none}.et-scheduler-time-grid-draft:where([data-committed]){border-style:solid;background:color-mix(in srgb,var(--et-theme-color-primary-solid) 18%,transparent)}.et-scheduler-time-grid-block{position:absolute;inset-block-start:calc(var(--_et-scheduler-time-grid-block-offset, 0) * 1%);inset-inline-start:calc(var(--_et-scheduler-time-grid-block-inline-offset, 0) * 1%);block-size:calc(var(--_et-scheduler-time-grid-block-span, 0) * 1%);inline-size:calc(var(--_et-scheduler-time-grid-block-inline-size, 100) * 1% - 2px);min-block-size:16px;display:flex;align-items:flex-start;gap:6px;overflow:hidden;padding:2px 6px;padding-inline-start:calc(min(var(--_et-scheduler-time-grid-block-depth, 0),4)*6px + 6px);border:none;border-radius:4px;background:color-mix(in srgb,var(--et-theme-color-primary-solid) 14%,transparent);color:var(--et-theme-color-ink-solid);font:inherit;font-size:12px;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.et-scheduler-time-grid-block .et-scheduler-appointment-dot{margin-block-start:4px}@media(hover:hover){.et-scheduler-time-grid-block:hover{background:color-mix(in srgb,var(--et-theme-color-primary-solid) 22%,transparent)}}.et-scheduler-time-grid-block:focus-visible{outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}.et-scheduler-time-grid-block:where([data-selected]){background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary)}}\n"] }]
|
|
55076
55721
|
}], ctorParameters: () => [], propDecorators: { timeGridBody: [{ type: i0.ViewChild, args: ['timeGridBody', { isSignal: true }] }], firstHourRow: [{ type: i0.ViewChild, args: ['hourRow', { isSignal: true }] }], draftBlock: [{ type: i0.ViewChild, args: ['draftBlock', { isSignal: true }] }] } });
|
|
55077
55722
|
|
|
55723
|
+
const NARROW_CONTAINER_WIDTH = 480;
|
|
55078
55724
|
class SchedulerComponent {
|
|
55079
55725
|
constructor() {
|
|
55080
55726
|
this.labels = injectSchedulerLabels();
|
|
@@ -55088,6 +55734,14 @@ class SchedulerComponent {
|
|
|
55088
55734
|
this.appointmentSave = output();
|
|
55089
55735
|
/** Emits every id to remove once the default edit surface deletes a chain. */
|
|
55090
55736
|
this.appointmentsDelete = output();
|
|
55737
|
+
this.dimensions = signalHostElementDimensions();
|
|
55738
|
+
/**
|
|
55739
|
+
* Whether the scheduler has so little room that the toolbar has to give up its text buttons - the
|
|
55740
|
+
* same width the `et-scheduler` container query in `scheduler.component.css` reflows the header
|
|
55741
|
+
* at, so the two must move together.
|
|
55742
|
+
*/
|
|
55743
|
+
this.isNarrow = computed(() => (this.dimensions().client?.width ?? Infinity) < NARROW_CONTAINER_WIDTH, /* @ts-ignore */
|
|
55744
|
+
...(ngDevMode ? [{ debugName: "isNarrow" }] : /* istanbul ignore next */ []));
|
|
55091
55745
|
this.previousLabel = computed(() => this.labels().previous, /* @ts-ignore */
|
|
55092
55746
|
...(ngDevMode ? [{ debugName: "previousLabel" }] : /* istanbul ignore next */ []));
|
|
55093
55747
|
this.nextLabel = computed(() => this.labels().next, /* @ts-ignore */
|
|
@@ -55154,10 +55808,14 @@ class SchedulerComponent {
|
|
|
55154
55808
|
this.addSurfaceOpener = createOverlayOpener(SCHEDULER_ADD_SURFACE_OVERLAY, {
|
|
55155
55809
|
afterClosed: (result) => this.handleEditSurfaceResult(result),
|
|
55156
55810
|
});
|
|
55811
|
+
this.openedDraftRange = null;
|
|
55157
55812
|
/** A range dragged out on a view opens over the range itself - see {@link SchedulerDraftRange}. */
|
|
55158
55813
|
this.draftSurfaceOpener = createOverlayOpener(SCHEDULER_EDIT_SURFACE_OVERLAY, {
|
|
55159
55814
|
afterClosed: (result) => {
|
|
55160
|
-
|
|
55815
|
+
// the close is animated, so a range drawn while it plays out is already the next surface's
|
|
55816
|
+
if (this.headless.draftRange() === this.openedDraftRange) {
|
|
55817
|
+
this.headless.clearDraftRange();
|
|
55818
|
+
}
|
|
55161
55819
|
this.handleEditSurfaceResult(result);
|
|
55162
55820
|
},
|
|
55163
55821
|
});
|
|
@@ -55234,6 +55892,7 @@ class SchedulerComponent {
|
|
|
55234
55892
|
end: draft.end,
|
|
55235
55893
|
allDay: draft.allDay,
|
|
55236
55894
|
};
|
|
55895
|
+
this.openedDraftRange = draft;
|
|
55237
55896
|
this.draftSurfaceOpener.open({
|
|
55238
55897
|
origin: this.takeSurfaceAnchor(),
|
|
55239
55898
|
bindings: this.editSurfaceBindings(appointment),
|
|
@@ -55266,14 +55925,15 @@ class SchedulerComponent {
|
|
|
55266
55925
|
}
|
|
55267
55926
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
55268
55927
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: SchedulerComponent, isStandalone: true, selector: "et-scheduler", outputs: { appointmentSave: "appointmentSave", appointmentsDelete: "appointmentsDelete" }, host: { classAttribute: "et-scheduler" }, providers: [
|
|
55269
|
-
provideIcons(CHEVRON_ICON, PLUS_ICON),
|
|
55928
|
+
provideIcons(CALENDAR_ICON, CHEVRON_ICON, PLUS_ICON),
|
|
55270
55929
|
{ provide: SCHEDULER_FEATURE_HOST, useExisting: SchedulerComponent },
|
|
55271
|
-
], hostDirectives: [{ directive: SchedulerDirective, inputs: ["appointments", "appointments", "view", "view", "focusedDate", "focusedDate", "selectedAppointmentId", "selectedAppointmentId", "locale", "locale", "firstDayOfWeek", "firstDayOfWeek"], outputs: ["viewChange", "viewChange", "focusedDateChange", "focusedDateChange", "selectedAppointmentIdChange", "selectedAppointmentIdChange"] }, { directive: SchedulerBadgeColorDotDirective, inputs: ["etSchedulerBadgeColorDot", "etSchedulerBadgeColorDot"] }, { directive: SchedulerBadgeTitleDirective, inputs: ["etSchedulerBadgeTitle", "etSchedulerBadgeTitle"] }, { directive: SchedulerBadgeTimeRangeDirective, inputs: ["etSchedulerBadgeTimeRange", "etSchedulerBadgeTimeRange"] }, { directive: SchedulerBadgeLocationDirective, inputs: ["etSchedulerBadgeLocation", "etSchedulerBadgeLocation"] }, { directive: SchedulerBadgeChainCountDirective, inputs: ["etSchedulerBadgeChainCount", "etSchedulerBadgeChainCount"] }, { directive: SchedulerActionAddAppointmentDirective, inputs: ["etSchedulerActionAddAppointment", "etSchedulerActionAddAppointment"] }], ngImport: i0, template: "<div class=\"et-scheduler-header\">\n <button\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n {{ todayLabel() }}\n </button>\n\n @for (action of toolbarActions(); track $index) {\n
|
|
55930
|
+
], hostDirectives: [{ directive: SchedulerDirective, inputs: ["appointments", "appointments", "view", "view", "focusedDate", "focusedDate", "selectedAppointmentId", "selectedAppointmentId", "locale", "locale", "firstDayOfWeek", "firstDayOfWeek"], outputs: ["viewChange", "viewChange", "focusedDateChange", "focusedDateChange", "selectedAppointmentIdChange", "selectedAppointmentIdChange"] }, { directive: SchedulerBadgeColorDotDirective, inputs: ["etSchedulerBadgeColorDot", "etSchedulerBadgeColorDot"] }, { directive: SchedulerBadgeTitleDirective, inputs: ["etSchedulerBadgeTitle", "etSchedulerBadgeTitle"] }, { directive: SchedulerBadgeTimeRangeDirective, inputs: ["etSchedulerBadgeTimeRange", "etSchedulerBadgeTimeRange"] }, { directive: SchedulerBadgeLocationDirective, inputs: ["etSchedulerBadgeLocation", "etSchedulerBadgeLocation"] }, { directive: SchedulerBadgeChainCountDirective, inputs: ["etSchedulerBadgeChainCount", "etSchedulerBadgeChainCount"] }, { directive: SchedulerActionAddAppointmentDirective, inputs: ["etSchedulerActionAddAppointment", "etSchedulerActionAddAppointment"] }, { directive: SchedulerSwipeNavigationDirective, inputs: ["etSchedulerSwipeNavigation", "etSchedulerSwipeNavigation"] }], ngImport: i0, template: "<div class=\"et-scheduler-header\">\n <button\n [attr.aria-label]=\"todayLabel()\"\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n <i etIcon=\"et-calendar\" aria-hidden=\"true\"></i>\n <span class=\"et-scheduler-today-button-label\">{{ todayLabel() }}</span>\n </button>\n\n @if (isNarrow()) {\n <div class=\"et-scheduler-toolbar-fabs\" etFloatingAction>\n <div etFloatingActionAnchor>\n <div class=\"et-scheduler-toolbar-fab-stack\" etFloatingActionTrigger>\n @for (action of toolbarActions(); track $index) {\n <!-- The icon has to be a static child of the FAB to reach its icon slot, so the two\n shapes are separate elements rather than one with a conditional icon inside. -->\n @if (action.icon; as icon) {\n <button\n [attr.aria-label]=\"action.label()\"\n (click)=\"action.run()\"\n class=\"et-scheduler-toolbar-action\"\n et-fab\n type=\"button\"\n >\n <i [etIcon]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-fab expanded type=\"button\">\n {{ action.label() }}\n </button>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n @for (action of toolbarActions(); track $index) {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-button size=\"sm\" type=\"button\">\n @if (action.icon) {\n <i [etIcon]=\"action.icon\" aria-hidden=\"true\"></i>\n }\n {{ action.label() }}\n </button>\n }\n }\n\n <div class=\"et-scheduler-nav-buttons\">\n <button\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"headless.previous()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--previous\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n\n <button\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"headless.next()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--next\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n </div>\n\n <span class=\"et-scheduler-header-label\">{{ headerLabel() }}</span>\n\n <div class=\"et-scheduler-header-spacer\"></div>\n\n <et-segmented-button-group\n [value]=\"headless.view()\"\n (valueChange)=\"setView($event)\"\n class=\"et-scheduler-view-switch\"\n size=\"sm\"\n variant=\"tabs\"\n >\n <et-label class=\"et-scheduler-view-switch-label\">{{ switchViewLabel() }}</et-label>\n\n <et-segmented-button value=\"month\">{{ monthViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"week\">{{ weekViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"day\">{{ dayViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"agenda\">{{ agendaViewLabel() }}</et-segmented-button>\n </et-segmented-button-group>\n</div>\n\n<div class=\"et-scheduler-body\">\n @switch (headless.view()) {\n @case ('week') {\n <et-scheduler-time-grid-view />\n }\n @case ('day') {\n <et-scheduler-time-grid-view />\n }\n @case ('agenda') {\n <et-scheduler-agenda-view />\n }\n @default {\n <et-scheduler-month-view />\n }\n }\n</div>\n", styles: ["@layer components{.et-scheduler{container-type:inline-size;container-name:et-scheduler;display:flex;flex-direction:column;gap:12px}.et-scheduler-header{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.et-scheduler-view-switch{flex-basis:100%}.et-scheduler-toolbar-fab-stack{display:flex;gap:8px}@container et-scheduler not (min-inline-size: 480px){.et-scheduler .et-scheduler-today-button{--et-button-padding: 0;inline-size:3.1rem;block-size:3.1rem;border-radius:9999px}.et-scheduler .et-scheduler-today-button-label{display:none}}@container et-scheduler (min-inline-size: 480px){.et-scheduler-header-spacer{display:block}.et-scheduler-view-switch{flex-basis:auto}.et-scheduler .et-scheduler-today-button .et-button-icon{display:none}}.et-scheduler-nav-buttons{display:flex;gap:2px}.et-scheduler-nav-button--previous .et-icon{rotate:-90deg}.et-scheduler-nav-button--next .et-icon{rotate:90deg}.et-scheduler-header-label{flex:1 1 auto;min-inline-size:0;overflow:hidden;font-size:15px;font-weight:600;color:var(--et-surface-color-solid);white-space:nowrap;text-overflow:ellipsis}.et-scheduler-header-spacer{display:none;flex:1}.et-scheduler-view-switch-label{position:absolute;inline-size:1px;block-size:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.et-scheduler-body{display:flex;flex:1;flex-direction:column}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "[et-button]", inputs: ["variant", "size", "iconAlignment"] }, { kind: "component", type: FabComponent, selector: "[et-fab]", inputs: ["variant", "size", "expanded", "iconAlignment"] }, { kind: "component", type: IconButtonComponent, selector: "[et-icon-button]", inputs: ["variant", "size"] }, { kind: "directive", type: FloatingActionDirective, selector: "[etFloatingAction]", inputs: ["disabled"], exportAs: ["etFloatingAction"] }, { kind: "directive", type: FloatingActionAnchorDirective, selector: "[etFloatingActionAnchor]", exportAs: ["etFloatingActionAnchor"] }, { kind: "directive", type: FloatingActionTriggerDirective, selector: "[etFloatingActionTrigger]", exportAs: ["etFloatingActionTrigger"] }, { kind: "component", type: SegmentedButtonGroupComponent, selector: "et-segmented-button-group", inputs: ["size", "variant"] }, { kind: "component", type: SegmentedButtonComponent, selector: "et-segmented-button" }, { kind: "component", type: LabelDirective, selector: "et-label" }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "component", type: SchedulerAgendaViewComponent, selector: "et-scheduler-agenda-view" }, { kind: "component", type: SchedulerMonthViewComponent, selector: "et-scheduler-month-view" }, { kind: "component", type: SchedulerTimeGridViewComponent, selector: "et-scheduler-time-grid-view" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
55272
55931
|
}
|
|
55273
55932
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SchedulerComponent, decorators: [{
|
|
55274
55933
|
type: Component,
|
|
55275
55934
|
args: [{ selector: 'et-scheduler', encapsulation: ViewEncapsulation.None, imports: [
|
|
55276
55935
|
...BUTTON_IMPORTS,
|
|
55936
|
+
...FLOATING_ACTION_IMPORTS,
|
|
55277
55937
|
...SEGMENTED_BUTTON_IMPORTS,
|
|
55278
55938
|
LabelDirective,
|
|
55279
55939
|
IconDirective,
|
|
@@ -55281,7 +55941,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
55281
55941
|
SchedulerMonthViewComponent,
|
|
55282
55942
|
SchedulerTimeGridViewComponent,
|
|
55283
55943
|
], providers: [
|
|
55284
|
-
provideIcons(CHEVRON_ICON, PLUS_ICON),
|
|
55944
|
+
provideIcons(CALENDAR_ICON, CHEVRON_ICON, PLUS_ICON),
|
|
55285
55945
|
{ provide: SCHEDULER_FEATURE_HOST, useExisting: SchedulerComponent },
|
|
55286
55946
|
], hostDirectives: [
|
|
55287
55947
|
{
|
|
@@ -55298,9 +55958,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
55298
55958
|
{ directive: SchedulerBadgeLocationDirective, inputs: ['etSchedulerBadgeLocation'] },
|
|
55299
55959
|
{ directive: SchedulerBadgeChainCountDirective, inputs: ['etSchedulerBadgeChainCount'] },
|
|
55300
55960
|
{ directive: SchedulerActionAddAppointmentDirective, inputs: ['etSchedulerActionAddAppointment'] },
|
|
55961
|
+
{ directive: SchedulerSwipeNavigationDirective, inputs: ['etSchedulerSwipeNavigation'] },
|
|
55301
55962
|
], host: {
|
|
55302
55963
|
class: 'et-scheduler',
|
|
55303
|
-
}, template: "<div class=\"et-scheduler-header\">\n <button\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n {{ todayLabel() }}\n </button>\n\n @for (action of toolbarActions(); track $index) {\n
|
|
55964
|
+
}, template: "<div class=\"et-scheduler-header\">\n <button\n [attr.aria-label]=\"todayLabel()\"\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n <i etIcon=\"et-calendar\" aria-hidden=\"true\"></i>\n <span class=\"et-scheduler-today-button-label\">{{ todayLabel() }}</span>\n </button>\n\n @if (isNarrow()) {\n <div class=\"et-scheduler-toolbar-fabs\" etFloatingAction>\n <div etFloatingActionAnchor>\n <div class=\"et-scheduler-toolbar-fab-stack\" etFloatingActionTrigger>\n @for (action of toolbarActions(); track $index) {\n <!-- The icon has to be a static child of the FAB to reach its icon slot, so the two\n shapes are separate elements rather than one with a conditional icon inside. -->\n @if (action.icon; as icon) {\n <button\n [attr.aria-label]=\"action.label()\"\n (click)=\"action.run()\"\n class=\"et-scheduler-toolbar-action\"\n et-fab\n type=\"button\"\n >\n <i [etIcon]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-fab expanded type=\"button\">\n {{ action.label() }}\n </button>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n @for (action of toolbarActions(); track $index) {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-button size=\"sm\" type=\"button\">\n @if (action.icon) {\n <i [etIcon]=\"action.icon\" aria-hidden=\"true\"></i>\n }\n {{ action.label() }}\n </button>\n }\n }\n\n <div class=\"et-scheduler-nav-buttons\">\n <button\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"headless.previous()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--previous\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n\n <button\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"headless.next()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--next\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n </div>\n\n <span class=\"et-scheduler-header-label\">{{ headerLabel() }}</span>\n\n <div class=\"et-scheduler-header-spacer\"></div>\n\n <et-segmented-button-group\n [value]=\"headless.view()\"\n (valueChange)=\"setView($event)\"\n class=\"et-scheduler-view-switch\"\n size=\"sm\"\n variant=\"tabs\"\n >\n <et-label class=\"et-scheduler-view-switch-label\">{{ switchViewLabel() }}</et-label>\n\n <et-segmented-button value=\"month\">{{ monthViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"week\">{{ weekViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"day\">{{ dayViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"agenda\">{{ agendaViewLabel() }}</et-segmented-button>\n </et-segmented-button-group>\n</div>\n\n<div class=\"et-scheduler-body\">\n @switch (headless.view()) {\n @case ('week') {\n <et-scheduler-time-grid-view />\n }\n @case ('day') {\n <et-scheduler-time-grid-view />\n }\n @case ('agenda') {\n <et-scheduler-agenda-view />\n }\n @default {\n <et-scheduler-month-view />\n }\n }\n</div>\n", styles: ["@layer components{.et-scheduler{container-type:inline-size;container-name:et-scheduler;display:flex;flex-direction:column;gap:12px}.et-scheduler-header{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.et-scheduler-view-switch{flex-basis:100%}.et-scheduler-toolbar-fab-stack{display:flex;gap:8px}@container et-scheduler not (min-inline-size: 480px){.et-scheduler .et-scheduler-today-button{--et-button-padding: 0;inline-size:3.1rem;block-size:3.1rem;border-radius:9999px}.et-scheduler .et-scheduler-today-button-label{display:none}}@container et-scheduler (min-inline-size: 480px){.et-scheduler-header-spacer{display:block}.et-scheduler-view-switch{flex-basis:auto}.et-scheduler .et-scheduler-today-button .et-button-icon{display:none}}.et-scheduler-nav-buttons{display:flex;gap:2px}.et-scheduler-nav-button--previous .et-icon{rotate:-90deg}.et-scheduler-nav-button--next .et-icon{rotate:90deg}.et-scheduler-header-label{flex:1 1 auto;min-inline-size:0;overflow:hidden;font-size:15px;font-weight:600;color:var(--et-surface-color-solid);white-space:nowrap;text-overflow:ellipsis}.et-scheduler-header-spacer{display:none;flex:1}.et-scheduler-view-switch-label{position:absolute;inline-size:1px;block-size:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.et-scheduler-body{display:flex;flex:1;flex-direction:column}}\n"] }]
|
|
55304
55965
|
}], ctorParameters: () => [], propDecorators: { appointmentSave: [{ type: i0.Output, args: ["appointmentSave"] }], appointmentsDelete: [{ type: i0.Output, args: ["appointmentsDelete"] }] } });
|
|
55305
55966
|
|
|
55306
55967
|
const SCHEDULER_IMPORTS = [
|
|
@@ -55327,6 +55988,7 @@ const SCHEDULER_IMPORTS = [
|
|
|
55327
55988
|
SchedulerActionAddSubAppointmentDirective,
|
|
55328
55989
|
SchedulerActionDeleteDirective,
|
|
55329
55990
|
SchedulerActionAddAppointmentDirective,
|
|
55991
|
+
SchedulerSwipeNavigationDirective,
|
|
55330
55992
|
];
|
|
55331
55993
|
|
|
55332
55994
|
/** The built-in English labels. */
|
|
@@ -66767,5 +67429,5 @@ const TREE_IMPORTS = [TreeComponent, TreeDirective, TreeNodeDirective, TreeNodeD
|
|
|
66767
67429
|
* Generated bundle index. Do not edit.
|
|
66768
67430
|
*/
|
|
66769
67431
|
|
|
66770
|
-
export { ACCORDION_ERROR_CODES, ACCORDION_GROUP_TOKEN, ACCORDION_IMPORTS, ACCORDION_TOKEN, ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROWS_LEFT_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, ARROW_UP_ICON, AVATAR_IMPORTS, AVATAR_SHAPES, AVATAR_SIZES, AccordionComponent, AccordionContentDirective, AccordionDirective, AccordionGroupComponent, AccordionGroupDirective, AccordionHintDirective, AccordionLabelDirective, AccordionPanelDirective, AccordionTriggerDirective, AvatarComponent, AvatarGroupComponent, BADGE_ICON_ALIGNMENTS, BADGE_IMPORTS, BADGE_SIZES, BADGE_VARIANTS, BANNER_IMPORTS, BANNER_LABELS, BANNER_TYPES, BOLD_ICON, BRACKET_CARD_CONTEXT, BRACKET_DATA_LAYOUT, BRACKET_DEFAULTS, BRACKET_DENSITY, BRACKET_DENSITY_PRESETS, BRACKET_ERROR_CODES, BRACKET_IMPORTS, BRACKET_LABELS, BRACKET_ROUND_MIRROR_TYPE, BRACKET_SWISS_GROUP_COLOR_TYPE, BREADCRUMB_COLLAPSE_IMPORTS, BREADCRUMB_COLLAPSE_TOKEN, BREADCRUMB_ERROR_CODES, BREADCRUMB_IMPORTS, BREADCRUMB_LABELS, BREADCRUMB_SEGMENT_TOKEN, BREADCRUMB_SEO_IMPORTS, BREADCRUMB_TOKEN, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BadgeComponent, BannerComponent, BracketComponent, BracketDefaultContinueComponent, BracketDefaultFinalMatchComponent, BracketDefaultMatchComponent, BracketDefaultRoundHeaderComponent, BracketMap, BracketRoundsListComponent, BrandLoaderComponent, BreadcrumbCollapseDirective, BreadcrumbComponent, BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbItemTemplateDirective, BreadcrumbOutletComponent, BreadcrumbOverflowComponent, BreadcrumbSegmentDirective, BreadcrumbSeoDirective, BreadcrumbSeparatorDirective, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CALENDAR_LABELS, CARD_IMPORTS, CARD_VARIANTS, CAROUSEL_AUTOPLAY_TOKEN, CAROUSEL_ERROR_CODES, CAROUSEL_IMPORTS, CAROUSEL_LABELS, CAROUSEL_SLIDE_ALIGNMENTS, CAROUSEL_TOKEN, CAROUSEL_TRANSITIONS, CAROUSEL_TRANSITION_DRIVERS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_LABELS, CASCADER_SELECTABLE_LEVELS, CHECKBOX_GROUP_IMPORTS, CHECKBOX_IMPORTS, CHECKBOX_OPTION_VARIANTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHIP_LABELS, CHOICE_FIELD_IMPORTS, CHOICE_FIELD_VARIANTS, CIRCLE_CHECK_ICON, CIRCLE_INFO_ICON, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_BLOCK_ICON, CODE_ICON, COLOR_INPUT_IMPORTS, COMMON_BRACKET_ROUND_TYPE, COPY_BUTTON_IMPORTS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CalendarHeaderDirective, CardComponent, CarouselAutoplayDirective, CarouselComponent, CarouselDirective, CarouselItemDirective, CarouselNextDirective, CarouselPlayToggleDirective, CarouselPreviousDirective, CarouselSlideDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxGroupSelectAllComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, ControlSuffixDirective, CopyButtonDirective, CounterComponent, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DATE_TIME_LABELS, DEFAULT_BANNER_LABELS, DEFAULT_BRACKET_LABELS, DEFAULT_BREADCRUMB_LABELS, DEFAULT_BREAKPOINTS, DEFAULT_CALENDAR_LABELS, DEFAULT_CALENDAR_RANGE_STRATEGY, DEFAULT_CAROUSEL_LABELS, DEFAULT_CASCADER_LABELS, DEFAULT_CHIP_LABELS, DEFAULT_DATE_TIME_LABELS, DEFAULT_DROPZONE_LABELS, DEFAULT_FILTER_OVERLAY_LABELS, DEFAULT_FORM_FIELD_LABELS, DEFAULT_GRID_LABELS, DEFAULT_ICON_VARIANT, DEFAULT_INPUT_LABELS, DEFAULT_LOADER_LABELS, DEFAULT_MATCH_CARD_START_TIME_FORMAT, DEFAULT_MATCH_LABELS, DEFAULT_NOTIFICATION_LABELS, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_NOTIFICATION_STATUS_ICONS, DEFAULT_PAGINATION_LABELS, DEFAULT_PHONE_INPUT_LABELS, DEFAULT_PIP_WINDOW_CONFIG, DEFAULT_QUERY_ERROR_LABELS, DEFAULT_RICH_TEXT_EDITOR_LABELS, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_SCHEDULER_LABELS, DEFAULT_SELECT_LABELS, DEFAULT_SLIDER_LABELS, DEFAULT_STANDINGS_LABELS, DEFAULT_STREAM_LABELS, DEFAULT_STREAM_PLAYER_STATE, DEFAULT_TABLE_LABELS, DEFAULT_TIME_PICKER_LABELS, DESCRIPTION_IMPORTS, DESCRIPTION_LIST_IMPORTS, DIVIDER_IMPORTS, DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DROPZONE_LABELS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DescriptionComponent, DescriptionListComponent, DividerComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ELLIPSIS_ICON, ELLIPSIS_VERTICAL_ICON, EMPTY_STATE_IMPORTS, ET_BUILT_IN_ICON_NAMES, EYE_ICON, EYE_SLASH_ICON, EmptyStateComponent, FACEBOOK_PLAYER_TOKEN, FILE_ICON, FILTER_ICON, FILTER_OVERLAY_ERROR_CODES, FILTER_OVERLAY_IMPORTS, FILTER_OVERLAY_LABELS, FILTER_OVERLAY_TOKEN, FLOATING_ACTION_ERROR_CODES, FLOATING_ACTION_IMPORTS, FLOATING_ACTION_STATES, FLOATING_ACTION_TOKEN, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABELS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FilterOverlayResetDirective, FilterOverlaySubmitDirective, FloatingActionAnchorDirective, FloatingActionDirective, FloatingActionScopeDirective, FloatingActionTopDirective, FloatingActionTriggerDirective, FocusRingDirective, FormErrorComponent, FormFieldBarrierDirective, FormFieldComponent, FormFieldDirective, GERMAN_FILTER_OVERLAY_LABELS, GERMAN_QUERY_ERROR_LABELS, GRID_2X2_ICON, GRID_DEBUG_IMPORTS, GRID_ERROR_CODES, GRID_IMPORTS, GRID_LABELS, GRID_TOKEN, GROUP_BRACKET_ROUND_TYPE, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemRef, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, IMAGE_ICON, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_LABELS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KBD_IMPORTS, KBD_PLATFORM, KICK_PLAYER_TOKEN, KbdComponent, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOADER_LABELS, LOCATION_ICON, LOCK_ICON, LabelDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MASONRY_ERROR_CODES, MASONRY_IMPORTS, MASONRY_TOKEN, MATCH_CARD_IMPORTS, MATCH_CARD_SIZES, MATCH_CARD_TOKEN, MATCH_ERROR_CODES, MATCH_LABELS, MATCH_PARTICIPANT_IMPORTS, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MasonryDirective, MasonryItemDirective, MatchCardComponent, MatchCardDirective, MatchCardGameScoresDirective, MatchCardMetaDirective, MatchCardScoreDirective, MatchParticipantComponent, MatchScoreComponent, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ACTION_SLOTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_LABELS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STATUS, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NotificationSwipeToDismissDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PAGE_SIZE_SELECT_IMPORTS, PAGINATION_IMPORTS, PAGINATION_LABELS, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PAUSE_ICON, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PHONE_INPUT_LABELS, PICTURE_IMPORTS, PICTURE_STATES, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLAY_ICON, PLUS_ICON, PROGRESS_STEPS_IMPORTS, PROGRESS_STEP_STATES, PageSizeSelectComponent, PaginationComponent, PaginationDirective, PaginationSeoDirective, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PictureComponent, PictureErrorDirective, PicturePlaceholderDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, ProgressStepComponent, ProgressStepsComponent, QUERY_DEVTOOLS_IMPORTS, QUERY_ERROR_ERROR_CODES, QUERY_ERROR_IMPORTS, QUERY_ERROR_LABELS, QUERY_ERROR_TOKEN, QUOTE_ICON, QueryDevtoolsComponent, QueryDevtoolsJsonComponent, QueryDevtoolsJsonStylesComponent, QueryDevtoolsTimelineStylesComponent, QueryDevtoolsToggleComponent, QueryErrorActionsDirective, QueryErrorComponent, QueryErrorDirective, QueryErrorTitleDirective, QueryParamOverlayLinkDirective, RADIO_GROUP_IMPORTS, RADIO_VARIANTS, RATING_IMPORTS, REDO_ICON, RICH_TEXT_EDITOR_FLOATING_TOOLBAR, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LABELS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_LINK_EDITOR, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorHeadingToolComponent, RichTextEditorImageEditorComponent, RichTextEditorImageStylesComponent, RichTextEditorImageToolComponent, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableStylesComponent, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, SCHEDULER_ADD_SURFACE_OVERLAY, SCHEDULER_EDIT_SURFACE_HOST, SCHEDULER_EDIT_SURFACE_OVERLAY, SCHEDULER_ERROR_CODES, SCHEDULER_FEATURE_HOST, SCHEDULER_IMPORTS, SCHEDULER_LABELS, SCROLLABLE_DARKEN_IMPORTS, SCROLLABLE_DRAG_IMPORTS, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SCROLLABLE_NAVIGATION_IMPORTS, SEGMENTED_BUTTON_GROUP_VARIANTS, SEGMENTED_BUTTON_IMPORTS, SELECTION_LIST_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SELECT_LABELS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SINGLE_ELIMINATION_BRACKET_ROUND_TYPE, SKELETON_IMPORTS, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_LABELS, SLIDER_MARK_VALUE_ATTRIBUTE, SLIDER_TOKEN, SNAP_HYSTERESIS, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STANDINGS_ERROR_CODES, STANDINGS_IMPORTS, STANDINGS_LABELS, STAR_ICON, STREAM_ALL_IMPORTS, STREAM_CONSENT_TOKEN, STREAM_DAILYMOTION_IMPORTS, STREAM_FACEBOOK_IMPORTS, STREAM_IMPORTS, STREAM_KICK_IMPORTS, STREAM_LABELS, STREAM_PIP_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_SOOP_IMPORTS, STREAM_TIKTOK_IMPORTS, STREAM_TWITCH_IMPORTS, STREAM_USER_CONSENT_PROVIDER_TOKEN, STREAM_VIMEO_IMPORTS, STREAM_YOUTUBE_IMPORTS, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWISS_BRACKET_ROUND_TYPE, SWITCH_IMPORTS, SchedulerActionAddAppointmentDirective, SchedulerActionAddSubAppointmentDirective, SchedulerActionDeleteDirective, SchedulerAgendaDirective, SchedulerAgendaViewComponent, SchedulerBadgeChainCountComponent, SchedulerBadgeChainCountDirective, SchedulerBadgeColorDotComponent, SchedulerBadgeColorDotDirective, SchedulerBadgeLocationComponent, SchedulerBadgeLocationDirective, SchedulerBadgeTimeRangeComponent, SchedulerBadgeTimeRangeDirective, SchedulerBadgeTitleComponent, SchedulerBadgeTitleDirective, SchedulerComponent, SchedulerDirective, SchedulerEditColorComponent, SchedulerEditColorDirective, SchedulerEditDescriptionComponent, SchedulerEditDescriptionDirective, SchedulerEditLocationComponent, SchedulerEditLocationDirective, SchedulerEditSurfaceComponent, SchedulerEditSurfaceDirective, SchedulerEditTimeRangeComponent, SchedulerEditTimeRangeDirective, SchedulerEditTitleComponent, SchedulerEditTitleDirective, SchedulerMonthDirective, SchedulerMonthViewComponent, SchedulerTimeGridDirective, SchedulerTimeGridViewComponent, ScrollableActiveChildDirective, ScrollableButtonsComponent, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksComponent, ScrollableNavigationComponent, ScrollableNavigationDirective, ScrollableSnapDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SkeletonComponent, SkeletonItemComponent, SkeletonTextComponent, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StandingsComponent, StandingsDirective, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_CELL_ERROR_TOOLTIP_IMPORTS, TABLE_COLUMN_CHOOSER_IMPORTS, TABLE_COLUMN_MENU_IMPORTS, TABLE_CSV_EXPORT_IMPORTS, TABLE_ERROR_CODES, TABLE_FEATURE_HOST, TABLE_FILTER_IMPORTS, TABLE_GROUP_HEADERS_IMPORTS, TABLE_ICON, TABLE_IMPORTS, TABLE_INLINE_EDIT_IMPORTS, TABLE_KEYBOARD_NAV_IMPORTS, TABLE_LABELS, TABLE_REORDER_IMPORTS, TABLE_RESIZE_IMPORTS, TABLE_ROW_EXPANSION_IMPORTS, TABLE_SELECTION_IMPORTS, TABLE_SKELETON_IMPORTS, TABLE_STATE_PERSISTENCE_IMPORTS, TABLE_STICKY_COLUMNS_IMPORTS, TABLE_VIRTUAL_SCROLL_IMPORTS, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TIKTOK_PLAYER_TOKEN, TIMELINE_IMPORTS, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TIME_PICKER_LABELS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLBAR_IMPORTS, TOOLBAR_ORIENTATIONS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TOURNAMENT_MODE, TRASH_ICON, TREE_ERROR_CODES, TREE_IMPORTS, TREE_LEVEL_STATUSES, TREE_MARKERS, TREE_SELECTION_MODES, TRIANGLE_EXCLAMATION_ICON, TROPHY_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TableCellDirective, TableCellEditDirective, TableCellErrorMarkComponent, TableCellErrorTooltipDirective, TableCellSkeletonDirective, TableColumnChooserComponent, TableColumnMenuDirective, TableColumnMenuTriggerComponent, TableComponent, TableCsvExportDirective, TableDetailStylesComponent, TableExpanderCellComponent, TableFilterOptionDirective, TableFilterTriggerComponent, TableFiltersDirective, TableFooterCellDirective, TableFooterDirective, TableGroupHeaderRowComponent, TableGroupHeadersDirective, TableHeaderCellDirective, TableInlineEditDirective, TableInlineEditStylesComponent, TableKeyboardNavDirective, TableReorderDirective, TableReorderOverlayComponent, TableResizeDirective, TableResizeGripComponent, TableRowDetailComponent, TableRowExpansionDirective, TableSelectAllCellComponent, TableSelectCellComponent, TableSelectionDirective, TableSkeletonDirective, TableSkeletonRowsComponent, TableStatePersistenceDirective, TableStickyColumnsDirective, TableVirtualScrollDirective, TableVirtualScrollStylesComponent, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerColumnDirective, TimePickerComponent, TimePickerDirective, TimePickerOptionDirective, TimelineComponent, TimelineItemComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, ToolbarComponent, ToolbarDirective, TooltipComponent, TooltipDirective, TreeComponent, TreeDirective, TreeMarkerComponent, TreeNodeDefDirective, TreeNodeDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNDO_ICON, UNIT_MS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_SLOT_TOKEN, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, YoutubePlayerSlotDirective, abortFullscreenAnimation, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, autoPlace, bottomSheetOverlayStrategy, bracketFitsWidth, bracketNaturalWidth, buildAnchoredRuntimePositionStrategy, canHaveChildren, cascaderFromQuery, centeredOverlayStrategy, clampPosition, clampResizeRect, cleanupFullscreenAnimation, cleanupFullscreenAnimationStyles, compactLayout, computeGeometry, computeGridHeight, countDescendants, createAnchoredPanelController, createAutoScroller, createCardMask, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createFixedLengthRangeStrategy, createGridAdapter, createIbanMask, createNormalizedBracketMatch, createNotificationPromiseFn, createNotificationRef, createOverlayOpener, createOverlayRef, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createStreamConfig, createStreamPlayerSlot, createTableRowsSource, createTableStateStorage, createV2DropzoneUpload, createWeekRangeStrategy, defaultCompareWith$1 as defaultCompareWith, defaultDropzoneRejectionMessage, defineOverlay, defineQueryParamOverlay, deriveDurationFormatSpec, deserializeGridLayout, deserializeTableState, detectKbdPlatform, dialogOverlayStrategy, disposeDropzoneEntry, doubleEliminationBracketLayout, dropzoneFiles, enableDragToDismiss, extractFirstImageUrl, filterOverlayLabelsForLocale, filterOverlayPreviewFromQuery, filterRows, findCollision, findNextRelevantHtmlElement, findScrollableAncestor, formatDuration, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, generateBracketDataForEthlete, generateRoundTypeFromEthleteRoundType, generateTournamentModeFormEthleteRounds, getClosestOverlay, getOriginCoordinatesAndDimensions, hysteresisRound, iconRegistryKey, indexOfNode, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectBannerLabels, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectBracketConfig, injectBracketLabels, injectBreadcrumbLabels, injectBreadcrumbManager, injectCalendarLabels, injectCarouselLabels, injectCascaderLabels, injectChipLabels, injectDateFormat, injectDateLocale, injectDateTimeLabels, injectDialogStrategy, injectDialogStrategyDefaults, injectDropzoneLabels, injectFilterOverlay, injectFilterOverlayLabels, injectFormFieldLabels, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectGridLabels, injectInputLabels, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectLoaderLabels, injectMatchLabels, injectNotificationLabels, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPaginationLabels, injectPhoneInputLabels, injectPictureConfig, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectQueryErrorLabels, injectRichTextEditorLabels, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSchedulerEditSurfaceHost, injectSchedulerFeatureHost, injectSchedulerLabels, injectSelectLabels, injectSidebarOverlay, injectSliderLabels, injectStandingsLabels, injectStreamConfig, injectStreamConsentConfig, injectStreamLabels, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTableCsvExport, injectTableFeatureHost, injectTableLabels, injectTimeFormat, injectTimePickerLabels, injectTopSheetStrategy, injectTopSheetStrategyDefaults, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isTargetInsideOverlayTree, isTouchEvent, itemsCollide, kbdKeyLabel, kbdKeyName, kindOf, leftSheetOverlayStrategy, legacyQueryErrorSource, mapLayoutToBreakpoint, matchCountryByDialCode, matchParticipantDisplayName, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, mirroredDoubleEliminationBracketLayout, mirroredSingleEliminationBracketLayout, mountRichTextEditorImageStyles, mountRichTextEditorTableStyles, nodesEqual$1 as nodesEqual, normalizeEthleteBracketMatch, normalizeEthleteGroupRanking, normalizeEthleteMatch, normalizeEthleteMatchStatus, normalizeEthleteMedia, normalizeEthleteParticipant, normalizeEthletePlacement, normalizePictureSizes, normalizePictureSource, paginate, parseDuration, parseKbdKeys, phoneCountryFlag, phoneCountryName, pixelRectsEqual, positionToPixelRect, positionsEqual, projectDragCell, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideBannerLabels, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideBracketConfig, provideBracketLabels, provideBreadcrumbLabels, provideBreadcrumbManager, provideCalendarLabels, provideCarouselLabels, provideCascaderLabels, provideChipLabels, provideDateFormat, provideDateLocale, provideDateTimeLabels, provideDialogStrategy, provideDialogStrategyDefaults, provideDropzoneLabels, provideFilterOverlay, provideFilterOverlayLabels, provideFormErrorMessageResolver, provideFormFieldLabels, provideFormSupport, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideGridLabels, provideIconOverrides, provideIcons, provideInputLabels, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideLoaderLabels, provideMatchLabels, provideNotificationLabels, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePaginationLabels, providePhoneInputLabels, providePictureConfig, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideQueryErrorLabels, provideRichTextEditorAlignmentTool, provideRichTextEditorAutoformat, provideRichTextEditorBlockquoteTool, provideRichTextEditorCodeBlockTool, provideRichTextEditorDefaultTools, provideRichTextEditorFloatingToolbar, provideRichTextEditorHeadingTool, provideRichTextEditorImageTool, provideRichTextEditorLabels, provideRichTextEditorLanguageTool, provideRichTextEditorLinkEditor, provideRichTextEditorLinkTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSchedulerLabels, provideSelectLabels, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideSliderLabels, provideStandingsLabels, provideStreamConfig, provideStreamConsentConfig, provideStreamLabels, provideStreamManager, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTableLabels, provideTimeFormat, provideTimePickerLabels, provideTopSheetStrategy, provideTopSheetStrategyDefaults, queryErrorLabelsForLocale, queryErrorResponseFromLegacyError, reconcileColumnOrder, reconcileColumnWidths, reconcileHiddenColumns, reduceSupportPresentation, registerSingleton, requiredLanguages, resizeSpanBounds, resolveBracketLayout, resolveBreakpoint, resolveClosestOverlay, resolveCollisions, resolveFilterOverlaySubmitButton, resolveNotificationStatusIcon, resolveTableCsvRows, richTextEditorToolLabel, rightSheetOverlayStrategy, rowsToPixelHeight, schedulerFeatureConfig, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, serializeTableState, setupRichTextEditorFloatingToolbar, setupRichTextEditorLinkEditor, singleEliminationBracketLayout, snapResizeSpan, sortRows, spanHeight, spanWidth, startFullscreenEnterAnimation, startFullscreenLeaveAnimation, startImageUpload, startOfCalendarUnit, stripTrunkZero, supportPresentationIncludesState, swissBracketLayout, tableCsvRowsFromPages, tableFeatureConfig, tableRowsFromQuery, tableRowsFromV2Query, tableToCsv, toChildrenObservable$1 as toChildrenObservable, toGridPosition, toNotificationContent, toPathObservable, toSearchObservable, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, wireFormSupport, withPictureBaseUrl };
|
|
67432
|
+
export { ACCORDION_ERROR_CODES, ACCORDION_GROUP_TOKEN, ACCORDION_IMPORTS, ACCORDION_TOKEN, ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROWS_LEFT_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, ARROW_UP_ICON, AVATAR_IMPORTS, AVATAR_SHAPES, AVATAR_SIZES, AccordionComponent, AccordionContentDirective, AccordionDirective, AccordionGroupComponent, AccordionGroupDirective, AccordionHintDirective, AccordionLabelDirective, AccordionPanelDirective, AccordionTriggerDirective, AvatarComponent, AvatarGroupComponent, BADGE_ICON_ALIGNMENTS, BADGE_IMPORTS, BADGE_SIZES, BADGE_VARIANTS, BANNER_IMPORTS, BANNER_LABELS, BANNER_TYPES, BOLD_ICON, BRACKET_CARD_CONTEXT, BRACKET_DATA_LAYOUT, BRACKET_DEFAULTS, BRACKET_DENSITY, BRACKET_DENSITY_PRESETS, BRACKET_ERROR_CODES, BRACKET_IMPORTS, BRACKET_LABELS, BRACKET_ROUND_MIRROR_TYPE, BRACKET_SWISS_GROUP_COLOR_TYPE, BREADCRUMB_COLLAPSE_IMPORTS, BREADCRUMB_COLLAPSE_TOKEN, BREADCRUMB_ERROR_CODES, BREADCRUMB_IMPORTS, BREADCRUMB_LABELS, BREADCRUMB_SEGMENT_TOKEN, BREADCRUMB_SEO_IMPORTS, BREADCRUMB_TOKEN, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BadgeComponent, BannerComponent, BracketComponent, BracketDefaultContinueComponent, BracketDefaultFinalMatchComponent, BracketDefaultMatchComponent, BracketDefaultRoundHeaderComponent, BracketMap, BracketRoundsListComponent, BrandLoaderComponent, BreadcrumbCollapseDirective, BreadcrumbComponent, BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbItemTemplateDirective, BreadcrumbOutletComponent, BreadcrumbOverflowComponent, BreadcrumbSegmentDirective, BreadcrumbSeoDirective, BreadcrumbSeparatorDirective, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CALENDAR_LABELS, CARD_IMPORTS, CARD_VARIANTS, CAROUSEL_AUTOPLAY_TOKEN, CAROUSEL_ERROR_CODES, CAROUSEL_IMPORTS, CAROUSEL_LABELS, CAROUSEL_SLIDE_ALIGNMENTS, CAROUSEL_TOKEN, CAROUSEL_TRANSITIONS, CAROUSEL_TRANSITION_DRIVERS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_LABELS, CASCADER_SELECTABLE_LEVELS, CHECKBOX_GROUP_IMPORTS, CHECKBOX_IMPORTS, CHECKBOX_OPTION_VARIANTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHIP_LABELS, CHOICE_FIELD_IMPORTS, CHOICE_FIELD_VARIANTS, CIRCLE_CHECK_ICON, CIRCLE_INFO_ICON, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_BLOCK_ICON, CODE_ICON, COLOR_INPUT_IMPORTS, COMMON_BRACKET_ROUND_TYPE, COPY_BUTTON_IMPORTS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CalendarHeaderDirective, CardComponent, CarouselAutoplayDirective, CarouselComponent, CarouselDirective, CarouselItemDirective, CarouselNextDirective, CarouselPlayToggleDirective, CarouselPreviousDirective, CarouselSlideDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxGroupSelectAllComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, ControlSuffixDirective, CopyButtonDirective, CounterComponent, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DATE_TIME_LABELS, DEFAULT_BANNER_LABELS, DEFAULT_BRACKET_LABELS, DEFAULT_BREADCRUMB_LABELS, DEFAULT_BREAKPOINTS, DEFAULT_CALENDAR_LABELS, DEFAULT_CALENDAR_RANGE_STRATEGY, DEFAULT_CAROUSEL_LABELS, DEFAULT_CASCADER_LABELS, DEFAULT_CHIP_LABELS, DEFAULT_DATE_TIME_LABELS, DEFAULT_DROPZONE_LABELS, DEFAULT_FILTER_OVERLAY_LABELS, DEFAULT_FORM_FIELD_LABELS, DEFAULT_GRID_LABELS, DEFAULT_ICON_VARIANT, DEFAULT_INPUT_LABELS, DEFAULT_LOADER_LABELS, DEFAULT_MATCH_CARD_START_TIME_FORMAT, DEFAULT_MATCH_LABELS, DEFAULT_NOTIFICATION_LABELS, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_NOTIFICATION_STATUS_ICONS, DEFAULT_PAGINATION_LABELS, DEFAULT_PHONE_INPUT_LABELS, DEFAULT_PIP_WINDOW_CONFIG, DEFAULT_QUERY_ERROR_LABELS, DEFAULT_RICH_TEXT_EDITOR_LABELS, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_SCHEDULER_LABELS, DEFAULT_SELECT_LABELS, DEFAULT_SLIDER_LABELS, DEFAULT_STANDINGS_LABELS, DEFAULT_STREAM_LABELS, DEFAULT_STREAM_PLAYER_STATE, DEFAULT_TABLE_LABELS, DEFAULT_TIME_PICKER_LABELS, DESCRIPTION_IMPORTS, DESCRIPTION_LIST_IMPORTS, DIVIDER_IMPORTS, DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DROPZONE_LABELS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DescriptionComponent, DescriptionListComponent, DividerComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ELLIPSIS_ICON, ELLIPSIS_VERTICAL_ICON, EMPTY_STATE_IMPORTS, ET_BUILT_IN_ICON_NAMES, EYE_ICON, EYE_SLASH_ICON, EmptyStateComponent, FACEBOOK_PLAYER_TOKEN, FILE_ICON, FILTER_ICON, FILTER_OVERLAY_ERROR_CODES, FILTER_OVERLAY_IMPORTS, FILTER_OVERLAY_LABELS, FILTER_OVERLAY_TOKEN, FLOATING_ACTION_ERROR_CODES, FLOATING_ACTION_IMPORTS, FLOATING_ACTION_STATES, FLOATING_ACTION_TOKEN, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABELS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FilterOverlayResetDirective, FilterOverlaySubmitDirective, FloatingActionAnchorDirective, FloatingActionDirective, FloatingActionScopeDirective, FloatingActionTopDirective, FloatingActionTriggerDirective, FocusRingDirective, FormErrorComponent, FormFieldBarrierDirective, FormFieldComponent, FormFieldDirective, GERMAN_FILTER_OVERLAY_LABELS, GERMAN_QUERY_ERROR_LABELS, GRID_2X2_ICON, GRID_DEBUG_IMPORTS, GRID_ERROR_CODES, GRID_IMPORTS, GRID_LABELS, GRID_TOKEN, GROUP_BRACKET_ROUND_TYPE, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemRef, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, IMAGE_ICON, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_LABELS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KBD_IMPORTS, KBD_PLATFORM, KICK_PLAYER_TOKEN, KbdComponent, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOADER_LABELS, LOCATION_ICON, LOCK_ICON, LabelDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MASONRY_ERROR_CODES, MASONRY_IMPORTS, MASONRY_TOKEN, MATCH_CARD_IMPORTS, MATCH_CARD_SIZES, MATCH_CARD_TOKEN, MATCH_ERROR_CODES, MATCH_LABELS, MATCH_PARTICIPANT_IMPORTS, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MasonryDirective, MasonryItemDirective, MatchCardComponent, MatchCardDirective, MatchCardGameScoresDirective, MatchCardMetaDirective, MatchCardScoreDirective, MatchParticipantComponent, MatchScoreComponent, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ACTION_SLOTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_LABELS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STATUS, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NotificationSwipeToDismissDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PAGE_SIZE_SELECT_IMPORTS, PAGINATION_IMPORTS, PAGINATION_LABELS, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PAUSE_ICON, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PHONE_INPUT_LABELS, PICTURE_IMPORTS, PICTURE_STATES, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLAY_ICON, PLUS_ICON, PROGRESS_STEPS_IMPORTS, PROGRESS_STEP_STATES, PageSizeSelectComponent, PaginationComponent, PaginationDirective, PaginationSeoDirective, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PictureComponent, PictureErrorDirective, PicturePlaceholderDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, ProgressStepComponent, ProgressStepsComponent, QUERY_DEVTOOLS_IMPORTS, QUERY_ERROR_ERROR_CODES, QUERY_ERROR_IMPORTS, QUERY_ERROR_LABELS, QUERY_ERROR_TOKEN, QUOTE_ICON, QueryDevtoolsComponent, QueryDevtoolsJsonComponent, QueryDevtoolsJsonStylesComponent, QueryDevtoolsTimelineStylesComponent, QueryDevtoolsToggleComponent, QueryErrorActionsDirective, QueryErrorComponent, QueryErrorDirective, QueryErrorTitleDirective, QueryParamOverlayLinkDirective, RADIO_GROUP_IMPORTS, RADIO_VARIANTS, RATING_IMPORTS, REDO_ICON, RICH_TEXT_EDITOR_FLOATING_TOOLBAR, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LABELS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_LINK_EDITOR, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorHeadingToolComponent, RichTextEditorImageEditorComponent, RichTextEditorImageStylesComponent, RichTextEditorImageToolComponent, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableStylesComponent, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, SCHEDULER_ADD_SURFACE_OVERLAY, SCHEDULER_EDIT_SURFACE_HOST, SCHEDULER_EDIT_SURFACE_OVERLAY, SCHEDULER_ERROR_CODES, SCHEDULER_FEATURE_HOST, SCHEDULER_IMPORTS, SCHEDULER_LABELS, SCROLLABLE_DARKEN_IMPORTS, SCROLLABLE_DRAG_IMPORTS, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SCROLLABLE_NAVIGATION_IMPORTS, SEGMENTED_BUTTON_GROUP_VARIANTS, SEGMENTED_BUTTON_IMPORTS, SELECTION_LIST_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SELECT_LABELS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SINGLE_ELIMINATION_BRACKET_ROUND_TYPE, SKELETON_IMPORTS, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_LABELS, SLIDER_MARK_VALUE_ATTRIBUTE, SLIDER_TOKEN, SNAP_HYSTERESIS, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STANDINGS_ERROR_CODES, STANDINGS_IMPORTS, STANDINGS_LABELS, STAR_ICON, STREAM_ALL_IMPORTS, STREAM_CONSENT_TOKEN, STREAM_DAILYMOTION_IMPORTS, STREAM_FACEBOOK_IMPORTS, STREAM_IMPORTS, STREAM_KICK_IMPORTS, STREAM_LABELS, STREAM_PIP_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_SOOP_IMPORTS, STREAM_TIKTOK_IMPORTS, STREAM_TWITCH_IMPORTS, STREAM_USER_CONSENT_PROVIDER_TOKEN, STREAM_VIMEO_IMPORTS, STREAM_YOUTUBE_IMPORTS, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWISS_BRACKET_ROUND_TYPE, SWITCH_IMPORTS, SchedulerActionAddAppointmentDirective, SchedulerActionAddSubAppointmentDirective, SchedulerActionDeleteDirective, SchedulerAgendaDirective, SchedulerAgendaViewComponent, SchedulerBadgeChainCountComponent, SchedulerBadgeChainCountDirective, SchedulerBadgeColorDotComponent, SchedulerBadgeColorDotDirective, SchedulerBadgeLocationComponent, SchedulerBadgeLocationDirective, SchedulerBadgeTimeRangeComponent, SchedulerBadgeTimeRangeDirective, SchedulerBadgeTitleComponent, SchedulerBadgeTitleDirective, SchedulerComponent, SchedulerDirective, SchedulerEditColorComponent, SchedulerEditColorDirective, SchedulerEditDescriptionComponent, SchedulerEditDescriptionDirective, SchedulerEditLocationComponent, SchedulerEditLocationDirective, SchedulerEditSurfaceComponent, SchedulerEditSurfaceDirective, SchedulerEditTimeRangeComponent, SchedulerEditTimeRangeDirective, SchedulerEditTitleComponent, SchedulerEditTitleDirective, SchedulerMonthDirective, SchedulerMonthViewComponent, SchedulerSwipeNavigationDirective, SchedulerTimeGridDirective, SchedulerTimeGridViewComponent, ScrollableActiveChildDirective, ScrollableButtonsComponent, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksComponent, ScrollableNavigationComponent, ScrollableNavigationDirective, ScrollableSnapDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SkeletonComponent, SkeletonItemComponent, SkeletonTextComponent, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StandingsComponent, StandingsDirective, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_CELL_ERROR_TOOLTIP_IMPORTS, TABLE_COLUMN_CHOOSER_IMPORTS, TABLE_COLUMN_MENU_IMPORTS, TABLE_CSV_EXPORT_IMPORTS, TABLE_ERROR_CODES, TABLE_FEATURE_HOST, TABLE_FILTER_IMPORTS, TABLE_GROUP_HEADERS_IMPORTS, TABLE_ICON, TABLE_IMPORTS, TABLE_INLINE_EDIT_IMPORTS, TABLE_KEYBOARD_NAV_IMPORTS, TABLE_LABELS, TABLE_REORDER_IMPORTS, TABLE_RESIZE_IMPORTS, TABLE_ROW_EXPANSION_IMPORTS, TABLE_SELECTION_IMPORTS, TABLE_SKELETON_IMPORTS, TABLE_STATE_PERSISTENCE_IMPORTS, TABLE_STICKY_COLUMNS_IMPORTS, TABLE_VIRTUAL_SCROLL_IMPORTS, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TIKTOK_PLAYER_TOKEN, TIMELINE_IMPORTS, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TIME_PICKER_LABELS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLBAR_IMPORTS, TOOLBAR_ORIENTATIONS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TOURNAMENT_MODE, TRASH_ICON, TREE_ERROR_CODES, TREE_IMPORTS, TREE_LEVEL_STATUSES, TREE_MARKERS, TREE_SELECTION_MODES, TRIANGLE_EXCLAMATION_ICON, TROPHY_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TableCellDirective, TableCellEditDirective, TableCellErrorMarkComponent, TableCellErrorTooltipDirective, TableCellSkeletonDirective, TableColumnChooserComponent, TableColumnMenuDirective, TableColumnMenuTriggerComponent, TableComponent, TableCsvExportDirective, TableDetailStylesComponent, TableExpanderCellComponent, TableFilterOptionDirective, TableFilterTriggerComponent, TableFiltersDirective, TableFooterCellDirective, TableFooterDirective, TableGroupHeaderRowComponent, TableGroupHeadersDirective, TableHeaderCellDirective, TableInlineEditDirective, TableInlineEditStylesComponent, TableKeyboardNavDirective, TableReorderDirective, TableReorderOverlayComponent, TableResizeDirective, TableResizeGripComponent, TableRowDetailComponent, TableRowExpansionDirective, TableSelectAllCellComponent, TableSelectCellComponent, TableSelectionDirective, TableSkeletonDirective, TableSkeletonRowsComponent, TableStatePersistenceDirective, TableStickyColumnsDirective, TableVirtualScrollDirective, TableVirtualScrollStylesComponent, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerColumnDirective, TimePickerComponent, TimePickerDirective, TimePickerOptionDirective, TimelineComponent, TimelineItemComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, ToolbarComponent, ToolbarDirective, TooltipComponent, TooltipDirective, TreeComponent, TreeDirective, TreeMarkerComponent, TreeNodeDefDirective, TreeNodeDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNDO_ICON, UNIT_MS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_SLOT_TOKEN, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, YoutubePlayerSlotDirective, abortFullscreenAnimation, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, autoPlace, bottomSheetOverlayStrategy, bracketFitsWidth, bracketNaturalWidth, buildAnchoredRuntimePositionStrategy, canHaveChildren, cascaderFromQuery, centeredOverlayStrategy, clampPosition, clampResizeRect, cleanupFullscreenAnimation, cleanupFullscreenAnimationStyles, compactLayout, computeGeometry, computeGridHeight, countDescendants, createAnchoredPanelController, createAutoScroller, createCardMask, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createFixedLengthRangeStrategy, createGridAdapter, createIbanMask, createNormalizedBracketMatch, createNotificationPromiseFn, createNotificationRef, createOverlayOpener, createOverlayRef, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createStreamConfig, createStreamPlayerSlot, createTableRowsSource, createTableStateStorage, createV2DropzoneUpload, createWeekRangeStrategy, defaultCompareWith$1 as defaultCompareWith, defaultDropzoneRejectionMessage, defineOverlay, defineQueryParamOverlay, deriveDurationFormatSpec, deserializeGridLayout, deserializeTableState, detectKbdPlatform, dialogOverlayStrategy, disposeDropzoneEntry, doubleEliminationBracketLayout, dropzoneFiles, enableDragToDismiss, extractFirstImageUrl, filterOverlayLabelsForLocale, filterOverlayPreviewFromQuery, filterRows, findCollision, findNextRelevantHtmlElement, findScrollableAncestor, formatDuration, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, generateBracketDataForEthlete, generateRoundTypeFromEthleteRoundType, generateTournamentModeFormEthleteRounds, getClosestOverlay, getOriginCoordinatesAndDimensions, hysteresisRound, iconRegistryKey, indexOfNode, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectBannerLabels, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectBracketConfig, injectBracketLabels, injectBreadcrumbLabels, injectBreadcrumbManager, injectCalendarLabels, injectCarouselLabels, injectCascaderLabels, injectChipLabels, injectDateFormat, injectDateLocale, injectDateTimeLabels, injectDialogStrategy, injectDialogStrategyDefaults, injectDropzoneLabels, injectFilterOverlay, injectFilterOverlayLabels, injectFormFieldLabels, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectGridLabels, injectInputLabels, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectLoaderLabels, injectMatchLabels, injectNotificationLabels, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPaginationLabels, injectPhoneInputLabels, injectPictureConfig, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectQueryErrorLabels, injectRichTextEditorLabels, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSchedulerEditSurfaceHost, injectSchedulerFeatureHost, injectSchedulerLabels, injectSelectLabels, injectSidebarOverlay, injectSliderLabels, injectStandingsLabels, injectStreamConfig, injectStreamConsentConfig, injectStreamLabels, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTableCsvExport, injectTableFeatureHost, injectTableLabels, injectTimeFormat, injectTimePickerLabels, injectTopSheetStrategy, injectTopSheetStrategyDefaults, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isTargetInsideOverlayTree, isTouchEvent, itemsCollide, kbdKeyLabel, kbdKeyName, kindOf, leftSheetOverlayStrategy, legacyQueryErrorSource, mapLayoutToBreakpoint, matchCountryByDialCode, matchParticipantDisplayName, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, mirroredDoubleEliminationBracketLayout, mirroredSingleEliminationBracketLayout, mountRichTextEditorImageStyles, mountRichTextEditorTableStyles, nodesEqual$1 as nodesEqual, normalizeEthleteBracketMatch, normalizeEthleteGroupRanking, normalizeEthleteMatch, normalizeEthleteMatchStatus, normalizeEthleteMedia, normalizeEthleteParticipant, normalizeEthletePlacement, normalizePictureSizes, normalizePictureSource, paginate, parseDuration, parseKbdKeys, phoneCountryFlag, phoneCountryName, pixelRectsEqual, positionToPixelRect, positionsEqual, projectDragCell, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideBannerLabels, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideBracketConfig, provideBracketLabels, provideBreadcrumbLabels, provideBreadcrumbManager, provideCalendarLabels, provideCarouselLabels, provideCascaderLabels, provideChipLabels, provideDateFormat, provideDateLocale, provideDateTimeLabels, provideDialogStrategy, provideDialogStrategyDefaults, provideDropzoneLabels, provideFilterOverlay, provideFilterOverlayLabels, provideFormErrorMessageResolver, provideFormFieldLabels, provideFormSupport, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideGridLabels, provideIconOverrides, provideIcons, provideInputLabels, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideLoaderLabels, provideMatchLabels, provideNotificationLabels, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePaginationLabels, providePhoneInputLabels, providePictureConfig, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideQueryErrorLabels, provideRichTextEditorAlignmentTool, provideRichTextEditorAutoformat, provideRichTextEditorBlockquoteTool, provideRichTextEditorCodeBlockTool, provideRichTextEditorDefaultTools, provideRichTextEditorFloatingToolbar, provideRichTextEditorHeadingTool, provideRichTextEditorImageTool, provideRichTextEditorLabels, provideRichTextEditorLanguageTool, provideRichTextEditorLinkEditor, provideRichTextEditorLinkTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSchedulerLabels, provideSelectLabels, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideSliderLabels, provideStandingsLabels, provideStreamConfig, provideStreamConsentConfig, provideStreamLabels, provideStreamManager, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTableLabels, provideTimeFormat, provideTimePickerLabels, provideTopSheetStrategy, provideTopSheetStrategyDefaults, queryErrorLabelsForLocale, queryErrorResponseFromLegacyError, reconcileColumnOrder, reconcileColumnWidths, reconcileHiddenColumns, reduceSupportPresentation, registerSingleton, requiredLanguages, resizeSpanBounds, resolveBracketLayout, resolveBreakpoint, resolveClosestOverlay, resolveCollisions, resolveFilterOverlaySubmitButton, resolveNotificationStatusIcon, resolveTableCsvRows, richTextEditorToolLabel, rightSheetOverlayStrategy, rowsToPixelHeight, schedulerFeatureConfig, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, serializeTableState, setupRichTextEditorFloatingToolbar, setupRichTextEditorLinkEditor, singleEliminationBracketLayout, snapResizeSpan, sortRows, spanHeight, spanWidth, startFullscreenEnterAnimation, startFullscreenLeaveAnimation, startImageUpload, startOfCalendarUnit, stripTrunkZero, supportPresentationIncludesState, swissBracketLayout, tableCsvRowsFromPages, tableFeatureConfig, tableRowsFromQuery, tableRowsFromV2Query, tableToCsv, toChildrenObservable$1 as toChildrenObservable, toGridPosition, toNotificationContent, toPathObservable, toSearchObservable, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, wireFormSupport, withPictureBaseUrl };
|
|
66771
67433
|
//# sourceMappingURL=ethlete-components.mjs.map
|