@memberjunction/ng-skip-chat 2.69.1 → 2.71.0

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.
@@ -9,7 +9,6 @@ import { DataContext } from '@memberjunction/data-context';
9
9
  import { CopyScalarsAndArrays, InvokeManualResize, MJEventType, MJGlobal, SafeJSONParse } from '@memberjunction/global';
10
10
  import { SkipSingleMessageComponent } from '../skip-single-message/skip-single-message.component';
11
11
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
12
- import { SkipReactComponentHost, GlobalComponentRegistry, registerExampleComponents, compileAndRegisterComponent } from '../dynamic-report/skip-react-component-host';
13
12
  import * as i0 from "@angular/core";
14
13
  import * as i1 from "@angular/router";
15
14
  import * as i2 from "@angular/common";
@@ -145,8 +144,7 @@ function SkipChatComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
145
144
  i0.ɵɵadvance();
146
145
  i0.ɵɵconditional(ctx_r2.AllowNewConversations ? 5 : -1);
147
146
  i0.ɵɵadvance();
148
- i0.ɵɵstyleProp("height", 280, "px");
149
- i0.ɵɵproperty("data", ctx_r2.Conversations)("itemClass", i0.ɵɵpureFunction0(6, _c8));
147
+ i0.ɵɵproperty("data", ctx_r2.Conversations)("itemClass", i0.ɵɵpureFunction0(4, _c8));
150
148
  } }
151
149
  function SkipChatComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
152
150
  const _r12 = i0.ɵɵgetCurrentView();
@@ -231,22 +229,22 @@ function SkipChatComponent_span_16_Template(rf, ctx) { if (rf & 1) {
231
229
  } }
232
230
  function SkipChatComponent_Conditional_17_Conditional_5_Template(rf, ctx) { if (rf & 1) {
233
231
  const _r16 = i0.ɵɵgetCurrentView();
234
- i0.ɵɵelementStart(0, "button", 64)(1, "span", 70);
232
+ i0.ɵɵelementStart(0, "button", 64)(1, "span", 68);
235
233
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_5_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showDataContextDialog()); });
236
234
  i0.ɵɵelementEnd()();
237
235
  } }
238
236
  function SkipChatComponent_Conditional_17_Conditional_6_Template(rf, ctx) { if (rf & 1) {
239
237
  const _r17 = i0.ɵɵgetCurrentView();
240
- i0.ɵɵelementStart(0, "button", 71);
238
+ i0.ɵɵelementStart(0, "button", 69);
241
239
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.stopProcessing()); });
242
- i0.ɵɵelement(1, "span", 72);
240
+ i0.ɵɵelement(1, "span", 70);
243
241
  i0.ɵɵelementEnd();
244
242
  } }
245
243
  function SkipChatComponent_Conditional_17_Conditional_7_Template(rf, ctx) { if (rf & 1) {
246
244
  const _r18 = i0.ɵɵgetCurrentView();
247
- i0.ɵɵelementStart(0, "button", 73);
245
+ i0.ɵɵelementStart(0, "button", 71);
248
246
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.sendSkipMessage()); });
249
- i0.ɵɵelement(1, "span", 74);
247
+ i0.ɵɵelement(1, "span", 72);
250
248
  i0.ɵɵelementEnd();
251
249
  } if (rf & 2) {
252
250
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -254,7 +252,7 @@ function SkipChatComponent_Conditional_17_Conditional_7_Template(rf, ctx) { if (
254
252
  } }
255
253
  function SkipChatComponent_Conditional_17_Conditional_8_Template(rf, ctx) { if (rf & 1) {
256
254
  const _r19 = i0.ɵɵgetCurrentView();
257
- i0.ɵɵelementStart(0, "button", 67)(1, "span", 75);
255
+ i0.ɵɵelementStart(0, "button", 67)(1, "span", 73);
258
256
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Conditional_8_Template_span_click_1_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.showSharingDialog()); });
259
257
  i0.ɵɵelementEnd()();
260
258
  } }
@@ -265,9 +263,7 @@ function SkipChatComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
265
263
  i0.ɵɵelementEnd()();
266
264
  i0.ɵɵelementStart(4, "div", 63);
267
265
  i0.ɵɵtemplate(5, SkipChatComponent_Conditional_17_Conditional_5_Template, 2, 0, "button", 64)(6, SkipChatComponent_Conditional_17_Conditional_6_Template, 2, 0, "button", 65)(7, SkipChatComponent_Conditional_17_Conditional_7_Template, 2, 1, "button", 66)(8, SkipChatComponent_Conditional_17_Conditional_8_Template, 2, 0, "button", 67);
268
- i0.ɵɵelementStart(9, "button", 68)(10, "span", 69);
269
- i0.ɵɵlistener("click", function SkipChatComponent_Conditional_17_Template_span_click_10_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.testButtonClick()); });
270
- i0.ɵɵelementEnd()()()();
266
+ i0.ɵɵelementEnd()();
271
267
  } if (rf & 2) {
272
268
  const ctx_r2 = i0.ɵɵnextContext();
273
269
  i0.ɵɵadvance(2);
@@ -283,7 +279,7 @@ function SkipChatComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
283
279
  } }
284
280
  function SkipChatComponent_skip_artifact_viewer_19_Template(rf, ctx) { if (rf & 1) {
285
281
  const _r20 = i0.ɵɵgetCurrentView();
286
- i0.ɵɵelementStart(0, "skip-artifact-viewer", 76);
282
+ i0.ɵɵelementStart(0, "skip-artifact-viewer", 74);
287
283
  i0.ɵɵlistener("NavigateToMatchingReport", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_NavigateToMatchingReport_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.NavigateToMatchingReport.emit($event)); })("NewReportCreated", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_NewReportCreated_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.NewReportCreated.emit($event)); })("DrillDownEvent", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_DrillDownEvent_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.DrillDownEvent.emit($event)); })("ArtifactInfoChanged", function SkipChatComponent_skip_artifact_viewer_19_Template_skip_artifact_viewer_ArtifactInfoChanged_0_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactInfoChanged($event)); });
288
284
  i0.ɵɵelementEnd();
289
285
  } if (rf & 2) {
@@ -292,7 +288,7 @@ function SkipChatComponent_skip_artifact_viewer_19_Template(rf, ctx) { if (rf &
292
288
  } }
293
289
  function SkipChatComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
294
290
  const _r21 = i0.ɵɵgetCurrentView();
295
- i0.ɵɵelementStart(0, "mj-data-context-dialog", 77);
291
+ i0.ɵɵelementStart(0, "mj-data-context-dialog", 75);
296
292
  i0.ɵɵlistener("dialogClosed", function SkipChatComponent_Conditional_20_Template_mj_data_context_dialog_dialogClosed_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDataContextDialog()); });
297
293
  i0.ɵɵelementEnd();
298
294
  } if (rf & 2) {
@@ -301,14 +297,14 @@ function SkipChatComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
301
297
  } }
302
298
  function SkipChatComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
303
299
  const _r22 = i0.ɵɵgetCurrentView();
304
- i0.ɵɵelementStart(0, "kendo-dialog", 78);
300
+ i0.ɵɵelementStart(0, "kendo-dialog", 76);
305
301
  i0.ɵɵlistener("close", function SkipChatComponent_Conditional_21_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("no")); });
306
- i0.ɵɵelement(1, "mj-resource-permissions", 79, 6);
307
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 80);
302
+ i0.ɵɵelement(1, "mj-resource-permissions", 77, 6);
303
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
308
304
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_21_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("yes")); });
309
305
  i0.ɵɵtext(5, " Save ");
310
306
  i0.ɵɵelementEnd();
311
- i0.ɵɵelementStart(6, "button", 81);
307
+ i0.ɵɵelementStart(6, "button", 79);
312
308
  i0.ɵɵlistener("click", function SkipChatComponent_Conditional_21_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeSharingDialog("no")); });
313
309
  i0.ɵɵtext(7, " Cancel ");
314
310
  i0.ɵɵelementEnd()()();
@@ -320,16 +316,16 @@ function SkipChatComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
320
316
  } }
321
317
  function SkipChatComponent_kendo_dialog_22_Template(rf, ctx) { if (rf & 1) {
322
318
  const _r23 = i0.ɵɵgetCurrentView();
323
- i0.ɵɵelementStart(0, "kendo-dialog", 82);
319
+ i0.ɵɵelementStart(0, "kendo-dialog", 80);
324
320
  i0.ɵɵlistener("close", function SkipChatComponent_kendo_dialog_22_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("no")); });
325
- i0.ɵɵelementStart(1, "p", 83);
321
+ i0.ɵɵelementStart(1, "p", 81);
326
322
  i0.ɵɵtext(2);
327
323
  i0.ɵɵelementEnd();
328
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 80);
324
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
329
325
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_22_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("yes")); });
330
326
  i0.ɵɵtext(5, " Yes ");
331
327
  i0.ɵɵelementEnd();
332
- i0.ɵɵelementStart(6, "button", 81);
328
+ i0.ɵɵelementStart(6, "button", 79);
333
329
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_22_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r23); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeDeleteConversation("no")); });
334
330
  i0.ɵɵtext(7, " No ");
335
331
  i0.ɵɵelementEnd()()();
@@ -341,16 +337,16 @@ function SkipChatComponent_kendo_dialog_22_Template(rf, ctx) { if (rf & 1) {
341
337
  } }
342
338
  function SkipChatComponent_kendo_dialog_23_Template(rf, ctx) { if (rf & 1) {
343
339
  const _r24 = i0.ɵɵgetCurrentView();
344
- i0.ɵɵelementStart(0, "kendo-dialog", 82);
340
+ i0.ɵɵelementStart(0, "kendo-dialog", 80);
345
341
  i0.ɵɵlistener("close", function SkipChatComponent_kendo_dialog_23_Template_kendo_dialog_close_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("no")); });
346
- i0.ɵɵelementStart(1, "p", 83);
342
+ i0.ɵɵelementStart(1, "p", 81);
347
343
  i0.ɵɵtext(2);
348
344
  i0.ɵɵelementEnd();
349
- i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 80);
345
+ i0.ɵɵelementStart(3, "kendo-dialog-actions")(4, "button", 78);
350
346
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_23_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("yes")); });
351
347
  i0.ɵɵtext(5, " Yes ");
352
348
  i0.ɵɵelementEnd();
353
- i0.ɵɵelementStart(6, "button", 81);
349
+ i0.ɵɵelementStart(6, "button", 79);
354
350
  i0.ɵɵlistener("click", function SkipChatComponent_kendo_dialog_23_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.closeMessageEditOrDeleteDialog("no")); });
355
351
  i0.ɵɵtext(7, " No ");
356
352
  i0.ɵɵelementEnd()()();
@@ -2303,34 +2299,6 @@ export class SkipChatComponent extends BaseAngularComponent {
2303
2299
  await new Promise(resolve => setTimeout(resolve, 100));
2304
2300
  attempts++;
2305
2301
  }
2306
- // Register the pre-built example components
2307
- if (window.React) {
2308
- console.log('React is available, registering pre-built components...');
2309
- console.log('Babel available:', !!window.Babel);
2310
- console.log('Chart available:', !!window.Chart);
2311
- try {
2312
- const registered = await registerExampleComponents(window.React, window.Chart);
2313
- if (registered) {
2314
- console.log('Pre-built components registered successfully');
2315
- // Mark these as pre-built so we don't try to re-register them
2316
- this.registeredTestComponents.set('ActionBrowser', { componentName: 'ActionBrowser', prebuilt: true });
2317
- this.registeredTestComponents.set('SearchBox', { componentName: 'SearchBox', prebuilt: true });
2318
- this.registeredTestComponents.set('CategoryChart', { componentName: 'CategoryChart', prebuilt: true });
2319
- // Verify registration
2320
- const registry = GlobalComponentRegistry.Instance;
2321
- console.log('Registry keys after registration:', registry.getRegisteredKeys());
2322
- }
2323
- else {
2324
- console.error('Failed to register pre-built components');
2325
- }
2326
- }
2327
- catch (error) {
2328
- console.error('Error during component registration:', error);
2329
- }
2330
- }
2331
- else {
2332
- console.error('React not available for component registration');
2333
- }
2334
2302
  }
