dp-widgets-framework 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +443 -221
- package/dist/index.js +442 -220
- package/package.json +2 -1
package/dist/index.esm.js
CHANGED
|
@@ -7,7 +7,7 @@ import * as LabelPrimitive from '@radix-ui/react-label';
|
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
8
8
|
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
9
9
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
10
|
-
import { ChevronDown, ChevronUp, Check, AlertCircle, MoveUp, MoveDown, Trash2, Plus, Bot, Type, Layout, LayoutGrid, BarChart as BarChart$1, Filter, Search, ArrowUp, ArrowDown, ChevronRight, RefreshCw,
|
|
10
|
+
import { ChevronDown, ChevronUp, Check, AlertCircle, MoveUp, MoveDown, Trash2, Plus, Bot, Type, Layout, LayoutGrid, BarChart as BarChart$1, Filter, Search, ArrowUp, ArrowDown, ChevronRight, RefreshCw, Loader2, Download, Send, X, AlignVerticalSpaceAround, LineChart as LineChart$1, PieChart as PieChart$1, Table, FileText, SlidersHorizontal, GripHorizontal, Edit, MessageCircleX, ChevronLeft, Maximize2, Grid3X3, Edit2 } from 'lucide-react';
|
|
11
11
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
12
12
|
import { Slot, createSlot, createSlottable } from '@radix-ui/react-slot';
|
|
13
13
|
import { debounce as debounce$1 } from 'lodash';
|
|
@@ -17,6 +17,7 @@ import { v4 } from 'uuid';
|
|
|
17
17
|
import * as ReactDOM from 'react-dom';
|
|
18
18
|
import { TextMessage, Role } from '@copilotkit/runtime-client-gql';
|
|
19
19
|
import { CopilotKit, useCopilotContext, useCoAgent, useCopilotChat } from '@copilotkit/react-core';
|
|
20
|
+
import jsPDF from 'jspdf';
|
|
20
21
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
21
22
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
22
23
|
import { format } from 'date-fns';
|
|
@@ -3774,6 +3775,71 @@ function computeCoordsFromPlacement(_ref, placement, rtl) {
|
|
|
3774
3775
|
return coords;
|
|
3775
3776
|
}
|
|
3776
3777
|
|
|
3778
|
+
/**
|
|
3779
|
+
* Resolves with an object of overflow side offsets that determine how much the
|
|
3780
|
+
* element is overflowing a given clipping boundary on each side.
|
|
3781
|
+
* - positive = overflowing the boundary by that number of pixels
|
|
3782
|
+
* - negative = how many pixels left before it will overflow
|
|
3783
|
+
* - 0 = lies flush with the boundary
|
|
3784
|
+
* @see https://floating-ui.com/docs/detectOverflow
|
|
3785
|
+
*/
|
|
3786
|
+
async function detectOverflow(state, options) {
|
|
3787
|
+
var _await$platform$isEle;
|
|
3788
|
+
if (options === void 0) {
|
|
3789
|
+
options = {};
|
|
3790
|
+
}
|
|
3791
|
+
const {
|
|
3792
|
+
x,
|
|
3793
|
+
y,
|
|
3794
|
+
platform,
|
|
3795
|
+
rects,
|
|
3796
|
+
elements,
|
|
3797
|
+
strategy
|
|
3798
|
+
} = state;
|
|
3799
|
+
const {
|
|
3800
|
+
boundary = 'clippingAncestors',
|
|
3801
|
+
rootBoundary = 'viewport',
|
|
3802
|
+
elementContext = 'floating',
|
|
3803
|
+
altBoundary = false,
|
|
3804
|
+
padding = 0
|
|
3805
|
+
} = evaluate(options, state);
|
|
3806
|
+
const paddingObject = getPaddingObject(padding);
|
|
3807
|
+
const altContext = elementContext === 'floating' ? 'reference' : 'floating';
|
|
3808
|
+
const element = elements[altBoundary ? altContext : elementContext];
|
|
3809
|
+
const clippingClientRect = rectToClientRect(await platform.getClippingRect({
|
|
3810
|
+
element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),
|
|
3811
|
+
boundary,
|
|
3812
|
+
rootBoundary,
|
|
3813
|
+
strategy
|
|
3814
|
+
}));
|
|
3815
|
+
const rect = elementContext === 'floating' ? {
|
|
3816
|
+
x,
|
|
3817
|
+
y,
|
|
3818
|
+
width: rects.floating.width,
|
|
3819
|
+
height: rects.floating.height
|
|
3820
|
+
} : rects.reference;
|
|
3821
|
+
const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
|
|
3822
|
+
const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
|
|
3823
|
+
x: 1,
|
|
3824
|
+
y: 1
|
|
3825
|
+
} : {
|
|
3826
|
+
x: 1,
|
|
3827
|
+
y: 1
|
|
3828
|
+
};
|
|
3829
|
+
const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
|
|
3830
|
+
elements,
|
|
3831
|
+
rect,
|
|
3832
|
+
offsetParent,
|
|
3833
|
+
strategy
|
|
3834
|
+
}) : rect);
|
|
3835
|
+
return {
|
|
3836
|
+
top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
|
|
3837
|
+
bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
|
|
3838
|
+
left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
|
|
3839
|
+
right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
|
|
3840
|
+
};
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3777
3843
|
/**
|
|
3778
3844
|
* Computes the `x` and `y` coordinates that will place the floating element
|
|
3779
3845
|
* next to a given reference element.
|
|
@@ -3803,6 +3869,7 @@ const computePosition$1 = async (reference, floating, config) => {
|
|
|
3803
3869
|
let middlewareData = {};
|
|
3804
3870
|
let resetCount = 0;
|
|
3805
3871
|
for (let i = 0; i < validMiddleware.length; i++) {
|
|
3872
|
+
var _platform$detectOverf;
|
|
3806
3873
|
const {
|
|
3807
3874
|
name,
|
|
3808
3875
|
fn
|
|
@@ -3820,7 +3887,10 @@ const computePosition$1 = async (reference, floating, config) => {
|
|
|
3820
3887
|
strategy,
|
|
3821
3888
|
middlewareData,
|
|
3822
3889
|
rects,
|
|
3823
|
-
platform
|
|
3890
|
+
platform: {
|
|
3891
|
+
...platform,
|
|
3892
|
+
detectOverflow: (_platform$detectOverf = platform.detectOverflow) != null ? _platform$detectOverf : detectOverflow
|
|
3893
|
+
},
|
|
3824
3894
|
elements: {
|
|
3825
3895
|
reference,
|
|
3826
3896
|
floating
|
|
@@ -3865,71 +3935,6 @@ const computePosition$1 = async (reference, floating, config) => {
|
|
|
3865
3935
|
};
|
|
3866
3936
|
};
|
|
3867
3937
|
|
|
3868
|
-
/**
|
|
3869
|
-
* Resolves with an object of overflow side offsets that determine how much the
|
|
3870
|
-
* element is overflowing a given clipping boundary on each side.
|
|
3871
|
-
* - positive = overflowing the boundary by that number of pixels
|
|
3872
|
-
* - negative = how many pixels left before it will overflow
|
|
3873
|
-
* - 0 = lies flush with the boundary
|
|
3874
|
-
* @see https://floating-ui.com/docs/detectOverflow
|
|
3875
|
-
*/
|
|
3876
|
-
async function detectOverflow(state, options) {
|
|
3877
|
-
var _await$platform$isEle;
|
|
3878
|
-
if (options === void 0) {
|
|
3879
|
-
options = {};
|
|
3880
|
-
}
|
|
3881
|
-
const {
|
|
3882
|
-
x,
|
|
3883
|
-
y,
|
|
3884
|
-
platform,
|
|
3885
|
-
rects,
|
|
3886
|
-
elements,
|
|
3887
|
-
strategy
|
|
3888
|
-
} = state;
|
|
3889
|
-
const {
|
|
3890
|
-
boundary = 'clippingAncestors',
|
|
3891
|
-
rootBoundary = 'viewport',
|
|
3892
|
-
elementContext = 'floating',
|
|
3893
|
-
altBoundary = false,
|
|
3894
|
-
padding = 0
|
|
3895
|
-
} = evaluate(options, state);
|
|
3896
|
-
const paddingObject = getPaddingObject(padding);
|
|
3897
|
-
const altContext = elementContext === 'floating' ? 'reference' : 'floating';
|
|
3898
|
-
const element = elements[altBoundary ? altContext : elementContext];
|
|
3899
|
-
const clippingClientRect = rectToClientRect(await platform.getClippingRect({
|
|
3900
|
-
element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),
|
|
3901
|
-
boundary,
|
|
3902
|
-
rootBoundary,
|
|
3903
|
-
strategy
|
|
3904
|
-
}));
|
|
3905
|
-
const rect = elementContext === 'floating' ? {
|
|
3906
|
-
x,
|
|
3907
|
-
y,
|
|
3908
|
-
width: rects.floating.width,
|
|
3909
|
-
height: rects.floating.height
|
|
3910
|
-
} : rects.reference;
|
|
3911
|
-
const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
|
|
3912
|
-
const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
|
|
3913
|
-
x: 1,
|
|
3914
|
-
y: 1
|
|
3915
|
-
} : {
|
|
3916
|
-
x: 1,
|
|
3917
|
-
y: 1
|
|
3918
|
-
};
|
|
3919
|
-
const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
|
|
3920
|
-
elements,
|
|
3921
|
-
rect,
|
|
3922
|
-
offsetParent,
|
|
3923
|
-
strategy
|
|
3924
|
-
}) : rect);
|
|
3925
|
-
return {
|
|
3926
|
-
top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
|
|
3927
|
-
bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
|
|
3928
|
-
left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
|
|
3929
|
-
right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
|
|
3930
|
-
};
|
|
3931
|
-
}
|
|
3932
|
-
|
|
3933
3938
|
/**
|
|
3934
3939
|
* Provides data to position an inner element of the floating element so that it
|
|
3935
3940
|
* appears centered to the reference element.
|
|
@@ -4062,7 +4067,7 @@ const flip$2 = function (options) {
|
|
|
4062
4067
|
fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
|
|
4063
4068
|
}
|
|
4064
4069
|
const placements = [initialPlacement, ...fallbackPlacements];
|
|
4065
|
-
const overflow = await detectOverflow(state, detectOverflowOptions);
|
|
4070
|
+
const overflow = await platform.detectOverflow(state, detectOverflowOptions);
|
|
4066
4071
|
const overflows = [];
|
|
4067
4072
|
let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
|
|
4068
4073
|
if (checkMainAxis) {
|
|
@@ -4169,7 +4174,8 @@ const hide$2 = function (options) {
|
|
|
4169
4174
|
options,
|
|
4170
4175
|
async fn(state) {
|
|
4171
4176
|
const {
|
|
4172
|
-
rects
|
|
4177
|
+
rects,
|
|
4178
|
+
platform
|
|
4173
4179
|
} = state;
|
|
4174
4180
|
const {
|
|
4175
4181
|
strategy = 'referenceHidden',
|
|
@@ -4178,7 +4184,7 @@ const hide$2 = function (options) {
|
|
|
4178
4184
|
switch (strategy) {
|
|
4179
4185
|
case 'referenceHidden':
|
|
4180
4186
|
{
|
|
4181
|
-
const overflow = await detectOverflow(state, {
|
|
4187
|
+
const overflow = await platform.detectOverflow(state, {
|
|
4182
4188
|
...detectOverflowOptions,
|
|
4183
4189
|
elementContext: 'reference'
|
|
4184
4190
|
});
|
|
@@ -4192,7 +4198,7 @@ const hide$2 = function (options) {
|
|
|
4192
4198
|
}
|
|
4193
4199
|
case 'escaped':
|
|
4194
4200
|
{
|
|
4195
|
-
const overflow = await detectOverflow(state, {
|
|
4201
|
+
const overflow = await platform.detectOverflow(state, {
|
|
4196
4202
|
...detectOverflowOptions,
|
|
4197
4203
|
altBoundary: true
|
|
4198
4204
|
});
|
|
@@ -4315,7 +4321,8 @@ const shift$2 = function (options) {
|
|
|
4315
4321
|
const {
|
|
4316
4322
|
x,
|
|
4317
4323
|
y,
|
|
4318
|
-
placement
|
|
4324
|
+
placement,
|
|
4325
|
+
platform
|
|
4319
4326
|
} = state;
|
|
4320
4327
|
const {
|
|
4321
4328
|
mainAxis: checkMainAxis = true,
|
|
@@ -4338,7 +4345,7 @@ const shift$2 = function (options) {
|
|
|
4338
4345
|
x,
|
|
4339
4346
|
y
|
|
4340
4347
|
};
|
|
4341
|
-
const overflow = await detectOverflow(state, detectOverflowOptions);
|
|
4348
|
+
const overflow = await platform.detectOverflow(state, detectOverflowOptions);
|
|
4342
4349
|
const crossAxis = getSideAxis(getSide(placement));
|
|
4343
4350
|
const mainAxis = getOppositeAxis(crossAxis);
|
|
4344
4351
|
let mainAxisCoord = coords[mainAxis];
|
|
@@ -4470,7 +4477,7 @@ const size$2 = function (options) {
|
|
|
4470
4477
|
apply = () => {},
|
|
4471
4478
|
...detectOverflowOptions
|
|
4472
4479
|
} = evaluate(options, state);
|
|
4473
|
-
const overflow = await detectOverflow(state, detectOverflowOptions);
|
|
4480
|
+
const overflow = await platform.detectOverflow(state, detectOverflowOptions);
|
|
4474
4481
|
const side = getSide(placement);
|
|
4475
4482
|
const alignment = getAlignment(placement);
|
|
4476
4483
|
const isYAxis = getSideAxis(placement) === 'y';
|
|
@@ -44409,6 +44416,175 @@ function SpacerWidget({ widget }) {
|
|
|
44409
44416
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full", style: styles });
|
|
44410
44417
|
}
|
|
44411
44418
|
|
|
44419
|
+
const WISENBAKER_PRIMARY = "#8f002d";
|
|
44420
|
+
const WISENBAKER_GRAY = "#475569";
|
|
44421
|
+
function parseMarkdown(text) {
|
|
44422
|
+
const segments = [];
|
|
44423
|
+
const regex = /\*\*(.+?)\*\*/g;
|
|
44424
|
+
let lastIndex = 0;
|
|
44425
|
+
let match;
|
|
44426
|
+
while ((match = regex.exec(text)) !== null) {
|
|
44427
|
+
if (match.index > lastIndex) {
|
|
44428
|
+
segments.push({ text: text.slice(lastIndex, match.index), bold: false });
|
|
44429
|
+
}
|
|
44430
|
+
segments.push({ text: match[1], bold: true });
|
|
44431
|
+
lastIndex = regex.lastIndex;
|
|
44432
|
+
}
|
|
44433
|
+
if (lastIndex < text.length) {
|
|
44434
|
+
segments.push({ text: text.slice(lastIndex), bold: false });
|
|
44435
|
+
}
|
|
44436
|
+
return segments.length > 0 ? segments : [{ text, bold: false }];
|
|
44437
|
+
}
|
|
44438
|
+
function formatLine(line) {
|
|
44439
|
+
const bulletMatch = line.match(/^(\s*)[\*\-•]\s+(.*)$/);
|
|
44440
|
+
if (bulletMatch) {
|
|
44441
|
+
const indent = bulletMatch[1].length;
|
|
44442
|
+
return { text: bulletMatch[2], isBullet: true, indent };
|
|
44443
|
+
}
|
|
44444
|
+
const numberedMatch = line.match(/^(\s*)\d+\.\s+(.*)$/);
|
|
44445
|
+
if (numberedMatch) {
|
|
44446
|
+
const indent = numberedMatch[1].length;
|
|
44447
|
+
return { text: numberedMatch[2], isBullet: true, indent };
|
|
44448
|
+
}
|
|
44449
|
+
return { text: line, isBullet: false, indent: 0 };
|
|
44450
|
+
}
|
|
44451
|
+
function generateExportFilename(widgetId) {
|
|
44452
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
44453
|
+
return `NSight_Chat_Export_${widgetId}_${date}.pdf`;
|
|
44454
|
+
}
|
|
44455
|
+
function exportChatToPDF(options) {
|
|
44456
|
+
const { widgetId, messages, dashboardName } = options;
|
|
44457
|
+
const doc = new jsPDF();
|
|
44458
|
+
let yPosition = 25;
|
|
44459
|
+
const pageHeight = doc.internal.pageSize.height;
|
|
44460
|
+
const pageWidth = doc.internal.pageSize.width;
|
|
44461
|
+
const margin = 20;
|
|
44462
|
+
const contentWidth = pageWidth - margin * 2;
|
|
44463
|
+
const maxWidth = contentWidth - 10;
|
|
44464
|
+
const checkPageBreak = (requiredSpace = 20) => {
|
|
44465
|
+
if (yPosition > pageHeight - requiredSpace) {
|
|
44466
|
+
doc.addPage();
|
|
44467
|
+
yPosition = 25;
|
|
44468
|
+
}
|
|
44469
|
+
};
|
|
44470
|
+
const renderFormattedText = (text, x, maxW, baseIndent = 0) => {
|
|
44471
|
+
const lines = text.split("\n");
|
|
44472
|
+
lines.forEach((line) => {
|
|
44473
|
+
const { text: lineText, isBullet, indent } = formatLine(line);
|
|
44474
|
+
const lineIndent = x + baseIndent + indent * 2;
|
|
44475
|
+
if (isBullet) {
|
|
44476
|
+
checkPageBreak(10);
|
|
44477
|
+
doc.setFont("helvetica", "normal");
|
|
44478
|
+
doc.text("\u2022", lineIndent, yPosition);
|
|
44479
|
+
}
|
|
44480
|
+
const textX = isBullet ? lineIndent + 5 : lineIndent;
|
|
44481
|
+
const textMaxWidth = maxW - (textX - x);
|
|
44482
|
+
const segments = parseMarkdown(lineText);
|
|
44483
|
+
let currentLine = "";
|
|
44484
|
+
let currentX = textX;
|
|
44485
|
+
segments.forEach((segment) => {
|
|
44486
|
+
doc.setFont("helvetica", segment.bold ? "bold" : "normal");
|
|
44487
|
+
const words = segment.text.split(" ");
|
|
44488
|
+
words.forEach((word, wordIndex) => {
|
|
44489
|
+
const testLine = currentLine + (currentLine ? " " : "") + word;
|
|
44490
|
+
const testWidth = doc.getTextWidth(testLine);
|
|
44491
|
+
if (testWidth > textMaxWidth && currentLine) {
|
|
44492
|
+
checkPageBreak(10);
|
|
44493
|
+
doc.text(currentLine, currentX, yPosition);
|
|
44494
|
+
yPosition += 5;
|
|
44495
|
+
currentLine = word;
|
|
44496
|
+
currentX = isBullet ? lineIndent + 5 : x + baseIndent;
|
|
44497
|
+
} else {
|
|
44498
|
+
currentLine = testLine;
|
|
44499
|
+
}
|
|
44500
|
+
});
|
|
44501
|
+
});
|
|
44502
|
+
if (currentLine) {
|
|
44503
|
+
checkPageBreak(10);
|
|
44504
|
+
const lastSegment = segments[segments.length - 1];
|
|
44505
|
+
doc.setFont("helvetica", (lastSegment == null ? void 0 : lastSegment.bold) ? "bold" : "normal");
|
|
44506
|
+
doc.text(currentLine, currentX, yPosition);
|
|
44507
|
+
yPosition += 5;
|
|
44508
|
+
}
|
|
44509
|
+
});
|
|
44510
|
+
};
|
|
44511
|
+
doc.setFontSize(18);
|
|
44512
|
+
doc.setFont("helvetica", "bold");
|
|
44513
|
+
doc.setTextColor(WISENBAKER_PRIMARY);
|
|
44514
|
+
doc.text("Wisenbaker AI Analytics", margin, yPosition);
|
|
44515
|
+
yPosition += 8;
|
|
44516
|
+
doc.setFontSize(11);
|
|
44517
|
+
doc.setFont("helvetica", "normal");
|
|
44518
|
+
doc.setTextColor(WISENBAKER_GRAY);
|
|
44519
|
+
doc.text("Chat Export", margin, yPosition);
|
|
44520
|
+
yPosition += 12;
|
|
44521
|
+
doc.setFontSize(9);
|
|
44522
|
+
doc.setTextColor("#666666");
|
|
44523
|
+
if (dashboardName) {
|
|
44524
|
+
doc.setFont("helvetica", "bold");
|
|
44525
|
+
doc.text("Dashboard:", margin, yPosition);
|
|
44526
|
+
doc.setFont("helvetica", "normal");
|
|
44527
|
+
doc.text(dashboardName, margin + 38, yPosition);
|
|
44528
|
+
yPosition += 5;
|
|
44529
|
+
}
|
|
44530
|
+
doc.setFont("helvetica", "bold");
|
|
44531
|
+
doc.text("Exported:", margin, yPosition);
|
|
44532
|
+
doc.setFont("helvetica", "normal");
|
|
44533
|
+
doc.text((/* @__PURE__ */ new Date()).toLocaleString(), margin + 38, yPosition);
|
|
44534
|
+
doc.setFont("helvetica", "bold");
|
|
44535
|
+
doc.text("Messages:", margin + 100, yPosition);
|
|
44536
|
+
doc.setFont("helvetica", "normal");
|
|
44537
|
+
doc.text(String(messages.length), margin + 130, yPosition);
|
|
44538
|
+
yPosition += 12;
|
|
44539
|
+
doc.setDrawColor(200, 200, 200);
|
|
44540
|
+
doc.setLineWidth(0.5);
|
|
44541
|
+
doc.line(margin, yPosition, pageWidth - margin, yPosition);
|
|
44542
|
+
yPosition += 8;
|
|
44543
|
+
messages.forEach((message, index) => {
|
|
44544
|
+
checkPageBreak(30);
|
|
44545
|
+
const isUser = message.role === "user";
|
|
44546
|
+
const roleLabel = isUser ? "You" : "AI Assistant";
|
|
44547
|
+
const timestamp = message.createdAt ? new Date(message.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "";
|
|
44548
|
+
const bgColor = isUser ? [143, 0, 45] : [241, 243, 245];
|
|
44549
|
+
doc.setFillColor(bgColor[0], bgColor[1], bgColor[2]);
|
|
44550
|
+
doc.setFontSize(9);
|
|
44551
|
+
doc.setFont("helvetica", "bold");
|
|
44552
|
+
doc.setTextColor(isUser ? WISENBAKER_PRIMARY : WISENBAKER_GRAY);
|
|
44553
|
+
doc.text(roleLabel, margin, yPosition);
|
|
44554
|
+
if (timestamp) {
|
|
44555
|
+
doc.setFont("helvetica", "normal");
|
|
44556
|
+
doc.setTextColor("#888888");
|
|
44557
|
+
doc.text(timestamp, margin + doc.getTextWidth(roleLabel) + 5, yPosition);
|
|
44558
|
+
}
|
|
44559
|
+
yPosition += 6;
|
|
44560
|
+
doc.setFontSize(10);
|
|
44561
|
+
doc.setTextColor("#333333");
|
|
44562
|
+
doc.setFont("helvetica", "normal");
|
|
44563
|
+
renderFormattedText(message.content, margin + 5, maxWidth - 5, 0);
|
|
44564
|
+
yPosition += 8;
|
|
44565
|
+
if (index < messages.length - 1) {
|
|
44566
|
+
doc.setDrawColor(230, 230, 230);
|
|
44567
|
+
doc.setLineWidth(0.3);
|
|
44568
|
+
doc.line(margin + 10, yPosition - 4, pageWidth - margin - 10, yPosition - 4);
|
|
44569
|
+
}
|
|
44570
|
+
});
|
|
44571
|
+
const totalPages = doc.getNumberOfPages();
|
|
44572
|
+
for (let i = 1; i <= totalPages; i++) {
|
|
44573
|
+
doc.setPage(i);
|
|
44574
|
+
doc.setFontSize(8);
|
|
44575
|
+
doc.setTextColor("#999999");
|
|
44576
|
+
doc.setFont("helvetica", "normal");
|
|
44577
|
+
doc.text(
|
|
44578
|
+
`Wisenbaker AI Analytics \u2022 Page ${i} of ${totalPages}`,
|
|
44579
|
+
pageWidth / 2,
|
|
44580
|
+
pageHeight - 10,
|
|
44581
|
+
{ align: "center" }
|
|
44582
|
+
);
|
|
44583
|
+
}
|
|
44584
|
+
const filename = generateExportFilename(widgetId);
|
|
44585
|
+
doc.save(filename);
|
|
44586
|
+
}
|
|
44587
|
+
|
|
44412
44588
|
var __defProp$b = Object.defineProperty;
|
|
44413
44589
|
var __defProps$9 = Object.defineProperties;
|
|
44414
44590
|
var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
|
|
@@ -44457,7 +44633,8 @@ function CopilotKitChatbot({
|
|
|
44457
44633
|
styles,
|
|
44458
44634
|
onResetReady,
|
|
44459
44635
|
widgetIds,
|
|
44460
|
-
datasetId
|
|
44636
|
+
datasetId,
|
|
44637
|
+
dashboardName
|
|
44461
44638
|
}) {
|
|
44462
44639
|
var _a, _b, _c, _d;
|
|
44463
44640
|
const { threadId, setThreadId } = useCopilotContext();
|
|
@@ -44474,7 +44651,24 @@ function CopilotKitChatbot({
|
|
|
44474
44651
|
const { reset, visibleMessages, appendMessage, isLoading } = useCopilotChat();
|
|
44475
44652
|
const [inputValue, setInputValue] = useState("");
|
|
44476
44653
|
const [chatMessages, setChatMessages] = useState([]);
|
|
44654
|
+
const [isExporting, setIsExporting] = useState(false);
|
|
44477
44655
|
const messagesEndRef = React__default.useRef(null);
|
|
44656
|
+
const handleExport = async () => {
|
|
44657
|
+
if (chatMessages.length === 0) return;
|
|
44658
|
+
setIsExporting(true);
|
|
44659
|
+
try {
|
|
44660
|
+
exportChatToPDF({
|
|
44661
|
+
widgetId: widget.id,
|
|
44662
|
+
widgetTitle: widget.title,
|
|
44663
|
+
messages: chatMessages,
|
|
44664
|
+
dashboardName
|
|
44665
|
+
});
|
|
44666
|
+
} catch (error) {
|
|
44667
|
+
console.error("Export failed:", error);
|
|
44668
|
+
} finally {
|
|
44669
|
+
setIsExporting(false);
|
|
44670
|
+
}
|
|
44671
|
+
};
|
|
44478
44672
|
const scrollToBottom = () => {
|
|
44479
44673
|
var _a2;
|
|
44480
44674
|
const el = messagesEndRef.current;
|
|
@@ -44549,6 +44743,25 @@ function CopilotKitChatbot({
|
|
|
44549
44743
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium", children: widget.title })
|
|
44550
44744
|
] }) }),
|
|
44551
44745
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 h-full flex flex-col", children: [
|
|
44746
|
+
chatMessages.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-start px-4 py-2 border-b border-gray-100", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
44747
|
+
"button",
|
|
44748
|
+
{
|
|
44749
|
+
onClick: handleExport,
|
|
44750
|
+
disabled: isExporting,
|
|
44751
|
+
className: cn(
|
|
44752
|
+
"flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md",
|
|
44753
|
+
"bg-gray-100 border border-gray-200",
|
|
44754
|
+
"text-gray-700 hover:bg-gray-200 hover:border-gray-300",
|
|
44755
|
+
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
44756
|
+
"transition-colors duration-150"
|
|
44757
|
+
),
|
|
44758
|
+
title: "Export conversation as PDF",
|
|
44759
|
+
children: [
|
|
44760
|
+
isExporting ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "h-3.5 w-3.5" }),
|
|
44761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Export PDF" })
|
|
44762
|
+
]
|
|
44763
|
+
}
|
|
44764
|
+
) }),
|
|
44552
44765
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: chatMessages.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-gray-500 text-xs mt-8", children: ((_b = widget.config) == null ? void 0 : _b.copilotInitialMessage) || ((_c = widget.config) == null ? void 0 : _c.placeholder) || "How can I help you today?" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
44553
44766
|
chatMessages.map((message) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
44554
44767
|
"div",
|
|
@@ -44624,7 +44837,8 @@ function ChatbotWidget({
|
|
|
44624
44837
|
widgetBackendUrl,
|
|
44625
44838
|
onResetReady,
|
|
44626
44839
|
widgetIds,
|
|
44627
|
-
datasetId
|
|
44840
|
+
datasetId,
|
|
44841
|
+
dashboardName
|
|
44628
44842
|
}) {
|
|
44629
44843
|
var _a, _b;
|
|
44630
44844
|
const styles = getStyleValues$4((_a = widget.config) == null ? void 0 : _a.styles);
|
|
@@ -44648,7 +44862,8 @@ function ChatbotWidget({
|
|
|
44648
44862
|
styles,
|
|
44649
44863
|
onResetReady,
|
|
44650
44864
|
widgetIds,
|
|
44651
|
-
datasetId
|
|
44865
|
+
datasetId,
|
|
44866
|
+
dashboardName
|
|
44652
44867
|
}
|
|
44653
44868
|
)
|
|
44654
44869
|
}
|
|
@@ -47165,7 +47380,8 @@ function WidgetRenderer({
|
|
|
47165
47380
|
datasetId,
|
|
47166
47381
|
pageId,
|
|
47167
47382
|
onApplyFilters,
|
|
47168
|
-
isEditing = false
|
|
47383
|
+
isEditing = false,
|
|
47384
|
+
dashboardName
|
|
47169
47385
|
}) {
|
|
47170
47386
|
const handleConfigUpdate = (config) => {
|
|
47171
47387
|
if (onConfigUpdate) {
|
|
@@ -47197,7 +47413,7 @@ function WidgetRenderer({
|
|
|
47197
47413
|
}
|
|
47198
47414
|
);
|
|
47199
47415
|
case "chatbot":
|
|
47200
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(ChatbotWidget, { widget, showHeader: false, widgetBackendUrl, onResetReady, widgetIds, datasetId });
|
|
47416
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(ChatbotWidget, { widget, showHeader: false, widgetBackendUrl, onResetReady, widgetIds, datasetId, dashboardName });
|
|
47201
47417
|
case "filters":
|
|
47202
47418
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
47203
47419
|
FiltersWidget,
|
|
@@ -48806,7 +49022,7 @@ function WidgetDashboard({
|
|
|
48806
49022
|
containerPadding: [0, 0],
|
|
48807
49023
|
margin: [16, 16],
|
|
48808
49024
|
children: displayWidgets.map((w) => {
|
|
48809
|
-
var _a, _b;
|
|
49025
|
+
var _a, _b, _c;
|
|
48810
49026
|
const filterStatus = w.type === "agent" ? getWidgetFilterStatus(w.id) : null;
|
|
48811
49027
|
const badgeInfo = filterStatus ? getFilterStatusBadge(filterStatus.status) : null;
|
|
48812
49028
|
const isFocusMode = focusWidgetId && w.id === focusWidgetId;
|
|
@@ -48845,7 +49061,7 @@ function WidgetDashboard({
|
|
|
48845
49061
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { onClick: () => handleClearChat(w == null ? void 0 : w.id), onMouseOver: () => setVisibleClearButton(w == null ? void 0 : w.id), onMouseLeave: () => setVisibleClearButton(""), className: "absolute top-[12px] right-0 z-40 flex align-middle justify-center gap-2 text-sm px-4 py-2 border-primary-300 rounded-l-sm w-fit bg-primary-700 text-white cursor-pointer shadow-md transition-all", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MessageCircleX, { className: "w-5 h-5" }) }),
|
|
48846
49062
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `absolute top-[56px] right-[16px] z-50 w-max py-1 text-xs px-2 rounded-sm text-white bg-gray-950 ${visibleClearButton === (w == null ? void 0 : w.id) ? "block" : "hidden"}`, children: "Clear Chat" })
|
|
48847
49063
|
] }),
|
|
48848
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(WidgetRenderer, { widget: w, widgetBackendUrl, onResetReady: handleResetReady, widgetIds: widgets.filter((widget) => widget.type !== "chatbot").map((widget) => widget.id), datasetId, pageId, onApplyFilters, isEditing })
|
|
49064
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(WidgetRenderer, { widget: w, widgetBackendUrl, onResetReady: handleResetReady, widgetIds: widgets.filter((widget) => widget.type !== "chatbot").map((widget) => widget.id), datasetId, pageId, onApplyFilters, isEditing, dashboardName: ((_c = pageData == null ? void 0 : pageData.basic) == null ? void 0 : _c.title) || (pageData == null ? void 0 : pageData.name) || (pageData == null ? void 0 : pageData.title) })
|
|
48849
49065
|
] })
|
|
48850
49066
|
] }, w.id);
|
|
48851
49067
|
})
|
|
@@ -48946,7 +49162,7 @@ function PresentationMode({
|
|
|
48946
49162
|
return;
|
|
48947
49163
|
}
|
|
48948
49164
|
item.style.cursor = "pointer";
|
|
48949
|
-
item.style.boxShadow = "0 0 0 3px var(--primary-500
|
|
49165
|
+
item.style.boxShadow = "0 0 0 3px var(--primary-500), 0 10px 30px -5px rgba(0, 0, 0, 0.2)";
|
|
48950
49166
|
item.style.transition = "box-shadow 0.2s ease-out";
|
|
48951
49167
|
item.style.zIndex = "10";
|
|
48952
49168
|
};
|
|
@@ -49064,156 +49280,162 @@ function PresentationMode({
|
|
|
49064
49280
|
}, [isOpen]);
|
|
49065
49281
|
if (!isOpen) return null;
|
|
49066
49282
|
const currentFocusWidget = focusableWidgets[currentFocusIndex];
|
|
49067
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49068
|
-
|
|
49069
|
-
|
|
49070
|
-
|
|
49071
|
-
|
|
49072
|
-
|
|
49073
|
-
|
|
49074
|
-
|
|
49075
|
-
|
|
49076
|
-
] }),
|
|
49077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49078
|
-
"button",
|
|
49079
|
-
{
|
|
49080
|
-
onClick: onClose,
|
|
49081
|
-
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
49082
|
-
"aria-label": "Close presentation",
|
|
49083
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-6 h-6 text-gray-600" })
|
|
49084
|
-
}
|
|
49085
|
-
)
|
|
49086
|
-
] }),
|
|
49087
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: `flex-1 min-h-0 ${viewMode === "grid" ? "overflow-auto bg-gray-50 p-6" : "overflow-hidden bg-gray-100"}`, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
49088
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 border-4 border-primary-600 border-t-transparent rounded-full animate-spin" }),
|
|
49089
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600", children: "Loading widgets..." })
|
|
49090
|
-
] }) }) : viewMode === "grid" ? (
|
|
49091
|
-
/* Grid View - Show all widgets using WidgetDashboard */
|
|
49092
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full relative", ref: gridContainerRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49093
|
-
WidgetDashboard,
|
|
49094
|
-
{
|
|
49095
|
-
pageId,
|
|
49096
|
-
isEditing: false,
|
|
49097
|
-
selectedWidget: null,
|
|
49098
|
-
onWidgetSelect: () => {
|
|
49099
|
-
},
|
|
49100
|
-
openWidgetPallete: false,
|
|
49101
|
-
onCloseWidgetPallete: () => {
|
|
49102
|
-
},
|
|
49103
|
-
onApplyFilters: () => {
|
|
49104
|
-
},
|
|
49105
|
-
isApplyingFilters: false,
|
|
49106
|
-
onSaveLayoutReady: () => {
|
|
49107
|
-
},
|
|
49108
|
-
widgetBackendUrl
|
|
49109
|
-
},
|
|
49110
|
-
`presentation-grid-${pageId}`
|
|
49111
|
-
) })
|
|
49112
|
-
) : (
|
|
49113
|
-
/* Focus View - Show one widget at a time */
|
|
49114
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full flex flex-col", ref: focusContainerRef, children: focusableWidgets.length > 0 && currentFocusWidget ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-h-0", children: [
|
|
49115
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "shrink-0 bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between", children: [
|
|
49116
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49117
|
-
"button",
|
|
49118
|
-
{
|
|
49119
|
-
onClick: () => setCurrentFocusIndex((prev) => prev > 0 ? prev - 1 : focusableWidgets.length - 1),
|
|
49120
|
-
className: "p-2 rounded-full hover:bg-gray-100 transition-colors disabled:opacity-30",
|
|
49121
|
-
disabled: focusableWidgets.length <= 1,
|
|
49122
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-5 h-5 text-gray-600" })
|
|
49123
|
-
}
|
|
49124
|
-
),
|
|
49125
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-500", children: [
|
|
49126
|
-
currentFocusIndex + 1,
|
|
49127
|
-
" of ",
|
|
49128
|
-
focusableWidgets.length
|
|
49283
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49284
|
+
"div",
|
|
49285
|
+
{
|
|
49286
|
+
className: `fixed inset-0 z-50 bg-white flex flex-col ${laserPointerActive ? "[&_*]:!cursor-none !cursor-none" : ""}`,
|
|
49287
|
+
children: [
|
|
49288
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "flex items-center justify-between px-6 py-4 border-b border-gray-200 bg-white shrink-0", children: [
|
|
49289
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
|
|
49290
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xl font-bold text-primary-700 tracking-wide", children: branding.title }),
|
|
49291
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-primary-500 tracking-[0.2em] -mt-1", children: branding.subtitle })
|
|
49129
49292
|
] }) }),
|
|
49293
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute left-1/2 transform -translate-x-1/2 text-center", children: [
|
|
49294
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-lg font-bold text-gray-900 uppercase tracking-wide", children: dashboardTitle }),
|
|
49295
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-12 h-1 bg-primary-600 mx-auto mt-1 rounded" })
|
|
49296
|
+
] }),
|
|
49130
49297
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49131
49298
|
"button",
|
|
49132
49299
|
{
|
|
49133
|
-
onClick:
|
|
49134
|
-
className: "p-2
|
|
49135
|
-
|
|
49136
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49300
|
+
onClick: onClose,
|
|
49301
|
+
className: "p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
49302
|
+
"aria-label": "Close presentation",
|
|
49303
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-6 h-6 text-gray-600" })
|
|
49137
49304
|
}
|
|
49138
49305
|
)
|
|
49139
49306
|
] }),
|
|
49140
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
49141
|
-
|
|
49142
|
-
{
|
|
49143
|
-
|
|
49144
|
-
|
|
49145
|
-
|
|
49146
|
-
|
|
49147
|
-
|
|
49148
|
-
|
|
49149
|
-
|
|
49150
|
-
|
|
49151
|
-
|
|
49152
|
-
|
|
49153
|
-
|
|
49154
|
-
|
|
49155
|
-
|
|
49156
|
-
|
|
49157
|
-
|
|
49158
|
-
|
|
49159
|
-
|
|
49160
|
-
|
|
49161
|
-
|
|
49162
|
-
|
|
49163
|
-
|
|
49164
|
-
|
|
49165
|
-
|
|
49166
|
-
|
|
49167
|
-
|
|
49168
|
-
|
|
49169
|
-
|
|
49170
|
-
|
|
49307
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: `flex-1 min-h-0 ${viewMode === "grid" ? "overflow-auto bg-gray-50 p-6" : "overflow-hidden bg-gray-100"}`, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
49308
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 border-4 border-primary-600 border-t-transparent rounded-full animate-spin" }),
|
|
49309
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600", children: "Loading widgets..." })
|
|
49310
|
+
] }) }) : viewMode === "grid" ? (
|
|
49311
|
+
/* Grid View - Show all widgets using WidgetDashboard */
|
|
49312
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full relative", ref: gridContainerRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49313
|
+
WidgetDashboard,
|
|
49314
|
+
{
|
|
49315
|
+
pageId,
|
|
49316
|
+
isEditing: false,
|
|
49317
|
+
selectedWidget: null,
|
|
49318
|
+
onWidgetSelect: () => {
|
|
49319
|
+
},
|
|
49320
|
+
openWidgetPallete: false,
|
|
49321
|
+
onCloseWidgetPallete: () => {
|
|
49322
|
+
},
|
|
49323
|
+
onApplyFilters: () => {
|
|
49324
|
+
},
|
|
49325
|
+
isApplyingFilters: false,
|
|
49326
|
+
onSaveLayoutReady: () => {
|
|
49327
|
+
},
|
|
49328
|
+
widgetBackendUrl
|
|
49329
|
+
},
|
|
49330
|
+
`presentation-grid-${pageId}`
|
|
49331
|
+
) })
|
|
49332
|
+
) : (
|
|
49333
|
+
/* Focus View - Show one widget at a time */
|
|
49334
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full flex flex-col", ref: focusContainerRef, children: focusableWidgets.length > 0 && currentFocusWidget ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col min-h-0", children: [
|
|
49335
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "shrink-0 bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between", children: [
|
|
49336
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49337
|
+
"button",
|
|
49338
|
+
{
|
|
49339
|
+
onClick: () => setCurrentFocusIndex((prev) => prev > 0 ? prev - 1 : focusableWidgets.length - 1),
|
|
49340
|
+
className: "p-2 rounded-full hover:bg-gray-100 transition-colors disabled:opacity-30",
|
|
49341
|
+
disabled: focusableWidgets.length <= 1,
|
|
49342
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-5 h-5 text-gray-600" })
|
|
49343
|
+
}
|
|
49344
|
+
),
|
|
49345
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-500", children: [
|
|
49346
|
+
currentFocusIndex + 1,
|
|
49347
|
+
" of ",
|
|
49348
|
+
focusableWidgets.length
|
|
49349
|
+
] }) }),
|
|
49350
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49351
|
+
"button",
|
|
49352
|
+
{
|
|
49353
|
+
onClick: () => setCurrentFocusIndex((prev) => prev < focusableWidgets.length - 1 ? prev + 1 : 0),
|
|
49354
|
+
className: "p-2 rounded-full hover:bg-gray-100 transition-colors disabled:opacity-30",
|
|
49355
|
+
disabled: focusableWidgets.length <= 1,
|
|
49356
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-5 h-5 text-gray-600" })
|
|
49357
|
+
}
|
|
49358
|
+
)
|
|
49359
|
+
] }),
|
|
49360
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 bg-white p-6 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full w-full rounded-xl border border-gray-200 bg-white shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49361
|
+
WidgetRenderer,
|
|
49362
|
+
{
|
|
49363
|
+
widget: currentFocusWidget,
|
|
49364
|
+
widgetBackendUrl,
|
|
49365
|
+
pageId,
|
|
49366
|
+
isEditing: false
|
|
49367
|
+
},
|
|
49368
|
+
`focus-widget-${currentFocusWidget.id}`
|
|
49369
|
+
) }) })
|
|
49370
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-gray-500", children: [
|
|
49371
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-12 h-12 mx-auto mb-4 text-gray-300" }),
|
|
49372
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-lg font-medium", children: "No widgets available for focus view" }),
|
|
49373
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm mt-2", children: "Text, Spacer, and Filter widgets are excluded." })
|
|
49374
|
+
] }) }) })
|
|
49375
|
+
) }),
|
|
49376
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("footer", { className: "bg-white border-t border-gray-200 py-4 shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
49377
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 bg-gray-100 rounded-full p-1", children: [
|
|
49378
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49379
|
+
"button",
|
|
49380
|
+
{
|
|
49381
|
+
onClick: () => setViewMode("grid"),
|
|
49382
|
+
className: `flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-all ${viewMode === "grid" ? "bg-primary-700 text-white shadow-md" : "text-gray-600 hover:text-gray-900"}`,
|
|
49383
|
+
children: [
|
|
49384
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Grid3X3, { className: "w-4 h-4" }),
|
|
49385
|
+
"Grid"
|
|
49386
|
+
]
|
|
49387
|
+
}
|
|
49388
|
+
),
|
|
49389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49390
|
+
"button",
|
|
49391
|
+
{
|
|
49392
|
+
onClick: () => setViewMode("focus"),
|
|
49393
|
+
className: `flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-all ${viewMode === "focus" ? "bg-primary-700 text-white shadow-md" : "text-gray-600 hover:text-gray-900"}`,
|
|
49394
|
+
children: [
|
|
49395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-4 h-4" }),
|
|
49396
|
+
"Focus"
|
|
49397
|
+
]
|
|
49398
|
+
}
|
|
49399
|
+
),
|
|
49400
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px h-6 bg-gray-300 mx-2" }),
|
|
49401
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49402
|
+
"button",
|
|
49403
|
+
{
|
|
49404
|
+
onClick: () => setLaserPointerActive((prev) => !prev),
|
|
49405
|
+
className: `p-2 transition-colors rounded-full ${laserPointerActive ? "bg-primary-600 text-white" : "text-gray-600 hover:text-gray-900 hover:bg-gray-200"}`,
|
|
49406
|
+
"aria-label": "Toggle laser pointer (L)",
|
|
49407
|
+
title: "Toggle laser pointer (L)",
|
|
49408
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LaserPointerIcon, { className: "w-4 h-4" })
|
|
49409
|
+
}
|
|
49410
|
+
),
|
|
49411
|
+
viewMode === "focus" && focusableWidgets.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
49412
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px h-6 bg-gray-300 mx-2" }),
|
|
49413
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-600 px-2", children: [
|
|
49414
|
+
currentFocusIndex + 1,
|
|
49415
|
+
" / ",
|
|
49416
|
+
focusableWidgets.length
|
|
49417
|
+
] })
|
|
49418
|
+
] })
|
|
49419
|
+
] }),
|
|
49420
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 uppercase tracking-wider", children: "ESC TO EXIT \u2022 F TO TOGGLE \u2022 L FOR LASER \u2022 ARROWS TO NAVIGATE" })
|
|
49421
|
+
] }) }),
|
|
49422
|
+
laserPointerActive && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49423
|
+
"div",
|
|
49171
49424
|
{
|
|
49172
|
-
|
|
49173
|
-
|
|
49425
|
+
className: "fixed pointer-events-none z-[100] transform -translate-x-1/2 -translate-y-1/2",
|
|
49426
|
+
style: {
|
|
49427
|
+
left: mousePosition.x,
|
|
49428
|
+
top: mousePosition.y
|
|
49429
|
+
},
|
|
49174
49430
|
children: [
|
|
49175
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
49176
|
-
"
|
|
49431
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 w-8 h-8 -translate-x-1/2 -translate-y-1/2 bg-red-500/20 rounded-full blur-md" }),
|
|
49432
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute w-4 h-4 -translate-x-1/2 -translate-y-1/2 bg-red-500 rounded-full shadow-lg shadow-red-500/50" })
|
|
49177
49433
|
]
|
|
49178
49434
|
}
|
|
49179
|
-
)
|
|
49180
|
-
|
|
49181
|
-
|
|
49182
|
-
|
|
49183
|
-
{
|
|
49184
|
-
onClick: () => setLaserPointerActive((prev) => !prev),
|
|
49185
|
-
className: `p-2 transition-colors rounded-full ${laserPointerActive ? "bg-primary-600 text-white" : "text-gray-600 hover:text-gray-900 hover:bg-gray-200"}`,
|
|
49186
|
-
"aria-label": "Toggle laser pointer (L)",
|
|
49187
|
-
title: "Toggle laser pointer (L)",
|
|
49188
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(LaserPointerIcon, { className: "w-4 h-4" })
|
|
49189
|
-
}
|
|
49190
|
-
),
|
|
49191
|
-
viewMode === "focus" && focusableWidgets.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
49192
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px h-6 bg-gray-300 mx-2" }),
|
|
49193
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-600 px-2", children: [
|
|
49194
|
-
currentFocusIndex + 1,
|
|
49195
|
-
" / ",
|
|
49196
|
-
focusableWidgets.length
|
|
49197
|
-
] })
|
|
49198
|
-
] })
|
|
49199
|
-
] }),
|
|
49200
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 uppercase tracking-wider", children: "ESC TO EXIT \u2022 F TO TOGGLE \u2022 L FOR LASER \u2022 ARROWS TO NAVIGATE" })
|
|
49201
|
-
] }) }),
|
|
49202
|
-
laserPointerActive && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
49203
|
-
"div",
|
|
49204
|
-
{
|
|
49205
|
-
className: "fixed pointer-events-none z-[100] transform -translate-x-1/2 -translate-y-1/2",
|
|
49206
|
-
style: {
|
|
49207
|
-
left: mousePosition.x,
|
|
49208
|
-
top: mousePosition.y
|
|
49209
|
-
},
|
|
49210
|
-
children: [
|
|
49211
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 w-8 h-8 -translate-x-1/2 -translate-y-1/2 bg-red-500/20 rounded-full blur-md" }),
|
|
49212
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute w-4 h-4 -translate-x-1/2 -translate-y-1/2 bg-red-500 rounded-full shadow-lg shadow-red-500/50" })
|
|
49213
|
-
]
|
|
49214
|
-
}
|
|
49215
|
-
)
|
|
49216
|
-
] });
|
|
49435
|
+
)
|
|
49436
|
+
]
|
|
49437
|
+
}
|
|
49438
|
+
);
|
|
49217
49439
|
}
|
|
49218
49440
|
|
|
49219
49441
|
var __defProp = Object.defineProperty;
|