@cqa-lib/cqa-ui 1.1.509 → 1.1.511

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.
@@ -1,4 +1,4 @@
1
- import { EventEmitter, ElementRef, AfterViewInit, OnDestroy, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';
1
+ import { EventEmitter, QueryList, ElementRef, AfterViewInit, AfterViewChecked, OnDestroy, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core';
2
2
  import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
3
3
  import * as i0 from "@angular/core";
4
4
  export interface FastForwardConfig {
@@ -23,7 +23,7 @@ declare type SegmentOption = {
23
23
  value: string;
24
24
  icon?: string;
25
25
  };
26
- export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnChanges {
26
+ export declare class SimulatorComponent implements AfterViewInit, AfterViewChecked, OnDestroy, OnChanges {
27
27
  private sanitizer;
28
28
  private cdr;
29
29
  videoUrl: string;
@@ -52,12 +52,16 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
52
52
  browserDevice: string;
53
53
  isFastForwarding: boolean;
54
54
  fastForwardConfig: FastForwardConfig | null;
55
+ showVideoLibrary: boolean;
56
+ showCaptureVideo: boolean;
57
+ isCapturingVideo: boolean;
55
58
  get fastForwardProgressPercent(): number;
56
59
  videoTimeUpdate: EventEmitter<number>;
57
60
  videoPlay: EventEmitter<void>;
58
61
  videoPause: EventEmitter<void>;
59
62
  markerHit: EventEmitter<StepMarker>;
60
63
  isVideoPlayingChange: EventEmitter<boolean>;
64
+ captureVideoRequested: EventEmitter<void>;
61
65
  private _vplayer?;
62
66
  set vplayerRef(ref: ElementRef<HTMLVideoElement> | undefined);
63
67
  get vplayer(): ElementRef<HTMLVideoElement> | undefined;
@@ -83,6 +87,26 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
83
87
  private hitMarkers;
84
88
  private playerState;
85
89
  private operationQueue;
90
+ isVideoLibraryCollapsed: boolean;
91
+ newVideoIndexes: Set<number>;
92
+ libraryVideoDurations: Map<number, number>;
93
+ downloadingIndexes: Set<number>;
94
+ downloadProgress: Map<number, number>;
95
+ clipVideos?: QueryList<ElementRef<HTMLVideoElement>>;
96
+ clipsScrollerRef?: ElementRef<HTMLElement>;
97
+ private lastLibrarySyncKey;
98
+ private lastScrolledClipIndex;
99
+ videoRefreshing: boolean;
100
+ private pendingRecoverySeekSec;
101
+ private pendingRecoveryPlay;
102
+ private recoveryAttempts;
103
+ private recoveryAttemptWindowStart;
104
+ private readonly MAX_RECOVERY_ATTEMPTS;
105
+ private readonly RECOVERY_WINDOW_MS;
106
+ isVideoFullMode: boolean;
107
+ globalDragProgress: number;
108
+ private clipsDragState;
109
+ clipsDragActive: boolean;
86
110
  get effectivePlatformType(): 'browser' | 'device';
87
111
  get hasDeviceFrame(): boolean;
88
112
  get isPlayerSwitching(): boolean;
@@ -125,6 +149,8 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
125
149
  [key: string]: string;
126
150
  };
127
151
  ngAfterViewInit(): void;
152
+ ngAfterViewChecked(): void;
153
+ private syncLibraryClipPlayback;
128
154
  ngOnChanges(changes: SimpleChanges): void;
129
155
  ngOnDestroy(): void;
130
156
  /**
@@ -175,6 +201,17 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
175
201
  get currentVideoMarkers(): StepMarker[];
176
202
  private adjustChildStepsDuration;
177
203
  getStepLeftPosition(step: StepMarker): number;
204
+ /** Full-video markers: every marker, flattened, laid out on the global timeline.
205
+ * `stepMarkers` is already in global coordinates — `currentVideoMarkers` does the
206
+ * inverse (filters + adjusts per-clip); here we just flatten the original list. */
207
+ get fullVideoMarkers(): StepMarker[];
208
+ getGlobalFullStepLeftPosition(step: StepMarker): number;
209
+ /** Cumulative elapsed ms on the global timeline (prior clip durations + current local time). */
210
+ get globalCurrentTimeMs(): number;
211
+ /** 0-100 position on the global timeline, driven by timeupdate. */
212
+ get globalProgress(): number;
213
+ /** While dragging in full mode, the scrubber reads the override; otherwise globalProgress. */
214
+ get globalScrubberPercent(): number;
178
215
  getStepColor(step: StepMarker): string;
179
216
  getStepResultColor(step: StepMarker): string;
180
217
  getGlobalMarkerColor(level?: number): string;
@@ -199,6 +236,14 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
199
236
  private removeDragListeners;
200
237
  onVideoMetadataLoaded(): void;
201
238
  onVideoCanPlay(): void;
239
+ /** Native error-event handler for the main <video> element. The Chrome media
240
+ * stack occasionally throws "PipelineStatus::PIPELINE_ERROR_READ: FFmpegDemuxer:
241
+ * data source error" during playback after a brief network blip or a burst of
242
+ * fast user actions; once that happens the element becomes unresponsive to
243
+ * play/pause/seek. We recover by unmounting+remounting the <video> via *ngIf
244
+ * — the same mechanism that makes the Screenshots↔Video tab-switch workaround
245
+ * work today — then restore the pre-error playhead and resume playback. */
246
+ onVideoError(): void;
202
247
  onVideoEnded(): void;
203
248
  private attachVideoListeners;
204
249
  private schedulePreloadAllSegments;
@@ -230,6 +275,43 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
230
275
  toggleFullScreen(): void;
231
276
  onSegmentChange(value: string): void;
232
277
  formatTime(seconds: number): string;
278
+ captureVideo(): void;
279
+ onClipsMouseDown(event: MouseEvent, scroller: HTMLElement): void;
280
+ onClipsMouseMove(event: MouseEvent, scroller: HTMLElement): void;
281
+ onClipsMouseUp(_event: MouseEvent): void;
282
+ onClipsMouseLeave(event: MouseEvent): void;
283
+ /** Click handler on a Video Library card — switches the main player to that clip and auto-plays.
284
+ * Selecting a *different* clip also collapses the library so the newly-playing video is unobstructed;
285
+ * re-clicking the active clip just toggles play/pause and keeps the drawer state.
286
+ * Ignored when the click originated from a horizontal drag-scroll. */
287
+ selectLibraryClip(index: number): void;
288
+ /** Per-card metadata handler — caches duration so the `0:42` thumbnail label can render.
289
+ * Bound to BOTH `loadedmetadata` and `durationchange`:
290
+ * - Some MP4s (esp. short clips with moov at the end) report a wrong/partial duration
291
+ * on `loadedmetadata`; Chrome later corrects it via `durationchange`. Listening to
292
+ * both + keeping the max-so-far avoids stale wrong values like "00:01" for a 5s clip.
293
+ * - For streamed MP4s that report `Infinity`, seek to the end once so Chrome fetches
294
+ * the cues/trailer and fires a corrected `durationchange`. */
295
+ onLibraryClipMetadataLoaded(index: number, videoEl: HTMLVideoElement): void;
296
+ trackLibraryClipByIndex(index: number, url: string): string;
297
+ /** Download the clip at `index`. Streams the bytes with fetch so we can show progress,
298
+ * then saves via a temporary blob URL so the file comes down on the same page
299
+ * (no new tab / window). Falls back to a direct anchor click if fetch is unavailable or fails. */
300
+ downloadClip(index: number): Promise<void>;
301
+ private deriveClipFilename;
302
+ private saveBlobAsDownload;
303
+ /** Circumference of the 6-radius progress ring (see clip-download-btn__ring in template). */
304
+ readonly downloadRingCircumference: number;
305
+ /** stroke-dashoffset for the progress ring of clip `index`; 0 = full, circumference = empty. */
306
+ downloadRingDashoffset(index: number): number;
307
+ private triggerDirectDownload;
308
+ onShowFullVideo(): void;
309
+ onExitFullVideo(): void;
310
+ /** Horizontally scrolls the `.clips-row` so the currently-playing clip card is
311
+ * in the visible strip. No-op if the card is already on screen. Caller guards
312
+ * on `isPlaying` so the user can freely scroll the row while paused. */
313
+ private scrollCurrentClipIntoView;
314
+ toggleVideoLibraryCollapsed(): void;
233
315
  getStatusBadgeClass(): string;
234
316
  getStatusTextClass(): string;
235
317
  get processedTraceUrl(): string;
@@ -248,6 +330,6 @@ export declare class SimulatorComponent implements AfterViewInit, OnDestroy, OnC
248
330
  private switchToVideoAndSeek;
249
331
  private switchToVideoAndSeekInternal;
250
332
  static ɵfac: i0.ɵɵFactoryDeclaration<SimulatorComponent, never>;
251
- static ɵcmp: i0.ɵɵComponentDeclaration<SimulatorComponent, "cqa-simulator", never, { "videoUrl": "videoUrl"; "videoUrls": "videoUrls"; "videoCurrentDuration": "videoCurrentDuration"; "stepMarkers": "stepMarkers"; "screenShotUrl": "screenShotUrl"; "traceViewUrl": "traceViewUrl"; "platformName": "platformName"; "platformType": "platformType"; "platform": "platform"; "deviceName": "deviceName"; "isLive": "isLive"; "liveStatus": "liveStatus"; "liveLoadingLabel": "liveLoadingLabel"; "isContentVideoLoading": "isContentVideoLoading"; "failedStatusMessage": "failedStatusMessage"; "isVNCSessionIntruppted": "isVNCSessionIntruppted"; "vncSessionIntupptedMessage": "vncSessionIntupptedMessage"; "selectedView": "selectedView"; "hideVideoTab": "hideVideoTab"; "browserViewPort": "browserViewPort"; "browserDevice": "browserDevice"; "isFastForwarding": "isFastForwarding"; "fastForwardConfig": "fastForwardConfig"; }, { "videoTimeUpdate": "videoTimeUpdate"; "videoPlay": "videoPlay"; "videoPause": "videoPause"; "markerHit": "markerHit"; "isVideoPlayingChange": "isVideoPlayingChange"; }, never, ["*"]>;
333
+ static ɵcmp: i0.ɵɵComponentDeclaration<SimulatorComponent, "cqa-simulator", never, { "videoUrl": "videoUrl"; "videoUrls": "videoUrls"; "videoCurrentDuration": "videoCurrentDuration"; "stepMarkers": "stepMarkers"; "screenShotUrl": "screenShotUrl"; "traceViewUrl": "traceViewUrl"; "platformName": "platformName"; "platformType": "platformType"; "platform": "platform"; "deviceName": "deviceName"; "isLive": "isLive"; "liveStatus": "liveStatus"; "liveLoadingLabel": "liveLoadingLabel"; "isContentVideoLoading": "isContentVideoLoading"; "failedStatusMessage": "failedStatusMessage"; "isVNCSessionIntruppted": "isVNCSessionIntruppted"; "vncSessionIntupptedMessage": "vncSessionIntupptedMessage"; "selectedView": "selectedView"; "hideVideoTab": "hideVideoTab"; "browserViewPort": "browserViewPort"; "browserDevice": "browserDevice"; "isFastForwarding": "isFastForwarding"; "fastForwardConfig": "fastForwardConfig"; "showVideoLibrary": "showVideoLibrary"; "showCaptureVideo": "showCaptureVideo"; "isCapturingVideo": "isCapturingVideo"; }, { "videoTimeUpdate": "videoTimeUpdate"; "videoPlay": "videoPlay"; "videoPause": "videoPause"; "markerHit": "markerHit"; "isVideoPlayingChange": "isVideoPlayingChange"; "captureVideoRequested": "captureVideoRequested"; }, never, ["*"]>;
252
334
  }
253
335
  export {};
@@ -140,6 +140,8 @@ export declare class TestCaseDetailsEditComponent implements OnInit, OnChanges {
140
140
  apiMockingRestoreMockChange: EventEmitter<boolean>;
141
141
  /** Emitted when the user flips the "Renew and store API responses" toggle. */
142
142
  apiMockingStoreMockChange: EventEmitter<boolean>;
143
+ /** Emitted when the user clicks "Configure Mock APIs" on the embedded card in edit mode. */
144
+ configureApiMocking: EventEmitter<void>;
143
145
  constructor(cdr: ChangeDetectorRef);
144
146
  /** Form state */
145
147
  editDescription: string;
@@ -270,5 +272,5 @@ export declare class TestCaseDetailsEditComponent implements OnInit, OnChanges {
270
272
  };
271
273
  getLabelCloseIconColor(_label: string): string;
272
274
  static ɵfac: i0.ɵɵFactoryDeclaration<TestCaseDetailsEditComponent, never>;
273
- static ɵcmp: i0.ɵɵComponentDeclaration<TestCaseDetailsEditComponent, "cqa-test-case-details-edit", never, { "descriptionTitle": "descriptionTitle"; "descriptionContent": "descriptionContent"; "enableMarkdown": "enableMarkdown"; "metadataItems": "metadataItems"; "labels": "labels"; "configTitle": "configTitle"; "configSections": "configSections"; "configSectionsRow2": "configSectionsRow2"; "isSaving": "isSaving"; "prerequisiteCaseOptions": "prerequisiteCaseOptions"; "platform": "platform"; "isStepGroup": "isStepGroup"; "selectConfigOverrides": "selectConfigOverrides"; "showApiMockingCard": "showApiMockingCard"; "apiMockingTitle": "apiMockingTitle"; "apiMockingStatusLabel": "apiMockingStatusLabel"; "apiMockingCaptureLabel": "apiMockingCaptureLabel"; "apiMockingCaptureHint": "apiMockingCaptureHint"; "apiMockingRenewLabel": "apiMockingRenewLabel"; "apiMockingRenewHint": "apiMockingRenewHint"; "apiMockingRestoreMock": "apiMockingRestoreMock"; "apiMockingStoreMock": "apiMockingStoreMock"; "apiMockingMockedApisCount": "apiMockingMockedApisCount"; "apiMockingTotalApisCount": "apiMockingTotalApisCount"; "apiMockingProgressPercent": "apiMockingProgressPercent"; "apiMockingShowProgress": "apiMockingShowProgress"; "apiMockingSummaryText": "apiMockingSummaryText"; "apiMockingPercentText": "apiMockingPercentText"; "orgLevelTestCaseTimeout": "orgLevelTestCaseTimeout"; }, { "save": "save"; "cancel": "cancel"; "selectSearch": "selectSearch"; "selectLoadMore": "selectLoadMore"; "selectOpened": "selectOpened"; "selectionChange": "selectionChange"; "labelAdded": "labelAdded"; "apiMockingRestoreMockChange": "apiMockingRestoreMockChange"; "apiMockingStoreMockChange": "apiMockingStoreMockChange"; }, never, never>;
275
+ static ɵcmp: i0.ɵɵComponentDeclaration<TestCaseDetailsEditComponent, "cqa-test-case-details-edit", never, { "descriptionTitle": "descriptionTitle"; "descriptionContent": "descriptionContent"; "enableMarkdown": "enableMarkdown"; "metadataItems": "metadataItems"; "labels": "labels"; "configTitle": "configTitle"; "configSections": "configSections"; "configSectionsRow2": "configSectionsRow2"; "isSaving": "isSaving"; "prerequisiteCaseOptions": "prerequisiteCaseOptions"; "platform": "platform"; "isStepGroup": "isStepGroup"; "selectConfigOverrides": "selectConfigOverrides"; "showApiMockingCard": "showApiMockingCard"; "apiMockingTitle": "apiMockingTitle"; "apiMockingStatusLabel": "apiMockingStatusLabel"; "apiMockingCaptureLabel": "apiMockingCaptureLabel"; "apiMockingCaptureHint": "apiMockingCaptureHint"; "apiMockingRenewLabel": "apiMockingRenewLabel"; "apiMockingRenewHint": "apiMockingRenewHint"; "apiMockingRestoreMock": "apiMockingRestoreMock"; "apiMockingStoreMock": "apiMockingStoreMock"; "apiMockingMockedApisCount": "apiMockingMockedApisCount"; "apiMockingTotalApisCount": "apiMockingTotalApisCount"; "apiMockingProgressPercent": "apiMockingProgressPercent"; "apiMockingShowProgress": "apiMockingShowProgress"; "apiMockingSummaryText": "apiMockingSummaryText"; "apiMockingPercentText": "apiMockingPercentText"; "orgLevelTestCaseTimeout": "orgLevelTestCaseTimeout"; }, { "save": "save"; "cancel": "cancel"; "selectSearch": "selectSearch"; "selectLoadMore": "selectLoadMore"; "selectOpened": "selectOpened"; "selectionChange": "selectionChange"; "labelAdded": "labelAdded"; "apiMockingRestoreMockChange": "apiMockingRestoreMockChange"; "apiMockingStoreMockChange": "apiMockingStoreMockChange"; "configureApiMocking": "configureApiMocking"; }, never, never>;
274
276
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cqa-lib/cqa-ui",
3
- "version": "1.1.509",
3
+ "version": "1.1.511",
4
4
  "description": "UI Kit library for Angular 13.4",
5
5
  "keywords": [
6
6
  "angular",