2335
2303
  getRequiredChildComponents(componentName) {
2336
2304
  // For pre-built components, return their specific dependencies
@@ -2352,624 +2320,6 @@ export class SkipChatComponent extends BaseAngularComponent {
2352
2320
  }
2353
2321
  }
2354
2322
  }
2355
- /**
2356
- * Process a SkipComponentRootSpec and register all components recursively
2357
- */
2358
- async processSkipComponentSpec(spec) {
2359
- const errors = [];
2360
- const registeredComponents = [];
2361
- try {
2362
- // Register root component (plain function, auto-wrapped)
2363
- const rootComponentName = spec.componentName;
2364
- const success = await compileAndRegisterComponent(rootComponentName, spec.componentCode, 'Global', // Use Global context for all test components
2365
- 'v1');
2366
- if (success) {
2367
- registeredComponents.push(rootComponentName);
2368
- this.registeredTestComponents.set(rootComponentName, spec);
2369
- }
2370
- else {
2371
- errors.push(`Failed to register root component: ${rootComponentName}`);
2372
- }
2373
- // Recursively register child components (plain functions, auto-wrapped)
2374
- if (spec.childComponents && Array.isArray(spec.childComponents)) {
2375
- for (const child of spec.childComponents) {
2376
- await this.registerComponentHierarchy(child, registeredComponents, errors);
2377
- }
2378
- }
2379
- return {
2380
- success: errors.length === 0,
2381
- rootComponentName,
2382
- registeredComponents,
2383
- errors
2384
- };
2385
- }
2386
- catch (error) {
2387
- errors.push(`Error processing spec: ${error.message}`);
2388
- return {
2389
- success: false,
2390
- rootComponentName: spec.componentName || 'Unknown',
2391
- registeredComponents,
2392
- errors
2393
- };
2394
- }
2395
- }
2396
- /**
2397
- * Recursively register child components
2398
- */
2399
- async registerComponentHierarchy(spec, registeredComponents, errors) {
2400
- try {
2401
- if (spec.componentCode) {
2402
- // Child components are plain functions, auto-wrapped
2403
- const success = await compileAndRegisterComponent(spec.componentName, spec.componentCode, 'Global', // Use Global context for all test components
2404
- 'v1');
2405
- if (success) {
2406
- registeredComponents.push(spec.componentName);
2407
- }
2408
- else {
2409
- errors.push(`Failed to register component: ${spec.componentName}`);
2410
- }
2411
- }
2412
- // Process nested children
2413
- const childArray = spec.childComponents || spec.components || [];
2414
- for (const child of childArray) {
2415
- await this.registerComponentHierarchy(child, registeredComponents, errors);
2416
- }
2417
- }
2418
- catch (error) {
2419
- errors.push(`Error registering ${spec.componentName}: ${error.message}`);
2420
- }
2421
- }
2422
- /**
2423
- * TEMPORARY TEST METHOD - Handle test button click
2424
- */
2425
- async testButtonClick() {
2426
- console.log('Test button clicked - Opening Component Tester');
2427
- // If dialog already exists, just show it
2428
- if (this.componentTesterDialog) {
2429
- return;
2430
- }
2431
- // Create the dialog container directly in the DOM
2432
- const dialogContainer = document.createElement('div');
2433
- dialogContainer.style.position = 'fixed';
2434
- dialogContainer.style.top = '50%';
2435
- dialogContainer.style.left = '50%';
2436
- dialogContainer.style.transform = 'translate(-50%, -50%)';
2437
- dialogContainer.style.width = '90vw';
2438
- dialogContainer.style.maxWidth = '1400px';
2439
- dialogContainer.style.height = '85vh';
2440
- dialogContainer.style.backgroundColor = 'white';
2441
- dialogContainer.style.boxShadow = '0 4px 20px rgba(0,0,0,0.3)';
2442
- dialogContainer.style.borderRadius = '8px';
2443
- dialogContainer.style.zIndex = '10000';
2444
- dialogContainer.style.display = 'flex';
2445
- dialogContainer.style.flexDirection = 'column';
2446
- // Create header
2447
- const header = document.createElement('div');
2448
- header.style.padding = '16px 20px';
2449
- header.style.borderBottom = '1px solid #e0e0e0';
2450
- header.style.display = 'flex';
2451
- header.style.justifyContent = 'space-between';
2452
- header.style.alignItems = 'center';
2453
- header.style.backgroundColor = '#f5f5f5';
2454
- header.style.borderRadius = '8px 8px 0 0';
2455
- const title = document.createElement('h3');
2456
- title.textContent = 'Skip Component Tester';
2457
- title.style.margin = '0';
2458
- title.style.fontSize = '18px';
2459
- title.style.fontWeight = '600';
2460
- const closeButton = document.createElement('button');
2461
- closeButton.innerHTML = '×';
2462
- closeButton.style.fontSize = '28px';
2463
- closeButton.style.border = 'none';
2464
- closeButton.style.background = 'none';
2465
- closeButton.style.cursor = 'pointer';
2466
- closeButton.style.padding = '0';
2467
- closeButton.style.width = '32px';
2468
- closeButton.style.height = '32px';
2469
- closeButton.style.lineHeight = '1';
2470
- closeButton.onclick = () => {
2471
- // Clean up splitter event listeners
2472
- if (testerContent.refs.splitter && testerContent.refs.splitter.cleanup) {
2473
- testerContent.refs.splitter.cleanup();
2474
- }
2475
- document.body.removeChild(dialogContainer);
2476
- document.body.removeChild(backdrop);
2477
- // Clear test components from registry
2478
- this.registeredTestComponents.forEach((spec, name) => {
2479
- if (!spec.prebuilt) {
2480
- // Only remove user-added components, not pre-built ones
2481
- GlobalComponentRegistry.Instance.remove(`${name}_Global_v1`);
2482
- }
2483
- });
2484
- this.registeredTestComponents.clear();
2485
- this.componentTesterDialog = null;
2486
- };
2487
- header.appendChild(title);
2488
- header.appendChild(closeButton);
2489
- // Create backdrop
2490
- const backdrop = document.createElement('div');
2491
- backdrop.style.position = 'fixed';
2492
- backdrop.style.top = '0';
2493
- backdrop.style.left = '0';
2494
- backdrop.style.right = '0';
2495
- backdrop.style.bottom = '0';
2496
- backdrop.style.backgroundColor = 'rgba(0,0,0,0.5)';
2497
- backdrop.style.zIndex = '9999';
2498
- // Create the component tester content
2499
- const testerContent = this.createComponentTesterContent();
2500
- testerContent.element.style.flex = '1';
2501
- testerContent.element.style.overflow = 'hidden';
2502
- dialogContainer.appendChild(header);
2503
- dialogContainer.appendChild(testerContent.element);
2504
- // Add to DOM
2505
- document.body.appendChild(backdrop);
2506
- document.body.appendChild(dialogContainer);
2507
- // Store reference for cleanup
2508
- this.componentTesterDialog = { close: () => closeButton.click() };
2509
- // Initialize code editor and other functionality
2510
- setTimeout(() => {
2511
- this.initializeComponentTester(testerContent);
2512
- }, 100);
2513
- }
2514
- createComponentTesterContent() {
2515
- const container = document.createElement('div');
2516
- container.style.height = '100%';
2517
- container.style.display = 'flex';
2518
- container.style.flexDirection = 'column';
2519
- // Header with controls
2520
- const header = document.createElement('div');
2521
- header.style.padding = '16px';
2522
- header.style.borderBottom = '1px solid #e0e0e0';
2523
- header.style.display = 'flex';
2524
- header.style.gap = '16px';
2525
- header.style.alignItems = 'center';
2526
- // Component selector dropdown
2527
- const selectorLabel = document.createElement('label');
2528
- selectorLabel.textContent = 'Component: ';
2529
- selectorLabel.style.fontWeight = 'bold';
2530
- const componentSelector = document.createElement('select');
2531
- componentSelector.style.padding = '8px';
2532
- componentSelector.style.borderRadius = '4px';
2533
- componentSelector.style.border = '1px solid #ccc';
2534
- componentSelector.style.minWidth = '200px';
2535
- // Add default option
2536
- const defaultOption = document.createElement('option');
2537
- defaultOption.value = '';
2538
- defaultOption.textContent = 'Select a component...';
2539
- componentSelector.appendChild(defaultOption);
2540
- // Add new component button
2541
- const addNewBtn = document.createElement('button');
2542
- addNewBtn.textContent = 'Add New Component';
2543
- addNewBtn.className = 'k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary';
2544
- addNewBtn.style.marginLeft = 'auto';
2545
- // Parse & Register button
2546
- const parseBtn = document.createElement('button');
2547
- parseBtn.textContent = 'Parse & Register';
2548
- parseBtn.className = 'k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary';
2549
- parseBtn.disabled = true;
2550
- // Clear button
2551
- const clearBtn = document.createElement('button');
2552
- clearBtn.textContent = 'Clear All';
2553
- clearBtn.className = 'k-button k-button-md k-rounded-md k-button-solid k-button-solid-base';
2554
- header.appendChild(selectorLabel);
2555
- header.appendChild(componentSelector);
2556
- header.appendChild(parseBtn);
2557
- header.appendChild(clearBtn);
2558
- header.appendChild(addNewBtn);
2559
- // Main content area with split view
2560
- const content = document.createElement('div');
2561
- content.style.flex = '1';
2562
- content.style.display = 'flex';
2563
- content.style.overflow = 'hidden';
2564
- content.style.position = 'relative';
2565
- // Get saved splitter position from local storage
2566
- const savedPosition = localStorage.getItem('skipComponentTesterSplitterPosition');
2567
- const leftWidth = savedPosition ? parseFloat(savedPosition) : 50;
2568
- const rightWidth = 100 - leftWidth;
2569
- // Left panel - Code editor
2570
- const leftPanel = document.createElement('div');
2571
- leftPanel.style.width = `${leftWidth}%`;
2572
- leftPanel.style.display = 'flex';
2573
- leftPanel.style.flexDirection = 'column';
2574
- leftPanel.style.minWidth = '200px';
2575
- const editorLabel = document.createElement('div');
2576
- editorLabel.style.padding = '8px 16px';
2577
- editorLabel.style.backgroundColor = '#f5f5f5';
2578
- editorLabel.style.borderBottom = '1px solid #e0e0e0';
2579
- editorLabel.innerHTML = '<strong>JSON Input (SkipComponentRootSpec)</strong>';
2580
- const editorContainer = document.createElement('div');
2581
- editorContainer.style.flex = '1';
2582
- editorContainer.style.position = 'relative';
2583
- leftPanel.appendChild(editorLabel);
2584
- leftPanel.appendChild(editorContainer);
2585
- // Splitter handle
2586
- const splitter = document.createElement('div');
2587
- splitter.style.width = '6px';
2588
- splitter.style.backgroundColor = '#e0e0e0';
2589
- splitter.style.cursor = 'col-resize';
2590
- splitter.style.position = 'relative';
2591
- splitter.style.userSelect = 'none';
2592
- // Add hover effect
2593
- splitter.onmouseenter = () => {
2594
- splitter.style.backgroundColor = '#c0c0c0';
2595
- };
2596
- splitter.onmouseleave = () => {
2597
- if (!isDragging) {
2598
- splitter.style.backgroundColor = '#e0e0e0';
2599
- }
2600
- };
2601
- // Right panel - Component preview
2602
- const rightPanel = document.createElement('div');
2603
- rightPanel.style.width = `${rightWidth}%`;
2604
- rightPanel.style.display = 'flex';
2605
- rightPanel.style.flexDirection = 'column';
2606
- rightPanel.style.minWidth = '200px';
2607
- const previewLabel = document.createElement('div');
2608
- previewLabel.style.padding = '8px 16px';
2609
- previewLabel.style.backgroundColor = '#f5f5f5';
2610
- previewLabel.style.borderBottom = '1px solid #e0e0e0';
2611
- previewLabel.innerHTML = '<strong>Component Preview</strong>';
2612
- const previewContainer = document.createElement('div');
2613
- previewContainer.style.flex = '1';
2614
- previewContainer.style.overflow = 'auto';
2615
- previewContainer.style.padding = '16px';
2616
- rightPanel.appendChild(previewLabel);
2617
- rightPanel.appendChild(previewContainer);
2618
- // Add splitter drag functionality
2619
- let isDragging = false;
2620
- let startX = 0;
2621
- let startLeftWidth = 0;
2622
- const handleMouseDown = (e) => {
2623
- isDragging = true;
2624
- startX = e.pageX;
2625
- startLeftWidth = leftPanel.offsetWidth;
2626
- splitter.style.backgroundColor = '#a0a0a0';
2627
- // Prevent text selection during drag
2628
- document.body.style.userSelect = 'none';
2629
- document.body.style.cursor = 'col-resize';
2630
- e.preventDefault();
2631
- };
2632
- const handleMouseMove = (e) => {
2633
- if (!isDragging)
2634
- return;
2635
- const containerWidth = content.offsetWidth;
2636
- const deltaX = e.pageX - startX;
2637
- const newLeftWidth = startLeftWidth + deltaX;
2638
- const newLeftPercent = (newLeftWidth / containerWidth) * 100;
2639
- // Limit the splitter position (20% to 80%)
2640
- if (newLeftPercent >= 20 && newLeftPercent <= 80) {
2641
- leftPanel.style.width = `${newLeftPercent}%`;
2642
- rightPanel.style.width = `${100 - newLeftPercent}%`;
2643
- }
2644
- };
2645
- const handleMouseUp = () => {
2646
- if (!isDragging)
2647
- return;
2648
- isDragging = false;
2649
- splitter.style.backgroundColor = '#e0e0e0';
2650
- document.body.style.userSelect = '';
2651
- document.body.style.cursor = '';
2652
- // Save position to local storage
2653
- const containerWidth = content.offsetWidth;
2654
- const leftPercent = (leftPanel.offsetWidth / containerWidth) * 100;
2655
- localStorage.setItem('skipComponentTesterSplitterPosition', leftPercent.toString());
2656
- };
2657
- splitter.addEventListener('mousedown', handleMouseDown);
2658
- document.addEventListener('mousemove', handleMouseMove);
2659
- document.addEventListener('mouseup', handleMouseUp);
2660
- // Clean up event listeners when dialog is closed
2661
- splitter.cleanup = () => {
2662
- document.removeEventListener('mousemove', handleMouseMove);
2663
- document.removeEventListener('mouseup', handleMouseUp);
2664
- };
2665
- // Error display area
2666
- const errorContainer = document.createElement('div');
2667
- errorContainer.style.display = 'none';
2668
- errorContainer.style.padding = '16px';
2669
- errorContainer.style.backgroundColor = '#fee';
2670
- errorContainer.style.color = '#c00';
2671
- errorContainer.style.borderTop = '1px solid #fcc';
2672
- errorContainer.style.maxHeight = '150px';
2673
- errorContainer.style.overflow = 'auto';
2674
- content.appendChild(leftPanel);
2675
- content.appendChild(splitter);
2676
- content.appendChild(rightPanel);
2677
- container.appendChild(header);
2678
- container.appendChild(content);
2679
- container.appendChild(errorContainer);
2680
- return {
2681
- element: container,
2682
- refs: {
2683
- componentSelector,
2684
- addNewBtn,
2685
- parseBtn,
2686
- clearBtn,
2687
- editorContainer,
2688
- previewContainer,
2689
- errorContainer,
2690
- splitter
2691
- }
2692
- };
2693
- }
2694
- async initializeComponentTester(testerContent) {
2695
- const { componentSelector, addNewBtn, parseBtn, clearBtn, editorContainer, previewContainer, errorContainer } = testerContent.refs;
2696
- let currentHost = null;
2697
- let codeEditorValue = '';
2698
- // First, ensure React and other libraries are loaded by creating a temporary host
2699
- const tempContainer = document.createElement('div');
2700
- tempContainer.style.display = 'none';
2701
- document.body.appendChild(tempContainer);
2702
- // this is done to get React loaded
2703
- const tempSpec = {
2704
- componentCode: 'function TempComponent() {};',
2705
- componentName: 'TempComponent',
2706
- functionalRequirements: 'Load React and other libraries',
2707
- technicalDesign: 'Temporary component to load libraries',
2708
- componentType: 'report',
2709
- title: 'Temporary Component',
2710
- description: 'This component is used to load React and other libraries for testing purposes',
2711
- callbackStrategy: 'none',
2712
- childComponents: [],
2713
- stateStructure: {},
2714
- userExplanation: 'This component is used to load React and other libraries for testing purposes',
2715
- techExplanation: 'This component is used to load React and other libraries for testing purposes'
2716
- };
2717
- const tempHost = new SkipReactComponentHost({
2718
- component: tempSpec,
2719
- container: tempContainer,
2720
- data: {},
2721
- metadata: { requiredChildComponents: [], componentContext: 'Global', version: 'v1' }
2722
- });
2723
- try {
2724
- await tempHost.initialize();
2725
- console.log('Libraries loaded via temporary host');
2726
- }
2727
- catch (error) {
2728
- console.error('Error loading libraries:', error);
2729
- }
2730
- finally {
2731
- tempHost.destroy();
2732
- document.body.removeChild(tempContainer);
2733
- }
2734
- // Now register the pre-built test components
2735
- await this.registerPrebuiltComponents();
2736
- // Add pre-built components to dropdown
2737
- const prebuiltComponents = [
2738
- { name: 'ActionBrowser', label: 'Action Browser (Pre-built)' },
2739
- { name: 'SearchBox', label: 'Search Box (Pre-built)' },
2740
- { name: 'CategoryChart', label: 'Category Chart (Pre-built)' }
2741
- ];
2742
- for (const comp of prebuiltComponents) {
2743
- const option = document.createElement('option');
2744
- option.value = comp.name;
2745
- option.textContent = comp.label;
2746
- componentSelector.appendChild(option);
2747
- // Ensure pre-built components are marked as such in our tracking map
2748
- if (!this.registeredTestComponents.has(comp.name)) {
2749
- this.registeredTestComponents.set(comp.name, { componentName: comp.name, prebuilt: true });
2750
- }
2751
- }
2752
- // Create a textarea for now instead of the Angular component
2753
- const codeEditor = document.createElement('textarea');
2754
- codeEditor.style.width = '100%';
2755
- codeEditor.style.height = '100%';
2756
- codeEditor.style.fontFamily = 'monospace';
2757
- codeEditor.style.fontSize = '13px';
2758
- codeEditor.style.border = 'none';
2759
- codeEditor.style.outline = 'none';
2760
- codeEditor.style.resize = 'none';
2761
- codeEditor.style.padding = '16px';
2762
- codeEditor.style.backgroundColor = '#f5f5f5';
2763
- // Listen for value changes
2764
- codeEditor.addEventListener('input', (event) => {
2765
- codeEditorValue = event.target.value;
2766
- parseBtn.disabled = !codeEditorValue.trim();
2767
- });
2768
- editorContainer.appendChild(codeEditor);
2769
- // Set initial value with example
2770
- const exampleSpec = {
2771
- componentName: "ExampleComponent",
2772
- componentType: "report",
2773
- title: "Example Component",
2774
- description: "An example component",
2775
- functionalRequirements: "Display hello world",
2776
- technicalDesign: "Simple React component",
2777
- callbackStrategy: "none",
2778
- stateStructure: {},
2779
- childComponents: [],
2780
- userExplanation: "Shows hello world",
2781
- techExplanation: "React createElement",
2782
- componentCode: `
2783
- function createComponent(React) {
2784
- const Component = () => {
2785
- return React.createElement('div', {
2786
- style: { padding: '20px', fontSize: '18px' }
2787
- }, 'Hello from Skip Component!');
2788
- };
2789
- return { component: Component };
2790
- }
2791
- `
2792
- };
2793
- setTimeout(() => {
2794
- codeEditor.value = JSON.stringify(exampleSpec, null, 2);
2795
- codeEditorValue = JSON.stringify(exampleSpec, null, 2);
2796
- parseBtn.disabled = false;
2797
- }, 200);
2798
- // Handle component selection
2799
- componentSelector.addEventListener('change', async () => {
2800
- const selectedName = componentSelector.value;
2801
- if (!selectedName) {
2802
- if (currentHost) {
2803
- currentHost.destroy();
2804
- currentHost = null;
2805
- }
2806
- previewContainer.innerHTML = '<div style="color: #666; text-align: center; padding: 40px;">Select a component to preview</div>';
2807
- return;
2808
- }
2809
- // Wait a bit to ensure components are registered
2810
- await new Promise(resolve => setTimeout(resolve, 100));
2811
- // Debug: Check registry state
2812
- const registry = GlobalComponentRegistry.Instance;
2813
- console.log('Before rendering - Registry keys:', registry.getRegisteredKeys());
2814
- console.log('Looking for component:', selectedName);
2815
- // Render the selected component
2816
- currentHost = await this.renderTestComponent(selectedName, previewContainer, currentHost);
2817
- });
2818
- // Handle parse & register button
2819
- parseBtn.addEventListener('click', async () => {
2820
- errorContainer.style.display = 'none';
2821
- errorContainer.innerHTML = '';
2822
- try {
2823
- const spec = JSON.parse(codeEditorValue);
2824
- // Generate unique name if component already exists
2825
- let componentName = spec.componentName;
2826
- let counter = 1;
2827
- while (this.registeredTestComponents.has(componentName)) {
2828
- componentName = `${spec.componentName}_${counter}`;
2829
- counter++;
2830
- }
2831
- const result = await this.processSkipComponentSpec(spec);
2832
- if (result.success) {
2833
- // Add to dropdown
2834
- const option = document.createElement('option');
2835
- option.value = componentName;
2836
- option.textContent = `${componentName} (${result.registeredComponents.length} components)`;
2837
- componentSelector.appendChild(option);
2838
- componentSelector.value = componentName;
2839
- // Trigger change event to render
2840
- componentSelector.dispatchEvent(new Event('change'));
2841
- this.notificationService.CreateSimpleNotification(`Successfully registered ${result.registeredComponents.length} components`, 'success', 3000);
2842
- }
2843
- else {
2844
- errorContainer.style.display = 'block';
2845
- errorContainer.innerHTML = '<strong>Errors:</strong><br>' + result.errors.join('<br>');
2846
- }
2847
- }
2848
- catch (error) {
2849
- errorContainer.style.display = 'block';
2850
- errorContainer.innerHTML = '<strong>JSON Parse Error:</strong><br>' + error.message;
2851
- }
2852
- });
2853
- // Handle clear button
2854
- clearBtn.addEventListener('click', () => {
2855
- // Clear only non-prebuilt components
2856
- this.registeredTestComponents.forEach((spec, name) => {
2857
- if (!spec.prebuilt) {
2858
- GlobalComponentRegistry.Instance.remove(`${name}_Global_v1`);
2859
- this.registeredTestComponents.delete(name);
2860
- }
2861
- });
2862
- // Clear dropdown but keep pre-built options
2863
- componentSelector.innerHTML = '';
2864
- const defaultOption = document.createElement('option');
2865
- defaultOption.value = '';
2866
- defaultOption.textContent = 'Select a component...';
2867
- componentSelector.appendChild(defaultOption);
2868
- // Re-add pre-built components
2869
- for (const comp of prebuiltComponents) {
2870
- const option = document.createElement('option');
2871
- option.value = comp.name;
2872
- option.textContent = comp.label;
2873
- componentSelector.appendChild(option);
2874
- }
2875
- // Clear preview
2876
- if (currentHost) {
2877
- currentHost.destroy();
2878
- currentHost = null;
2879
- }
2880
- previewContainer.innerHTML = '<div style="color: #666; text-align: center; padding: 40px;">Select a component to preview</div>';
2881
- // Clear editor
2882
- codeEditor.value = '';
2883
- codeEditorValue = '';
2884
- parseBtn.disabled = true;
2885
- });
2886
- // Handle add new button
2887
- addNewBtn.addEventListener('click', () => {
2888
- codeEditor.value = JSON.stringify(exampleSpec, null, 2);
2889
- codeEditorValue = JSON.stringify(exampleSpec, null, 2);
2890
- parseBtn.disabled = false;
2891
- });
2892
- // Initial state
2893
- previewContainer.innerHTML = '<div style="color: #666; text-align: center; padding: 40px;">Paste JSON and click "Parse & Register" to test a component</div>';
2894
- }
2895
- async renderTestComponent(componentName, container, currentHost) {
2896
- // Clean up existing host
2897
- if (currentHost) {
2898
- currentHost.destroy();
2899
- }
2900
- container.innerHTML = '';
2901
- try {
2902
- // Create wrapper component that uses the selected component
2903
- const wrapperCode = `
2904
- function createComponent(React, ReactDOM, useState, useEffect, useCallback, createStateUpdater, createStandardEventHandler, libraries) {
2905
- const WrapperComponent = ({ data, utilities, userState, callbacks, styles, components }) => {
2906
- const SelectedComponent = components['${componentName}'];
2907
-
2908
- if (!SelectedComponent) {
2909
- return React.createElement('div', {
2910
- style: { color: 'red', padding: '20px' }
2911
- }, 'Component "${componentName}" not found in registry');
2912
- }
2913
-
2914
- return React.createElement(SelectedComponent, {
2915
- data: data,
2916
- utilities: utilities,
2917
- userState: userState,
2918
- callbacks: callbacks,
2919
- styles: styles,
2920
- components: components
2921
- });
2922
- };
2923
-
2924
- return { component: WrapperComponent };
2925
- }
2926
- `;
2927
- // The React host will handle all registration automatically
2928
- const host = new SkipReactComponentHost({
2929
- component: {
2930
- componentName: 'TestWrapper',
2931
- componentCode: wrapperCode,
2932
- componentType: 'other',
2933
- childComponents: [], // No child components for the wrapper
2934
- functionalRequirements: 'Test wrapper component',
2935
- technicalDesign: 'Wrapper for testing components',
2936
- description: 'Wrapper component for testing',
2937
- callbackStrategy: 'none',
2938
- stateStructure: {},
2939
- title: 'Test Wrapper',
2940
- userExplanation: 'This is a test wrapper',
2941
- techExplanation: 'Wraps components for testing'
2942
- },
2943
- container: container,
2944
- data: {},
2945
- initialState: {},
2946
- utilities: {
2947
- md: {},
2948
- rv: new TestRunView(),
2949
- rq: {}
2950
- },
2951
- metadata: {
2952
- requiredChildComponents: this.getRequiredChildComponents(componentName),
2953
- componentContext: 'Global', // Always use Global context for test components
2954
- version: 'v1'
2955
- },
2956
- callbacks: {
2957
- RefreshData: () => console.log('Refresh data requested'),
2958
- UpdateUserState: (state) => console.log('User state updated:', state),
2959
- OpenEntityRecord: (entityName, key) => console.log('Open entity:', entityName, key),
2960
- NotifyEvent: (eventType, data) => console.log('Event:', eventType, data)
2961
- }
2962
- });
2963
- await host.initialize();
2964
- console.log('Component rendered successfully');
2965
- return host;
2966
- }
2967
- catch (error) {
2968
- console.error('Error rendering component:', error);
2969
- container.innerHTML = `<div style="color: red; padding: 20px;">Error rendering component: ${error}</div>`;
2970
- return null;
2971
- }
2972
- }
2973
2323
  static ɵfac = function SkipChatComponent_Factory(t) { return new (t || SkipChatComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i2.Location), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.MJNotificationService), i0.ɵɵdirectiveInject(i4.DialogService)); };
