UNPKG

@memberjunction/ng-ai-test-harness

Version:

MemberJunction AI Test Harness - A reusable component for testing AI agents and prompts with beautiful UX

125 lines 10.7 kB
import { Injectable, Component, createComponent } from '@angular/core'; import * as i0 from "@angular/core"; const _forTrack0 = ($index, $item) => $item.windowId; function WindowDockComponent_For_2_Template(rf, ctx) { if (rf & 1) { const _r1 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 2); i0.ɵɵlistener("click", function WindowDockComponent_For_2_Template_div_click_0_listener() { const item_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.restoreWindow(item_r2)); }); i0.ɵɵelement(1, "i"); i0.ɵɵelementStart(2, "span", 3); i0.ɵɵtext(3); i0.ɵɵelementEnd()(); } if (rf & 2) { const item_r2 = ctx.$implicit; const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵproperty("title", item_r2.title); i0.ɵɵadvance(); i0.ɵɵclassMap(item_r2.icon); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r2.getTruncatedTitle(item_r2.title)); } } export class WindowDockComponent { constructor() { this.dockItems = []; } addItem(item) { this.dockItems.push(item); } removeItem(windowId) { this.dockItems = this.dockItems.filter(item => item.windowId !== windowId); } restoreWindow(item) { item.restoreCallback(); this.removeItem(item.windowId); } getTruncatedTitle(title) { // Remove "Test: " prefix for the label to save space const cleanTitle = title.startsWith('Test: ') ? title.substring(6) : title; // Truncate to first 8 characters for the label return cleanTitle.length > 8 ? cleanTitle.substring(0, 8) + '...' : cleanTitle; } static { this.ɵfac = function WindowDockComponent_Factory(t) { return new (t || WindowDockComponent)(); }; } static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WindowDockComponent, selectors: [["mj-window-dock"]], standalone: true, features: [i0.ɵɵStandaloneFeature], decls: 3, vars: 0, consts: [[1, "window-dock"], [1, "dock-item", 3, "title"], [1, "dock-item", 3, "click", "title"], [1, "dock-item-label"]], template: function WindowDockComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 0); i0.ɵɵrepeaterCreate(1, WindowDockComponent_For_2_Template, 4, 4, "div", 1, _forTrack0); i0.ɵɵelementEnd(); } if (rf & 2) { i0.ɵɵadvance(); i0.ɵɵrepeater(ctx.dockItems); } }, styles: ["[_nghost-%COMP%] {\n position: fixed;\n bottom: 10px;\n right: 10px;\n z-index: 10001;\n }\n \n .window-dock[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n background: #f0f4f8;\n border: 1px solid #d0d8e0;\n border-radius: 8px;\n padding: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n \n .dock-item[_ngcontent-%COMP%] {\n width: 64px;\n height: 72px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n padding: 8px 4px;\n \n &:hover {\n background-color: rgba(255, 255, 255, 0.8);\n transform: translateY(-2px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 28px;\n color: #2c5282;\n }\n \n .dock-item-label {\n font-size: 11px;\n color: #4a5568;\n text-align: center;\n line-height: 1.2;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .dock-item-progress {\n position: absolute;\n bottom: 2px;\n left: 2px;\n right: 2px;\n height: 3px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 2px;\n overflow: hidden;\n }\n \n .dock-item-progress-bar {\n height: 100%;\n background: #0076B6; \n\n transition: width 0.3s ease;\n }\n \n \n\n .dock-item-progress-bar[style*=\"width: 50%\"] {\n animation: _ngcontent-%COMP%_pulse-progress 1.5s ease-in-out infinite;\n }\n }\n \n @keyframes _ngcontent-%COMP%_pulse-progress {\n 0% { opacity: 0.6; width: 30%; }\n 50% { opacity: 1; width: 70%; }\n 100% { opacity: 0.6; width: 30%; }\n }"] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WindowDockComponent, [{ type: Component, args: [{ selector: 'mj-window-dock', standalone: true, imports: [], template: ` <div class="window-dock"> @for (item of dockItems; track item.windowId) { <div class="dock-item" [title]="item.title" (click)="restoreWindow(item)"> <i [class]="item.icon"></i> <span class="dock-item-label">{{ getTruncatedTitle(item.title) }}</span> </div> } </div> `, styles: ["\n :host {\n position: fixed;\n bottom: 10px;\n right: 10px;\n z-index: 10001;\n }\n \n .window-dock {\n display: flex;\n gap: 12px;\n background: #f0f4f8;\n border: 1px solid #d0d8e0;\n border-radius: 8px;\n padding: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n }\n \n .dock-item {\n width: 64px;\n height: 72px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 4px;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n padding: 8px 4px;\n \n &:hover {\n background-color: rgba(255, 255, 255, 0.8);\n transform: translateY(-2px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n \n i {\n font-size: 28px;\n color: #2c5282;\n }\n \n .dock-item-label {\n font-size: 11px;\n color: #4a5568;\n text-align: center;\n line-height: 1.2;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n \n .dock-item-progress {\n position: absolute;\n bottom: 2px;\n left: 2px;\n right: 2px;\n height: 3px;\n background: rgba(0, 0, 0, 0.1);\n border-radius: 2px;\n overflow: hidden;\n }\n \n .dock-item-progress-bar {\n height: 100%;\n background: #0076B6; /* MJ blue color */\n transition: width 0.3s ease;\n }\n \n /* Pulse animation for indeterminate progress (50%) */\n .dock-item-progress-bar[style*=\"width: 50%\"] {\n animation: pulse-progress 1.5s ease-in-out infinite;\n }\n }\n \n @keyframes pulse-progress {\n 0% { opacity: 0.6; width: 30%; }\n 50% { opacity: 1; width: 70%; }\n 100% { opacity: 0.6; width: 30%; }\n }\n "] }] }], null, null); })(); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WindowDockComponent, { className: "WindowDockComponent", filePath: "lib/window-dock.service.ts", lineNumber: 111 }); })(); export class WindowDockService { constructor(appRef, injector) { this.appRef = appRef; this.injector = injector; } ensureDockExists() { if (!this.dockComponent) { // Create dock component this.dockComponent = createComponent(WindowDockComponent, { environmentInjector: this.appRef.injector, elementInjector: this.injector }); // Attach to DOM document.body.appendChild(this.dockComponent.location.nativeElement); this.appRef.attachView(this.dockComponent.hostView); } } addWindow(windowId, title, icon, restoreCallback, iconUrl, progress) { this.ensureDockExists(); if (this.dockComponent) { this.dockComponent.instance.addItem({ windowId, title, icon, iconUrl, restoreCallback: restoreCallback || (() => { }), progress }); } } removeWindow(windowId) { if (this.dockComponent) { this.dockComponent.instance.removeItem(windowId); // If no more items, remove the dock if (this.dockComponent.instance.dockItems.length === 0) { this.appRef.detachView(this.dockComponent.hostView); this.dockComponent.destroy(); this.dockComponent = undefined; } } } updateWindowProgress(windowId, progress) { if (this.dockComponent) { const item = this.dockComponent.instance.dockItems.find(i => i.windowId === windowId); if (item) { item.progress = progress; } } } static { this.ɵfac = function WindowDockService_Factory(t) { return new (t || WindowDockService)(i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.Injector)); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: WindowDockService, factory: WindowDockService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WindowDockService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [{ type: i0.ApplicationRef }, { type: i0.Injector }], null); })(); //# sourceMappingURL=window-dock.service.js.map