2974
2324
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SkipChatComponent, selectors: [["skip-chat"]], viewQuery: function SkipChatComponent_Query(rf, ctx) { if (rf & 1) {
2975
2325
  i0.ɵɵviewQuery(Container, 7);
@@ -2992,10 +2342,10 @@ export class SkipChatComponent extends BaseAngularComponent {
2992
2342
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.topLevelDiv = _t.first);
2993
2343
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.resourcePermissionsRef = _t.first);
2994
2344
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.splitPanel = _t.first);
2995
- } }, inputs: { AllowSend: "AllowSend", Messages: "Messages", Conversations: "Conversations", SelectedConversation: "SelectedConversation", ConversationEditMode: "ConversationEditMode", ShowConversationList: "ShowConversationList", AllowNewConversations: "AllowNewConversations", Title: "Title", DataContextID: "DataContextID", LinkedEntity: "LinkedEntity", LinkedEntityCompositeKey: "LinkedEntityCompositeKey", ShowDataContextButton: "ShowDataContextButton", IncludeLinkedConversationsInList: "IncludeLinkedConversationsInList", SkipLogoURL: "SkipLogoURL", SkipMarkOnlyLogoURL: "SkipMarkOnlyLogoURL", UserImage: "UserImage", VerboseLogging: "VerboseLogging", UpdateAppRoute: "UpdateAppRoute", ShowSkipLogoInConversationList: "ShowSkipLogoInConversationList", ShowSharingButton: "ShowSharingButton", SharingExcludeRoleNames: "SharingExcludeRoleNames", SharingExcludeEmails: "SharingExcludeEmails", EnableArtifactSplitView: "EnableArtifactSplitView", DefaultSplitRatio: "DefaultSplitRatio", DefaultTextboxPlaceholder: "DefaultTextboxPlaceholder", ProcessingTextBoxPlaceholder: "ProcessingTextBoxPlaceholder", WelcomeQuestions: "WelcomeQuestions", AutoLoad: "AutoLoad" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", ConversationSelected: "ConversationSelected", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactSelected: "ArtifactSelected", ArtifactViewed: "ArtifactViewed" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 24, vars: 18, consts: [["topLevelDiv", ""], ["splitPanel", ""], ["AskSkipPanel", ""], ["scrollContainer", ""], ["conversationList", ""], ["AskSkipInput", ""], ["resourcePermissions", ""], ["kendoDialogContainer", "", 1, "chat-container"], [1, "layout"], [1, "left-panel"], [1, "fa-solid", "fa-table-columns", "toggle-icon"], [1, "right-panel"], ["mjFillContainer", "", 3, "SplitRatioChanged", "VersionSelected", "Mode", "SplitRatio", "RightPanelHeaderContent", "VersionList", "SelectedVersionId", "fillWidth", "fillHeight"], ["left-panel", "", 1, "conversation-wrapper"], [2, "width", "0", "height", "0", "overflow", "hidden", "position", "absolute"], [1, "messages", 3, "scroll"], ["class", "welcome-wrapper", 4, "ngIf"], [1, "loading-convo-messages-wrapper"], ["mjContainer", "", "mjSkipResize", "true", 1, "messages-container"], ["class", "scroll-to-bottom-icon", 3, "left", "click", 4, "ngIf"], [1, "input-area"], ["right-panel", ""], [3, "ArtifactID", "ArtifactVersionID", "DataContext", "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", 4, "ngIf"], [3, "dataContextId", "Provider"], ["title", "Share Conversation", 3, "width", "height"], ["title", "Please confirm", 3, "minWidth", "width", "close", 4, "ngIf"], [1, "conversation-history"], [1, "new-chat-area"], [1, "fa-solid", "fa-table-columns", "toggle-icon", 3, "click"], [1, "avatar", 3, "src"], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon"], [1, "conversation-list", 3, "data", "itemClass"], ["kendoListViewItemTemplate", ""], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon", 3, "click"], [1, "conversation-item", 3, "click", "ngClass", "title"], ["class", "fa-regular fa-clock", 4, "ngIf"], [1, "text-container"], [4, "ngIf"], ["maxlength", "100", 3, "ngModel", "ngModelChange", 4, "ngIf"], ["class", "edit-conversation-panel", 4, "ngIf"], [1, "fa-regular", "fa-clock"], ["maxlength", "100", 3, "ngModelChange", "ngModel"], [1, "edit-conversation-panel"], ["class", "fa-solid fa-pen-to-square", 3, "click", 4, "ngIf"], ["class", "fa-regular fa-trash-can", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-check", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-xmark", 3, "click", 4, "ngIf"], [1, "fa-solid", "fa-pen-to-square", 3, "click"], [1, "fa-regular", "fa-trash-can", 3, "click"], [1, "fa-solid", "fa-check", 3, "click"], [1, "fa-solid", "fa-xmark", 3, "click"], [1, "welcome-wrapper"], [1, "welcome-message"], [3, "src"], [1, "welcome-header-text"], [1, "welcome-suggested-questions"], [1, "welcome-suggested-questions-col"], [1, "welcome-question", 3, "click"], [1, "welcome-question-header"], [1, "scroll-to-bottom-icon", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "text-area-wrapper"], ["type", "text", 3, "keyup.enter", "input", "disabled", "placeholder"], [1, "button-area"], ["kendoButton", ""], ["kendoButton", "", 1, "stop-button"], ["kendoButton", "", 3, "disabled"], ["kendoButton", "", 1, "share-button"], ["kendoButton", "", 1, "test-button", 2, "background-color", "#ff0000", "color", "white"], [1, "fa-solid", "fa-flask", 3, "click"], [1, "fa-solid", "fa-gear", 3, "click"], ["kendoButton", "", 1, "stop-button", 3, "click"], [1, "fas", "fa-solid", "fa-stop"], ["kendoButton", "", 3, "click", "disabled"], [1, "fas", "fa-solid", "fa-arrow-up"], [1, "fa-solid", "fa-share", 3, "click"], [3, "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", "ArtifactID", "ArtifactVersionID", "DataContext"], [3, "dialogClosed", "dataContextId", "Provider"], ["title", "Share Conversation", 3, "close", "width", "height"], [3, "Provider", "ResourceTypeID", "ResourceRecordID", "ExcludedRoleNames", "ExcludedUserEmails"], ["kendoButton", "", "themeColor", "primary", 3, "click"], ["kendoButton", "", 3, "click"], ["title", "Please confirm", 3, "close", "minWidth", "width"], [2, "margin", "30px", "text-align", "center"]], template: function SkipChatComponent_Template(rf, ctx) { if (rf & 1) {
2345
+ } }, inputs: { AllowSend: "AllowSend", Messages: "Messages", Conversations: "Conversations", SelectedConversation: "SelectedConversation", ConversationEditMode: "ConversationEditMode", ShowConversationList: "ShowConversationList", AllowNewConversations: "AllowNewConversations", Title: "Title", DataContextID: "DataContextID", LinkedEntity: "LinkedEntity", LinkedEntityCompositeKey: "LinkedEntityCompositeKey", ShowDataContextButton: "ShowDataContextButton", IncludeLinkedConversationsInList: "IncludeLinkedConversationsInList", SkipLogoURL: "SkipLogoURL", SkipMarkOnlyLogoURL: "SkipMarkOnlyLogoURL", UserImage: "UserImage", VerboseLogging: "VerboseLogging", UpdateAppRoute: "UpdateAppRoute", ShowSkipLogoInConversationList: "ShowSkipLogoInConversationList", ShowSharingButton: "ShowSharingButton", SharingExcludeRoleNames: "SharingExcludeRoleNames", SharingExcludeEmails: "SharingExcludeEmails", EnableArtifactSplitView: "EnableArtifactSplitView", DefaultSplitRatio: "DefaultSplitRatio", DefaultTextboxPlaceholder: "DefaultTextboxPlaceholder", ProcessingTextBoxPlaceholder: "ProcessingTextBoxPlaceholder", WelcomeQuestions: "WelcomeQuestions", AutoLoad: "AutoLoad" }, outputs: { NavigateToMatchingReport: "NavigateToMatchingReport", ConversationSelected: "ConversationSelected", NewReportCreated: "NewReportCreated", DrillDownEvent: "DrillDownEvent", ArtifactSelected: "ArtifactSelected", ArtifactViewed: "ArtifactViewed" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 24, vars: 18, consts: [["topLevelDiv", ""], ["splitPanel", ""], ["AskSkipPanel", ""], ["scrollContainer", ""], ["conversationList", ""], ["AskSkipInput", ""], ["resourcePermissions", ""], ["kendoDialogContainer", "", 1, "chat-container"], [1, "layout"], [1, "left-panel"], [1, "fa-solid", "fa-table-columns", "toggle-icon"], [1, "right-panel"], ["mjFillContainer", "", 3, "SplitRatioChanged", "VersionSelected", "Mode", "SplitRatio", "RightPanelHeaderContent", "VersionList", "SelectedVersionId", "fillWidth", "fillHeight"], ["left-panel", "", 1, "conversation-wrapper"], [2, "width", "0", "height", "0", "overflow", "hidden", "position", "absolute"], [1, "messages", 3, "scroll"], ["class", "welcome-wrapper", 4, "ngIf"], [1, "loading-convo-messages-wrapper"], ["mjContainer", "", "mjSkipResize", "true", 1, "messages-container"], ["class", "scroll-to-bottom-icon", 3, "left", "click", 4, "ngIf"], [1, "input-area"], ["right-panel", ""], [3, "ArtifactID", "ArtifactVersionID", "DataContext", "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", 4, "ngIf"], [3, "dataContextId", "Provider"], ["title", "Share Conversation", 3, "width", "height"], ["title", "Please confirm", 3, "minWidth", "width", "close", 4, "ngIf"], [1, "conversation-history"], [1, "new-chat-area"], [1, "fa-solid", "fa-table-columns", "toggle-icon", 3, "click"], [1, "avatar", 3, "src"], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon"], [1, "conversation-list", 3, "data", "itemClass"], ["kendoListViewItemTemplate", ""], [1, "fa-solid", "fa-pen-to-square", "new-convo-icon", 3, "click"], [1, "conversation-item", 3, "click", "ngClass", "title"], ["class", "fa-regular fa-clock", 4, "ngIf"], [1, "text-container"], [4, "ngIf"], ["maxlength", "100", 3, "ngModel", "ngModelChange", 4, "ngIf"], ["class", "edit-conversation-panel", 4, "ngIf"], [1, "fa-regular", "fa-clock"], ["maxlength", "100", 3, "ngModelChange", "ngModel"], [1, "edit-conversation-panel"], ["class", "fa-solid fa-pen-to-square", 3, "click", 4, "ngIf"], ["class", "fa-regular fa-trash-can", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-check", 3, "click", 4, "ngIf"], ["class", "fa-solid fa-xmark", 3, "click", 4, "ngIf"], [1, "fa-solid", "fa-pen-to-square", 3, "click"], [1, "fa-regular", "fa-trash-can", 3, "click"], [1, "fa-solid", "fa-check", 3, "click"], [1, "fa-solid", "fa-xmark", 3, "click"], [1, "welcome-wrapper"], [1, "welcome-message"], [3, "src"], [1, "welcome-header-text"], [1, "welcome-suggested-questions"], [1, "welcome-suggested-questions-col"], [1, "welcome-question", 3, "click"], [1, "welcome-question-header"], [1, "scroll-to-bottom-icon", 3, "click"], [1, "fas", "fa-arrow-down"], [1, "text-area-wrapper"], ["type", "text", 3, "keyup.enter", "input", "disabled", "placeholder"], [1, "button-area"], ["kendoButton", ""], ["kendoButton", "", 1, "stop-button"], ["kendoButton", "", 3, "disabled"], ["kendoButton", "", 1, "share-button"], [1, "fa-solid", "fa-gear", 3, "click"], ["kendoButton", "", 1, "stop-button", 3, "click"], [1, "fas", "fa-solid", "fa-stop"], ["kendoButton", "", 3, "click", "disabled"], [1, "fas", "fa-solid", "fa-arrow-up"], [1, "fa-solid", "fa-share", 3, "click"], [3, "NavigateToMatchingReport", "NewReportCreated", "DrillDownEvent", "ArtifactInfoChanged", "ArtifactID", "ArtifactVersionID", "DataContext"], [3, "dialogClosed", "dataContextId", "Provider"], ["title", "Share Conversation", 3, "close", "width", "height"], [3, "Provider", "ResourceTypeID", "ResourceRecordID", "ExcludedRoleNames", "ExcludedUserEmails"], ["kendoButton", "", "themeColor", "primary", 3, "click"], ["kendoButton", "", 3, "click"], ["title", "Please confirm", 3, "close", "minWidth", "width"], [2, "margin", "30px", "text-align", "center"]], template: function SkipChatComponent_Template(rf, ctx) { if (rf & 1) {
2996
2346
  const _r1 = i0.ɵɵgetCurrentView();
2997
2347
  i0.ɵɵelementStart(0, "div", 7, 0)(2, "div", 8);
2998
- i0.ɵɵtemplate(3, SkipChatComponent_Conditional_3_Template, 9, 7, "div", 9)(4, SkipChatComponent_Conditional_4_Template, 1, 0, "span", 10);
2348
+ i0.ɵɵtemplate(3, SkipChatComponent_Conditional_3_Template, 9, 5, "div", 9)(4, SkipChatComponent_Conditional_4_Template, 1, 0, "span", 10);
2999
2349
  i0.ɵɵelementStart(5, "div", 11)(6, "skip-split-panel", 12, 1);
3000
2350
  i0.ɵɵlistener("SplitRatioChanged", function SkipChatComponent_Template_skip_split_panel_SplitRatioChanged_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSplitRatioChanged($event)); })("VersionSelected", function SkipChatComponent_Template_skip_split_panel_VersionSelected_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onArtifactVersionSelected($event)); });
3001
2351
  i0.ɵɵelementStart(8, "div", 13);
@@ -3006,7 +2356,7 @@ export class SkipChatComponent extends BaseAngularComponent {
3006
2356
  i0.ɵɵelement(15, "div", 18);
3007
2357
  i0.ɵɵtemplate(16, SkipChatComponent_span_16_Template, 2, 2, "span", 19);
3008
2358
  i0.ɵɵelementEnd();
3009
- i0.ɵɵtemplate(17, SkipChatComponent_Conditional_17_Template, 11, 7, "div", 20);
2359
+ i0.ɵɵtemplate(17, SkipChatComponent_Conditional_17_Template, 9, 7, "div", 20);
3010
2360
  i0.ɵɵelementEnd();
3011
2361
  i0.ɵɵelementStart(18, "div", 21);
3012
2362
  i0.ɵɵtemplate(19, SkipChatComponent_skip_artifact_viewer_19_Template, 1, 3, "skip-artifact-viewer", 22);
@@ -3041,7 +2391,7 @@ export class SkipChatComponent extends BaseAngularComponent {
3041
2391
  }
3042
2392
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SkipChatComponent, [{
3043
2393
  type: Component,
3044
- args: [{ selector: 'skip-chat', template: "<div class=\"chat-container\" kendoDialogContainer #topLevelDiv>\n <div class=\"layout\">\n @if (IsConversationListVisible) {\n <div class=\"left-panel\">\n <div class=\"conversation-history\">\n <div class=\"new-chat-area\">\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(false)\"></span>\n @if (ShowSkipLogoInConversationList) {\n <img [src]=\"SkipLogoURL\" class=\"avatar\" />\n }\n @if (AllowNewConversations) {\n <span class=\"fa-solid fa-pen-to-square new-convo-icon\" (click)=\"CreateNewConversation()\"></span> \n }\n </div>\n <kendo-listview\n class=\"conversation-list\"\n [data]=\"Conversations\"\n [style.height.px]=\"280\"\n [itemClass]=\"{ 'item-border': true }\" \n #conversationList\n >\n <ng-template kendoListViewItemTemplate let-dataItem=\"dataItem\">\n <div class=\"conversation-item\" \n [ngClass]=\"GetConversationItemClass(dataItem)\"\n [title]=\"dataItem.Name\" \n (click)=\"SelectConversation(dataItem)\"> \n <span *ngIf=\"SelectedConversation && IsSkipProcessing(dataItem)\" class=\"fa-regular fa-clock\"></span>\n <div class=\"text-container\">\n <span *ngIf=\"dataItem.ID !== SelectedConversation?.ID || !ConversationEditMode\">{{ dataItem.Name }}</span>\n <textarea *ngIf=\"dataItem.ID === SelectedConversation?.ID && ConversationEditMode\" [(ngModel)]=\"dataItem.Name\" maxlength=\"100\"></textarea>\n </div>\n <div *ngIf=\"SelectedConversation?.ID === dataItem.ID\" class=\"edit-conversation-panel\">\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-solid fa-pen-to-square\" (click)=\"editConvo(dataItem)\"></span>\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-regular fa-trash-can\" (click)=\"showDeleteConvoDialog(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-check\" (click)=\"saveConvoName(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-xmark\" (click)=\"cancelConvoEdit(dataItem)\"></span>\n </div>\n </div>\n </ng-template>\n </kendo-listview>\n <!-- COMMENTED OUT as we don't want to support embedded conversations in the UI for now\n <div class=\"embedded-conversations\"><input kendoCheckBox type=\"checkbox\" [(ngModel)]=\"IncludeLinkedConversationsInList\" (ngModelChange)=\"loadConversations()\"/> <span (click)=\"FlipEmbeddedConversationState()\">Show Linked Conversations</span></div> -->\n </div> \n </div>\n }\n @if (!IsConversationListVisible) {\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(true)\"></span>\n }\n\n <div class=\"right-panel\">\n <skip-split-panel \n #splitPanel\n [Mode]=\"EnableArtifactSplitView && selectedArtifact ? 'BothSides' : 'LeftOnly'\" \n [SplitRatio]=\"SplitRatio\" \n (SplitRatioChanged)=\"onSplitRatioChanged($event)\"\n [RightPanelHeaderContent]=\"artifactHeaderInfo\"\n [VersionList]=\"artifactVersionList\"\n [SelectedVersionId]=\"selectedArtifactVersionId\"\n (VersionSelected)=\"onArtifactVersionSelected($event)\"\n mjFillContainer [fillWidth]=\"false\" [fillHeight]=\"true\">\n \n <!-- Left Panel (Chat) -->\n <div left-panel class=\"conversation-wrapper\">\n <!-- Use this for reference only, but don't display - hidden via width:0, height:0 -->\n <div #AskSkipPanel style=\"width:0; height:0; overflow:hidden; position:absolute;\"></div>\n \n <div class=\"messages\" #scrollContainer (scroll)=\"checkScroll()\">\n <div class=\"welcome-wrapper\" *ngIf=\"(!Messages || Messages.length ===0) && _conversationLoadComplete\">\n <div class='welcome-message'>\n <img [src]=\"SkipLogoURL\" />\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n </div>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n </div>\n </div> \n </div>\n @if (!_conversationLoadComplete) {\n <div class=\"loading-convo-messages-wrapper\">\n <kendo-loader></kendo-loader>\n </div>\n } \n <div class=\"messages-container\" mjContainer mjSkipResize=\"true\"><!--mjSkipResize results in everything below this level NOT being resized, performance optimization-->\n <!-- Dynamic messages will be injected here -->\n </div>\n <span class=\"scroll-to-bottom-icon\" \n *ngIf=\"_showScrollToBottomIcon && Messages && Messages.length > 0\" \n [style.left.px]=\"getScrollToBottomIconPosition()\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n @if (SelectedConversationCurrentUserPermissionLevel === 'Owner' || \n SelectedConversationCurrentUserPermissionLevel === 'Edit') {\n <div class=\"input-area\">\n <div class=\"text-area-wrapper\">\n <textarea\n #AskSkipInput \n [disabled]=\"SelectedConversation && IsSkipProcessing(SelectedConversation)\" \n (keyup.enter)=\"onEnter($event)\" \n (input)=\"onInputChange($event)\"\n type=\"text\" \n [placeholder]=\"_AskSkipTextboxPlaceholder\"></textarea>\n </div>\n <div class=\"button-area\" [style.marginLeft.px]=\"-35 * NumVisibleButtons\">\n @if (ShowDataContextButton) {\n <button kendoButton >\n <span class=\"fa-solid fa-gear\" \n (click)=\"showDataContextDialog()\"></span>\n </button> \n }\n @if (SelectedConversation && IsSkipProcessing(SelectedConversation)) {\n <button kendoButton \n class=\"stop-button\"\n (click)=\"stopProcessing()\">\n <span class=\"fas fa-solid fa-stop\"></span>\n </button>\n }\n @else {\n <button kendoButton \n [disabled]=\"IsTextAreaEmpty()\" \n (click)=\"sendSkipMessage()\">\n <span class=\"fas fa-solid fa-arrow-up\"></span>\n </button>\n }\n @if (ShowSharingButton && SelectedConversationCurrentUserPermissionLevel === 'Owner') {\n <button kendoButton class=\"share-button\">\n <span class=\"fa-solid fa-share\"\n (click)=\"showSharingDialog()\"></span>\n </button> \n }\n <!-- TEMPORARY TEST BUTTON -->\n <button kendoButton class=\"test-button\" style=\"background-color: #ff0000; color: white;\">\n <span class=\"fa-solid fa-flask\"\n (click)=\"testButtonClick()\"></span>\n </button>\n </div>\n </div>\n }\n </div>\n \n <!-- Right Panel (Artifact Viewer) -->\n <div right-panel>\n <skip-artifact-viewer\n *ngIf=\"selectedArtifact\"\n [ArtifactID]=\"selectedArtifact.artifactId\"\n [ArtifactVersionID]=\"selectedArtifact.artifactVersionId\"\n [DataContext]=\"DataContext\"\n (NavigateToMatchingReport)=\"NavigateToMatchingReport.emit($event)\"\n (NewReportCreated)=\"NewReportCreated.emit($event)\"\n (DrillDownEvent)=\"DrillDownEvent.emit($event)\"\n (ArtifactInfoChanged)=\"onArtifactInfoChanged($event)\">\n </skip-artifact-viewer>\n </div>\n </skip-split-panel>\n </div> \n </div> \n</div> \n\n@if(isDataContextDialogVisible) {\n <mj-data-context-dialog [dataContextId]=\"DataContextID\" (dialogClosed)=\"closeDataContextDialog()\" [Provider]=\"ProviderToUse\"></mj-data-context-dialog>\n}\n@if(isSharingDialogVisible && SelectedConversation && conversationResourceTypeID) {\n <kendo-dialog\n title=\"Share Conversation\"\n (close)=\"closeSharingDialog('no')\"\n [width]=\"650\"\n [height]=\"400\"\n >\n <mj-resource-permissions \n [Provider]=\"Provider\"\n [ResourceTypeID]=\"conversationResourceTypeID\"\n [ResourceRecordID]=\"SelectedConversation.ID\"\n [ExcludedRoleNames]=\"SharingExcludeRoleNames\"\n [ExcludedUserEmails]=\"SharingExcludeEmails\"\n #resourcePermissions\n >\n </mj-resource-permissions>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeSharingDialog('yes')\" themeColor=\"primary\">\n Save\n </button>\n <button kendoButton (click)=\"closeSharingDialog('no')\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog> \n}\n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmDeleteConversationDialogOpen\"\n (close)=\"closeDeleteConversation('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to delete {{SelectedConversation?.Name}}?\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeDeleteConversation('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeDeleteConversation('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> \n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmMessageEditOrDeleteDialogOpen\"\n (close)=\"closeMessageEditOrDeleteDialog('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to {{messageEditOrDeleteType}} this message? Doing so will result in any subsequent messages in the conversation being deleted.\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> ", styles: [".layout {\n display: flex;\n flex-direction: row; /* Ensures left and right panels are side by side */\n height: 100%; /* Fill the available height */\n width: 100%; /* Fill the available width */\n position: relative;\n overflow: hidden; /* Prevent content from expanding beyond container */\n}\n\n.left-panel {\n width: 272px; /* Fixed width for the conversation list */\n background-color: #f8f9fa; /* Optional: Background color */\n border-right: 1px solid #ddd; /* Optional: Add a divider */\n overflow-y: auto; /* Enable scrolling if content overflows */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n position: relative;\n\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.left-panel::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.left-panel::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.left-panel::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.left-panel::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n.right-panel {\n flex: 1; /* Take up the remaining space */\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; /* Don't exceed parent container height */\n overflow: hidden; /* Hide overflow to prevent double scrollbars */\n}\n\n.conversation-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel .toggle-icon {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; /* For the right panel toggle */\n}\n\n\n.chat-container {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n /*initial sizes*/\n width: 100%;\n overflow: hidden; /* Prevent container from growing beyond viewport */\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper {\n display: flex;\n flex-direction: column;\n position: relative; /* This ensures child absolute elements position relative to this container */\n background-color: #f9f9f9;\n height: 100%; /* Ensure it takes full height */\n max-height: 100%; /* Don't exceed parent container height */\n flex: 1;\n overflow: auto; /* Allow content to scroll */\n}\n\n.new-conversation {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; /* Add scroll if the content exceeds the height */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history > button {\n height: 25px;\n}\n\n.skip-title {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n/* Center the welcome message vertically and horizontally */\n.welcome-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; /* Push the content up a bit */\n}\n\n.embedded-conversations {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations > span {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message img {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; /* Adds some space between the image and the text below */\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text {\n font-size: larger;\n font-weight: bold;\n}\n\n/* Position the welcome-suggested-questions at the bottom of its container */\n.welcome-suggested-questions {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; /* Push questions down for spacing */\n}\n.welcome-suggested-questions-col {\n display: flex;\n margin-bottom: 10px; /* Space between rows */\n}\n\n/* Flex layout for questions, two per row */\n.welcome-question {\n display: flex;\n flex-direction: column; /* Stack the header and text vertically */\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; /* Adds some space around each question */\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header {\n font-size: 12pt;\n font-weight: bold;\n display: block; /* Ensures the header is on its own line */\n}\n\n/* Non-bold text for the content below the header */\n.welcome-question span:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages {\n overflow-y: auto !important; /* enable scrolling if the content overflows */\n overflow-x: hidden !important; /* hide horizontal scrollbar */\n /* border: solid 1px rgba(0, 0, 0, 0.08); */\n margin-bottom: 5px;\n\n margin-top: 2px; /* align it with the top of converation history exactly*/\n\n background-color: #f9f9f9;\n flex: 1 1 auto; /* Take up available space but don't push parent beyond size */\n height: calc(100% - 50px); /* Ensure messages container has a height */\n max-height: 100%; /* Don't exceed parent height */\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n position: relative; /* For proper positioning of scroll icon */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.messages::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.messages::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.messages::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.messages::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n/* Class for the messages container */\n.messages-container {\n min-height: 20px; /* Ensure container takes space even when empty */\n}\n\n\n\n.new-chat-area {\n display: flex;\n justify-content: space-between; /* Aligns children (img and button) to each end */\n align-items: center; /* Centers children vertically */\n}\n.avatar {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n /* Ensure the image aligns to the left */\n margin-right: auto; /* Pushes everything else to the right */\n}\n\n.conversation-item {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; /* Align items to the top */\n\n flex-wrap: wrap; /* Allow items to wrap to the next line */\n}\n\n.text-container {\n flex: 1; /* Take up remaining space */\n display: flex;\n flex-direction: column; /* Stack children vertically */\n}\n\n.text-container textarea {\n resize: none; /* Disable resizing */\n /* Add more styles for the textarea if needed */\n}\n\n.conversation-item > .conversation-icon {\n margin-top: 3px;\n}\n\n.conversation-item span {\n display: inline-block;\n white-space: pre-wrap; /* Allow text to wrap */\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; /* Move the text to the right */\n}\n\n.conversation-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item > .conversation-icon {\n margin-right: 11px;\n}\n.edit-conversation-panel {\n display: flex;\n justify-content: flex-end; /* Align icons to the right */\n margin-top: 2px; /* litle buffer on top */\n margin-right: 2px; /* litle buffer to the right */\n}\n.edit-conversation-panel > .k-icon {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel > .k-icon:hover {\n color: #ff0000;\n}\n\n\n\n.input-area {\n min-height: 35px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-area > .button-area {\n vertical-align: top;\n margin-top: 3px;\n margin-left: -65px;\n}\n/*all buttons in the button area within the input area*/\n.button-area > button {\n width: 30px;\n height: 30px;\n border-radius: 12px;\n margin-left: 3px;\n}\n\n/* Stop button styling */\n.button-area > button.stop-button {\n background-color: #dc3545;\n color: white;\n}\n\n.button-area > button.stop-button:hover {\n background-color: #c82333;\n}\n/* .input-area > button:first-of-type {\n margin-left: -40px;\n}\n.input-area > button:last-child {\n margin-left: -65px;\n}\n.input-area > .share-button {\n margin-left: 10px;\n} */\n\n.text-area-wrapper {\n padding: 3px;\n border: solid 1px rgba(0, 0, 0, 0.08) ;\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; /* Prevent it from growing beyond the container */\n\n overflow: hidden; \n align-items: center;\n\n /*combined width and padding is 800*/\n width: 710px; \n padding-right: 90px\n} \n.text-area-wrapper > textarea {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; /* Initial height */\n\n width: 100%;\n overflow-y: hidden; /* Hide scrollbar */\n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n\n background-color: #f9f9f9;\n}\n\n/* .text-area-wrapper > textarea:disabled {\n background-color: white;\n} */\n\n.input-wrapper {\n flex-grow: 1; /* This will make the input-wrapper take the remaining space */\n height: 100%;\n}\n\n.waiting-for-ai {\n position: absolute;\n display: flex; /* Use flexbox layout */\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon {\n position: fixed; /* Fixed positioning to float over content */\n bottom: 120px; /* Position relative to the viewport */\n /* left position will be set dynamically via inline style */\n transform: translateX(-50%); /* Shift it back by half its width to center it */\n z-index: 1000; /* Ensure it stays on top */\n background-color: white; /* Circle background color */\n color: black; /* Icon color */\n border-radius: 50%; /* Makes the background a circle */\n width: 40px; /* Circle size */\n height: 40px; /* Circle size */\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); /* Subtle shadow for better visibility */\n cursor: pointer;\n opacity: 0.9; /* Slightly transparent */\n}\n\n.loading-convo-messages-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions {\n display: flex;\n flex-wrap: wrap; /* Allows questions to wrap to the next line */\n align-content: flex-end; /* Aligns the content to the bottom */\n }\n}\n \n"] }]
2394
+ args: [{ selector: 'skip-chat', template: "<div class=\"chat-container\" kendoDialogContainer #topLevelDiv>\n <div class=\"layout\">\n @if (IsConversationListVisible) {\n <div class=\"left-panel\">\n <div class=\"conversation-history\">\n <div class=\"new-chat-area\">\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(false)\"></span>\n @if (ShowSkipLogoInConversationList) {\n <img [src]=\"SkipLogoURL\" class=\"avatar\" />\n }\n @if (AllowNewConversations) {\n <span class=\"fa-solid fa-pen-to-square new-convo-icon\" (click)=\"CreateNewConversation()\"></span> \n }\n </div>\n <kendo-listview\n class=\"conversation-list\"\n [data]=\"Conversations\"\n [itemClass]=\"{ 'item-border': true }\" \n #conversationList\n >\n <ng-template kendoListViewItemTemplate let-dataItem=\"dataItem\">\n <div class=\"conversation-item\" \n [ngClass]=\"GetConversationItemClass(dataItem)\"\n [title]=\"dataItem.Name\" \n (click)=\"SelectConversation(dataItem)\"> \n <span *ngIf=\"SelectedConversation && IsSkipProcessing(dataItem)\" class=\"fa-regular fa-clock\"></span>\n <div class=\"text-container\">\n <span *ngIf=\"dataItem.ID !== SelectedConversation?.ID || !ConversationEditMode\">{{ dataItem.Name }}</span>\n <textarea *ngIf=\"dataItem.ID === SelectedConversation?.ID && ConversationEditMode\" [(ngModel)]=\"dataItem.Name\" maxlength=\"100\"></textarea>\n </div>\n <div *ngIf=\"SelectedConversation?.ID === dataItem.ID\" class=\"edit-conversation-panel\">\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-solid fa-pen-to-square\" (click)=\"editConvo(dataItem)\"></span>\n <span *ngIf=\"!ConversationEditMode\" class=\"fa-regular fa-trash-can\" (click)=\"showDeleteConvoDialog(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-check\" (click)=\"saveConvoName(dataItem)\"></span>\n <span *ngIf=\"ConversationEditMode\" class=\"fa-solid fa-xmark\" (click)=\"cancelConvoEdit(dataItem)\"></span>\n </div>\n </div>\n </ng-template>\n </kendo-listview>\n <!-- COMMENTED OUT as we don't want to support embedded conversations in the UI for now\n <div class=\"embedded-conversations\"><input kendoCheckBox type=\"checkbox\" [(ngModel)]=\"IncludeLinkedConversationsInList\" (ngModelChange)=\"loadConversations()\"/> <span (click)=\"FlipEmbeddedConversationState()\">Show Linked Conversations</span></div> -->\n </div> \n </div>\n }\n @if (!IsConversationListVisible) {\n <span class=\"fa-solid fa-table-columns toggle-icon\" (click)=\"DisplayConversationList(true)\"></span>\n }\n\n <div class=\"right-panel\">\n <skip-split-panel \n #splitPanel\n [Mode]=\"EnableArtifactSplitView && selectedArtifact ? 'BothSides' : 'LeftOnly'\" \n [SplitRatio]=\"SplitRatio\" \n (SplitRatioChanged)=\"onSplitRatioChanged($event)\"\n [RightPanelHeaderContent]=\"artifactHeaderInfo\"\n [VersionList]=\"artifactVersionList\"\n [SelectedVersionId]=\"selectedArtifactVersionId\"\n (VersionSelected)=\"onArtifactVersionSelected($event)\"\n mjFillContainer [fillWidth]=\"false\" [fillHeight]=\"true\">\n \n <!-- Left Panel (Chat) -->\n <div left-panel class=\"conversation-wrapper\">\n <!-- Use this for reference only, but don't display - hidden via width:0, height:0 -->\n <div #AskSkipPanel style=\"width:0; height:0; overflow:hidden; position:absolute;\"></div>\n \n <div class=\"messages\" #scrollContainer (scroll)=\"checkScroll()\">\n <div class=\"welcome-wrapper\" *ngIf=\"(!Messages || Messages.length ===0) && _conversationLoadComplete\">\n <div class='welcome-message'>\n <img [src]=\"SkipLogoURL\" />\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n </div>\n <div class=\"welcome-suggested-questions-col\">\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div>\n <div class=\"welcome-question\" (click)=\"sendPrompt(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n </div>\n </div> \n </div>\n @if (!_conversationLoadComplete) {\n <div class=\"loading-convo-messages-wrapper\">\n <kendo-loader></kendo-loader>\n </div>\n } \n <div class=\"messages-container\" mjContainer mjSkipResize=\"true\"><!--mjSkipResize results in everything below this level NOT being resized, performance optimization-->\n <!-- Dynamic messages will be injected here -->\n </div>\n <span class=\"scroll-to-bottom-icon\" \n *ngIf=\"_showScrollToBottomIcon && Messages && Messages.length > 0\" \n [style.left.px]=\"getScrollToBottomIconPosition()\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n @if (SelectedConversationCurrentUserPermissionLevel === 'Owner' || \n SelectedConversationCurrentUserPermissionLevel === 'Edit') {\n <div class=\"input-area\">\n <div class=\"text-area-wrapper\">\n <textarea\n #AskSkipInput \n [disabled]=\"SelectedConversation && IsSkipProcessing(SelectedConversation)\" \n (keyup.enter)=\"onEnter($event)\" \n (input)=\"onInputChange($event)\"\n type=\"text\" \n [placeholder]=\"_AskSkipTextboxPlaceholder\"></textarea>\n </div>\n <div class=\"button-area\" [style.marginLeft.px]=\"-35 * NumVisibleButtons\">\n @if (ShowDataContextButton) {\n <button kendoButton >\n <span class=\"fa-solid fa-gear\" \n (click)=\"showDataContextDialog()\"></span>\n </button> \n }\n @if (SelectedConversation && IsSkipProcessing(SelectedConversation)) {\n <button kendoButton \n class=\"stop-button\"\n (click)=\"stopProcessing()\">\n <span class=\"fas fa-solid fa-stop\"></span>\n </button>\n }\n @else {\n <button kendoButton \n [disabled]=\"IsTextAreaEmpty()\" \n (click)=\"sendSkipMessage()\">\n <span class=\"fas fa-solid fa-arrow-up\"></span>\n </button>\n }\n @if (ShowSharingButton && SelectedConversationCurrentUserPermissionLevel === 'Owner') {\n <button kendoButton class=\"share-button\">\n <span class=\"fa-solid fa-share\"\n (click)=\"showSharingDialog()\"></span>\n </button> \n }\n </div>\n </div>\n }\n </div>\n \n <!-- Right Panel (Artifact Viewer) -->\n <div right-panel>\n <skip-artifact-viewer\n *ngIf=\"selectedArtifact\"\n [ArtifactID]=\"selectedArtifact.artifactId\"\n [ArtifactVersionID]=\"selectedArtifact.artifactVersionId\"\n [DataContext]=\"DataContext\"\n (NavigateToMatchingReport)=\"NavigateToMatchingReport.emit($event)\"\n (NewReportCreated)=\"NewReportCreated.emit($event)\"\n (DrillDownEvent)=\"DrillDownEvent.emit($event)\"\n (ArtifactInfoChanged)=\"onArtifactInfoChanged($event)\">\n </skip-artifact-viewer>\n </div>\n </skip-split-panel>\n </div> \n </div> \n</div> \n\n@if(isDataContextDialogVisible) {\n <mj-data-context-dialog [dataContextId]=\"DataContextID\" (dialogClosed)=\"closeDataContextDialog()\" [Provider]=\"ProviderToUse\"></mj-data-context-dialog>\n}\n@if(isSharingDialogVisible && SelectedConversation && conversationResourceTypeID) {\n <kendo-dialog\n title=\"Share Conversation\"\n (close)=\"closeSharingDialog('no')\"\n [width]=\"650\"\n [height]=\"400\"\n >\n <mj-resource-permissions \n [Provider]=\"Provider\"\n [ResourceTypeID]=\"conversationResourceTypeID\"\n [ResourceRecordID]=\"SelectedConversation.ID\"\n [ExcludedRoleNames]=\"SharingExcludeRoleNames\"\n [ExcludedUserEmails]=\"SharingExcludeEmails\"\n #resourcePermissions\n >\n </mj-resource-permissions>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeSharingDialog('yes')\" themeColor=\"primary\">\n Save\n </button>\n <button kendoButton (click)=\"closeSharingDialog('no')\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog> \n}\n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmDeleteConversationDialogOpen\"\n (close)=\"closeDeleteConversation('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to delete {{SelectedConversation?.Name}}?\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeDeleteConversation('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeDeleteConversation('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> \n\n<kendo-dialog\n title=\"Please confirm\"\n *ngIf=\"confirmMessageEditOrDeleteDialogOpen\"\n (close)=\"closeMessageEditOrDeleteDialog('no')\"\n [minWidth]=\"250\"\n [width]=\"450\"\n>\n <p style=\"margin: 30px; text-align: center;\">\n Would you like to {{messageEditOrDeleteType}} this message? Doing so will result in any subsequent messages in the conversation being deleted.\n </p>\n <kendo-dialog-actions>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('yes')\" themeColor=\"primary\">\n Yes\n </button>\n <button kendoButton (click)=\"closeMessageEditOrDeleteDialog('no')\">\n No\n </button>\n </kendo-dialog-actions>\n</kendo-dialog> ", styles: [".layout {\n display: flex;\n flex-direction: row; /* Ensures left and right panels are side by side */\n height: 100%; /* Fill the available height */\n width: 100%; /* Fill the available width */\n position: relative;\n overflow: hidden; /* Prevent content from expanding beyond container */\n}\n\n.left-panel {\n width: 272px; /* Fixed width for the conversation list */\n background-color: #f8f9fa; /* Optional: Background color */\n border-right: 1px solid #ddd; /* Optional: Add a divider */\n overflow-y: auto; /* Enable scrolling if content overflows */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n position: relative;\n\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.left-panel::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.left-panel::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.left-panel::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.left-panel::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n.right-panel {\n flex: 1; /* Take up the remaining space */\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%; /* Don't exceed parent container height */\n overflow: hidden; /* Hide overflow to prevent double scrollbars */\n}\n\n.conversation-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 16px;\n background-color: #f5f7f9;\n border-bottom: 1px solid #dde4ee;\n height: 40px;\n flex-shrink: 0;\n}\n\n.conversation-title {\n font-size: 15px;\n font-weight: 500;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 70%;\n}\n\n.artifact-counter-container {\n display: flex;\n align-items: center;\n}\n\n\n.new-convo-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n padding: 5px;\n border-radius: 4px;\n}\n\n.toggle-icon {\n color: #808080; /* Mid-gray */\n font-size: 18px; /* Adjust icon size */\n cursor: pointer; /* Make it clear the icon is clickable */\n z-index: 10; /* Ensure the icon is above other content */\n margin-left: 6px;\n padding: 3px;\n border-radius: 3px;\n}\n \n\n.right-panel .toggle-icon {\n margin-left: 3px;\n margin-top: 2px;\n position: absolute;\n top: 10px;\n left: auto;\n right: 10px; /* For the right panel toggle */\n}\n\n\n.chat-container {\n padding: 5px;\n display: flex;\n flex-direction: row;\n height: calc(100vh - 111px);\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n /*initial sizes*/\n width: 100%;\n overflow: hidden; /* Prevent container from growing beyond viewport */\n background-color: #f9f9f9;\n}\n\n.conversation-wrapper {\n display: flex;\n flex-direction: column;\n position: relative; /* This ensures child absolute elements position relative to this container */\n background-color: #f9f9f9;\n height: 100%; /* Ensure it takes full height */\n max-height: 100%; /* Don't exceed parent container height */\n flex: 1;\n overflow: auto; /* Allow content to scroll */\n}\n\n.new-conversation {\n height: 30px;\n font-size: large;\n}\n\n.conversation-history {\n width: 240px;\n min-width: 240px;\n height: 95%;\n overflow-y: auto; /* Add scroll if the content exceeds the height */\n overflow-x: hidden; /* Hide horizontal scrollbar */\n margin-right: 10px;\n padding-top: 5px;\n background-color: #f9f9f9;\n margin-top: 0px; \n padding: 12px; \n}\n\n.k-tabstrip-content-for-skip {\n padding: 0;\n padding-block: 0;\n}\n\n\n.conversation-history > button {\n height: 25px;\n}\n\n.skip-title {\n font-size: larger;\n margin-bottom: 5px;\n height: 20px;\n margin-top: 5px;\n}\n\n.conversation-list {\n margin-top: 5px;\n padding-top: 5px;\n \n border: 0;\n background-color: #f9f9f9;\n}\n\n\n\n/* Center the welcome message vertically and horizontally */\n.welcome-wrapper {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 5;\n}\n\n.welcome-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n padding-bottom: 100px; /* Push the content up a bit */\n}\n\n.embedded-conversations {\n margin-left: 3px;\n margin-top: 5px;\n font-size: 10pt;\n color: rgb(48, 48, 235);\n}\n.embedded-conversations > span {\n margin-top: 4px;\n margin-left: 5px;\n cursor: pointer;\n}\n.conversation-item-linked {\n color: rgb(48, 48, 235);\n}\n\n.welcome-message img {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; /* Adds some space between the image and the text below */\n position: relative;\n z-index: 10;\n}\n\n.welcome-header-text {\n font-size: larger;\n font-weight: bold;\n}\n\n/* Position the welcome-suggested-questions at the bottom of its container */\n.welcome-suggested-questions {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n margin-top: 30px; /* Push questions down for spacing */\n}\n.welcome-suggested-questions-col {\n display: flex;\n margin-bottom: 10px; /* Space between rows */\n}\n\n/* Flex layout for questions, two per row */\n.welcome-question {\n display: flex;\n flex-direction: column; /* Stack the header and text vertically */\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; /* Adds some space around each question */\n border: solid 1px rgba(41, 28, 28, 0.08);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n\n.welcome-question-header {\n font-size: 12pt;\n font-weight: bold;\n display: block; /* Ensures the header is on its own line */\n}\n\n/* Non-bold text for the content below the header */\n.welcome-question span:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n.messages {\n overflow-y: auto !important; /* enable scrolling if the content overflows */\n overflow-x: hidden !important; /* hide horizontal scrollbar */\n /* border: solid 1px rgba(0, 0, 0, 0.08); */\n margin-bottom: 5px;\n\n margin-top: 2px; /* align it with the top of converation history exactly*/\n\n background-color: #f9f9f9;\n flex: 1 1 auto; /* Take up available space but don't push parent beyond size */\n height: calc(100% - 50px); /* Ensure messages container has a height */\n max-height: 100%; /* Don't exceed parent height */\n scrollbar-width: thin; /* For Firefox */\n scrollbar-color: #d3d3d3 #f8f9fa; /* Thumb color and track color */\n position: relative; /* For proper positioning of scroll icon */\n}\n\n/* For WebKit-based browsers (Chrome, Edge, Safari) */\n.messages::-webkit-scrollbar {\n width: 8px; /* Narrower scrollbar */\n background-color: #f8f9fa; /* Scrollbar track color */\n}\n\n.messages::-webkit-scrollbar-thumb {\n background-color: #d3d3d3; /* Lighter gray scrollbar thumb */\n border-radius: 4px; /* Rounded corners for the thumb */\n}\n\n.messages::-webkit-scrollbar-thumb:hover {\n background-color: #c0c0c0; /* Slightly darker gray on hover */\n}\n\n.messages::-webkit-scrollbar-track {\n background-color: #f8f9fa; /* Background of the scrollbar track */\n}\n\n/* Class for the messages container */\n.messages-container {\n min-height: 20px; /* Ensure container takes space even when empty */\n}\n\n\n\n.new-chat-area {\n display: flex;\n justify-content: space-between; /* Aligns children (img and button) to each end */\n align-items: center; /* Centers children vertically */\n}\n.avatar {\n max-height: 24px;\n margin-right: 10px;\n margin-left: 5px;\n margin-bottom: 3px;\n /* Ensure the image aligns to the left */\n margin-right: auto; /* Pushes everything else to the right */\n}\n\n.conversation-item {\n margin-left: 5px;\n margin-right: 5px;\n padding-top: 10px;\n padding-bottom: 10px;\n padding-left: 5px;\n padding-right: 5px;\n border-radius: 5px;\n cursor: pointer;\n overflow: hidden;\n max-height: 150px;\n font-size: 14px;\n\n display: flex;\n align-items: flex-start; /* Align items to the top */\n\n flex-wrap: wrap; /* Allow items to wrap to the next line */\n}\n\n.text-container {\n flex: 1; /* Take up remaining space */\n display: flex;\n flex-direction: column; /* Stack children vertically */\n}\n\n.text-container textarea {\n resize: none; /* Disable resizing */\n /* Add more styles for the textarea if needed */\n}\n\n.conversation-item > .conversation-icon {\n margin-top: 3px;\n}\n\n.conversation-item span {\n display: inline-block;\n white-space: pre-wrap; /* Allow text to wrap */\n overflow: auto;\n word-wrap: break-word;\n margin-left: 3px; /* Move the text to the right */\n}\n\n.conversation-item:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.conversation-item-selected {\n background-color: rgba(0, 0, 0, 0.15);\n}\n\n\n.conversation-item > .conversation-icon {\n margin-right: 11px;\n}\n.edit-conversation-panel {\n display: flex;\n justify-content: flex-end; /* Align icons to the right */\n margin-top: 2px; /* litle buffer on top */\n margin-right: 2px; /* litle buffer to the right */\n}\n.edit-conversation-panel > .k-icon {\n margin-left: 5px;\n cursor: pointer;\n}\n.edit-conversation-panel > .k-icon:hover {\n color: #ff0000;\n}\n\n\n\n.input-area {\n min-height: 35px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 15px;\n position: sticky;\n bottom: 0;\n background-color: #f9f9f9;\n z-index: 10;\n}\n\n.input-area > .button-area {\n vertical-align: top;\n margin-top: 3px;\n margin-left: -65px;\n}\n/*all buttons in the button area within the input area*/\n.button-area > button {\n width: 30px;\n height: 30px;\n border-radius: 12px;\n margin-left: 3px;\n}\n\n/* Stop button styling */\n.button-area > button.stop-button {\n background-color: #dc3545;\n color: white;\n}\n\n.button-area > button.stop-button:hover {\n background-color: #c82333;\n}\n/* .input-area > button:first-of-type {\n margin-left: -40px;\n}\n.input-area > button:last-child {\n margin-left: -65px;\n}\n.input-area > .share-button {\n margin-left: 10px;\n} */\n\n.text-area-wrapper {\n padding: 3px;\n border: solid 1px rgba(0, 0, 0, 0.08) ;\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; /* Prevent it from growing beyond the container */\n\n overflow: hidden; \n align-items: center;\n\n /*combined width and padding is 800*/\n width: 710px; \n padding-right: 90px\n} \n.text-area-wrapper > textarea {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; /* Initial height */\n\n width: 100%;\n overflow-y: hidden; /* Hide scrollbar */\n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n\n background-color: #f9f9f9;\n}\n\n/* .text-area-wrapper > textarea:disabled {\n background-color: white;\n} */\n\n.input-wrapper {\n flex-grow: 1; /* This will make the input-wrapper take the remaining space */\n height: 100%;\n}\n\n.waiting-for-ai {\n position: absolute;\n display: flex; /* Use flexbox layout */\n bottom: 100px;\n z-index: 999;\n left: 10px; \n}\n \n.scroll-to-bottom-icon {\n position: fixed; /* Fixed positioning to float over content */\n bottom: 120px; /* Position relative to the viewport */\n /* left position will be set dynamically via inline style */\n transform: translateX(-50%); /* Shift it back by half its width to center it */\n z-index: 1000; /* Ensure it stays on top */\n background-color: white; /* Circle background color */\n color: black; /* Icon color */\n border-radius: 50%; /* Makes the background a circle */\n width: 40px; /* Circle size */\n height: 40px; /* Circle size */\n display: flex;\n justify-content: center;\n align-items: center;\n box-shadow: 0px 0px 5px rgba(0,0,0,0.3); /* Subtle shadow for better visibility */\n cursor: pointer;\n opacity: 0.9; /* Slightly transparent */\n}\n\n.loading-convo-messages-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n position: absolute;\n z-index: 1000;\n}\n\n@media (min-width: 600px) {\n .welcome-suggested-questions {\n display: flex;\n flex-wrap: wrap; /* Allows questions to wrap to the next line */\n align-content: flex-end; /* Aligns the content to the bottom */\n }\n}\n \n"] }]
3045
2395
  }], () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.Location }, { type: i0.ChangeDetectorRef }, { type: i3.MJNotificationService }, { type: i4.DialogService }], { AllowSend: [{
3046
2396
  type: Input
3047
2397
  }], Messages: [{
@@ -3138,19 +2488,5 @@ export class SkipChatComponent extends BaseAngularComponent {
3138
2488
  type: ViewChild,
3139
2489
  args: ['splitPanel']
3140
2490
  }] }); })();
3141
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SkipChatComponent, { className: "SkipChatComponent", filePath: "src/lib/skip-chat/skip-chat.component.ts", lineNumber: 49 }); })();
3142
- class TestRunView {
3143
- _rv;
3144
- constructor() {
3145
- this._rv = new RunView();
3146
- }
3147
- runView(params) {
3148
- console.log('Running single view with params:', params);
3149
- return this._rv.RunView(params);
3150
- }
3151
- runViews(params) {
3152
- console.log('Running multiple views with params:', params);
3153
- return this._rv.RunViews(params);
3154
- }
3155
- }
2491
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SkipChatComponent, { className: "SkipChatComponent", filePath: "src/lib/skip-chat/skip-chat.component.ts", lineNumber: 46 }); })();
3156
2492
  //# sourceMappingURL=skip-chat.component.js.map