@papernote/ui 1.10.26 → 1.11.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.
- package/dist/components/ActionCard.d.ts +48 -0
- package/dist/components/ActionCard.d.ts.map +1 -0
- package/dist/components/AnomalyBanner.d.ts +27 -0
- package/dist/components/AnomalyBanner.d.ts.map +1 -0
- package/dist/components/CaseQueueItem.d.ts +35 -0
- package/dist/components/CaseQueueItem.d.ts.map +1 -0
- package/dist/components/ConfidenceBadge.d.ts +19 -0
- package/dist/components/ConfidenceBadge.d.ts.map +1 -0
- package/dist/components/ConfidenceIndicator.d.ts +25 -0
- package/dist/components/ConfidenceIndicator.d.ts.map +1 -0
- package/dist/components/EntityCard.d.ts +46 -0
- package/dist/components/EntityCard.d.ts.map +1 -0
- package/dist/components/FunnelChart.d.ts +31 -0
- package/dist/components/FunnelChart.d.ts.map +1 -0
- package/dist/components/MatchIndicator.d.ts +20 -0
- package/dist/components/MatchIndicator.d.ts.map +1 -0
- package/dist/components/PersonaDashboard.d.ts +39 -0
- package/dist/components/PersonaDashboard.d.ts.map +1 -0
- package/dist/components/ProcessHealthBar.d.ts +28 -0
- package/dist/components/ProcessHealthBar.d.ts.map +1 -0
- package/dist/components/ProcessIndicator.d.ts +38 -0
- package/dist/components/ProcessIndicator.d.ts.map +1 -0
- package/dist/components/ReviewDecisionCard.d.ts +53 -0
- package/dist/components/ReviewDecisionCard.d.ts.map +1 -0
- package/dist/components/SLAIndicator.d.ts +24 -0
- package/dist/components/SLAIndicator.d.ts.map +1 -0
- package/dist/components/SplitPane.d.ts +33 -0
- package/dist/components/SplitPane.d.ts.map +1 -0
- package/dist/components/SystemActionEntry.d.ts +42 -0
- package/dist/components/SystemActionEntry.d.ts.map +1 -0
- package/dist/components/VarianceDisplay.d.ts +26 -0
- package/dist/components/VarianceDisplay.d.ts.map +1 -0
- package/dist/components/index.d.ts +32 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +529 -2
- package/dist/index.esm.js +661 -28
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +675 -26
- package/dist/index.js.map +1 -1
- package/dist/styles.css +369 -0
- package/package.json +1 -1
- package/src/components/ActionCard.tsx +176 -0
- package/src/components/AnomalyBanner.tsx +113 -0
- package/src/components/CaseQueueItem.tsx +145 -0
- package/src/components/ConfidenceBadge.tsx +62 -0
- package/src/components/ConfidenceIndicator.tsx +96 -0
- package/src/components/EntityCard.tsx +216 -0
- package/src/components/FunnelChart.tsx +160 -0
- package/src/components/MatchIndicator.tsx +73 -0
- package/src/components/PersonaDashboard.tsx +105 -0
- package/src/components/ProcessHealthBar.tsx +107 -0
- package/src/components/ProcessIndicator.tsx +167 -0
- package/src/components/ReviewDecisionCard.tsx +186 -0
- package/src/components/SLAIndicator.tsx +108 -0
- package/src/components/SplitPane.tsx +150 -0
- package/src/components/SystemActionEntry.tsx +175 -0
- package/src/components/VarianceDisplay.tsx +116 -0
- package/src/components/index.ts +48 -0
package/dist/index.js
CHANGED
|
@@ -724,7 +724,7 @@ function usePrefersMobile() {
|
|
|
724
724
|
}
|
|
725
725
|
|
|
726
726
|
// Size classes for trigger button
|
|
727
|
-
const sizeClasses$
|
|
727
|
+
const sizeClasses$d = {
|
|
728
728
|
sm: 'h-8 text-sm py-1',
|
|
729
729
|
md: 'h-10 text-base py-2',
|
|
730
730
|
lg: 'h-12 text-base py-3 min-h-touch', // 44px touch target
|
|
@@ -1041,14 +1041,14 @@ const Select = React.forwardRef((props, ref) => {
|
|
|
1041
1041
|
if (useNativeSelect) {
|
|
1042
1042
|
return (jsxRuntime.jsxs("div", { className: "w-full", children: [label && (jsxRuntime.jsxs("label", { id: labelId, className: "label", children: [label, required && jsxRuntime.jsx("span", { className: "text-error-500 ml-1", children: "*" })] })), jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsxs("select", { ref: nativeSelectRef, value: value || '', onChange: (e) => onChange?.(e.target.value), disabled: disabled, className: `
|
|
1043
1043
|
input w-full appearance-none pr-10
|
|
1044
|
-
${sizeClasses$
|
|
1044
|
+
${sizeClasses$d[effectiveSize]}
|
|
1045
1045
|
${error ? 'border-error-400 focus:border-error-400 focus:ring-error-400' : ''}
|
|
1046
1046
|
${disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
|
|
1047
1047
|
`, "aria-labelledby": label ? labelId : undefined, "aria-invalid": error ? 'true' : undefined, "aria-describedby": error ? errorId : (helperText ? helperTextId : undefined), "aria-required": required, children: [jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }), options.map((opt) => (jsxRuntime.jsx("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))), groups.map((group) => (jsxRuntime.jsx("optgroup", { label: group.label, children: group.options.map((opt) => (jsxRuntime.jsx("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))) }, group.label)))] }), jsxRuntime.jsx(lucideReact.ChevronDown, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-5 w-5 text-ink-500 pointer-events-none" })] }), error && (jsxRuntime.jsx("p", { id: errorId, className: "mt-2 text-xs text-error-600", role: "alert", "aria-live": "assertive", children: error })), helperText && !error && (jsxRuntime.jsx("p", { id: helperTextId, className: "mt-2 text-xs text-ink-600", children: helperText }))] }));
|
|
1048
1048
|
}
|
|
1049
1049
|
return (jsxRuntime.jsxs("div", { className: "w-full", children: [label && (jsxRuntime.jsxs("label", { id: labelId, className: "label", children: [label, required && jsxRuntime.jsx("span", { className: "text-error-500 ml-1", children: "*" })] })), jsxRuntime.jsx("div", { ref: selectRef, className: "relative", children: jsxRuntime.jsxs("button", { ref: buttonRef, type: "button", onClick: () => !disabled && setIsOpen(!isOpen), disabled: disabled, className: `
|
|
1050
1050
|
input w-full flex items-center justify-between px-3
|
|
1051
|
-
${sizeClasses$
|
|
1051
|
+
${sizeClasses$d[effectiveSize]}
|
|
1052
1052
|
${error ? 'border-error-400 focus:border-error-400 focus:ring-error-400' : ''}
|
|
1053
1053
|
${disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
|
|
1054
1054
|
`, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-labelledby": label ? labelId : undefined, "aria-label": !label ? placeholder : undefined, "aria-activedescendant": activeDescendant, "aria-invalid": error ? 'true' : undefined, "aria-describedby": error ? errorId : (helperText ? helperTextId : undefined), "aria-disabled": disabled, "aria-required": required, children: [jsxRuntime.jsxs("span", { className: `flex items-center gap-2 ${selectedOption ? 'text-ink-800' : 'text-ink-400'}`, children: [loading && jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin text-ink-500" }), !loading && selectedOption?.icon && jsxRuntime.jsx("span", { children: selectedOption.icon }), selectedOption ? selectedOption.label : placeholder] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [clearable && value && (jsxRuntime.jsx("button", { type: "button", onClick: (e) => {
|
|
@@ -1193,7 +1193,7 @@ const Switch = React.forwardRef(({ checked, onChange, label, description, disabl
|
|
|
1193
1193
|
Switch.displayName = 'Switch';
|
|
1194
1194
|
|
|
1195
1195
|
// Size classes for textarea
|
|
1196
|
-
const sizeClasses$
|
|
1196
|
+
const sizeClasses$c = {
|
|
1197
1197
|
sm: 'px-3 py-2 text-sm',
|
|
1198
1198
|
md: 'px-4 py-3 text-sm',
|
|
1199
1199
|
lg: 'px-4 py-3.5 text-base', // Larger padding and text for mobile
|
|
@@ -1281,7 +1281,7 @@ const Textarea = React.forwardRef(({ label, helperText, validationState, validat
|
|
|
1281
1281
|
bg-white bg-subtle-grain transition-all duration-200
|
|
1282
1282
|
focus:outline-none focus:ring-2 ${getResizeClass()}
|
|
1283
1283
|
disabled:bg-paper-100 disabled:text-ink-400 disabled:cursor-not-allowed disabled:opacity-60
|
|
1284
|
-
${sizeClasses$
|
|
1284
|
+
${sizeClasses$c[effectiveSize]}
|
|
1285
1285
|
${getValidationClasses()}
|
|
1286
1286
|
${loading ? 'pr-10' : ''}
|
|
1287
1287
|
${className}
|
|
@@ -3830,7 +3830,7 @@ var module$1 = {};
|
|
|
3830
3830
|
var confetti = module$1.exports;
|
|
3831
3831
|
module$1.exports.create;
|
|
3832
3832
|
|
|
3833
|
-
const defaultColors = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#ec4899'];
|
|
3833
|
+
const defaultColors$1 = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#ec4899'];
|
|
3834
3834
|
/**
|
|
3835
3835
|
* Celebration component for triggering confetti and other celebration animations.
|
|
3836
3836
|
*
|
|
@@ -3846,7 +3846,7 @@ const defaultColors = ['#22c55e', '#3b82f6', '#a855f7', '#f59e0b', '#ef4444', '#
|
|
|
3846
3846
|
* // Stars with custom colors
|
|
3847
3847
|
* <Celebration trigger={true} type="stars" colors={['#ffd700', '#ffed4a']} />
|
|
3848
3848
|
*/
|
|
3849
|
-
function Celebration({ trigger = false, type = 'confetti', duration = 2000, particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors, onComplete, enabled = true, }) {
|
|
3849
|
+
function Celebration({ trigger = false, type = 'confetti', duration = 2000, particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors$1, onComplete, enabled = true, }) {
|
|
3850
3850
|
const animationRef = React.useRef(null);
|
|
3851
3851
|
const endTimeRef = React.useRef(0);
|
|
3852
3852
|
const fireConfetti = React.useCallback(() => {
|
|
@@ -3949,7 +3949,7 @@ function Celebration({ trigger = false, type = 'confetti', duration = 2000, part
|
|
|
3949
3949
|
*/
|
|
3950
3950
|
function useCelebration() {
|
|
3951
3951
|
const celebrate = React.useCallback((options) => {
|
|
3952
|
-
const { type = 'confetti', particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors, duration = 2000, } = options || {};
|
|
3952
|
+
const { type = 'confetti', particleCount = 100, spread = 70, origin = { x: 0.5, y: 0.6 }, colors = defaultColors$1, duration = 2000, } = options || {};
|
|
3953
3953
|
switch (type) {
|
|
3954
3954
|
case 'fireworks': {
|
|
3955
3955
|
const end = Date.now() + duration;
|
|
@@ -4610,7 +4610,7 @@ function BottomSheetActions({ children, className = '' }) {
|
|
|
4610
4610
|
|
|
4611
4611
|
// Selector for all focusable elements
|
|
4612
4612
|
const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
4613
|
-
const sizeClasses$
|
|
4613
|
+
const sizeClasses$b = {
|
|
4614
4614
|
sm: 'max-w-md',
|
|
4615
4615
|
md: 'max-w-lg',
|
|
4616
4616
|
lg: 'max-w-2xl',
|
|
@@ -4799,7 +4799,7 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
|
|
|
4799
4799
|
return reactDom.createPortal(jsxRuntime.jsx(BottomSheet, { isOpen: isOpen, onClose: onClose, title: title, height: mobileHeight, showHandle: mobileShowHandle, showCloseButton: showCloseButton, children: children }), document.body);
|
|
4800
4800
|
}
|
|
4801
4801
|
// Render as standard modal on desktop
|
|
4802
|
-
const modalContent = (jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onMouseDown: handleBackdropMouseDown, onClick: handleBackdropClick, children: jsxRuntime.jsxs("div", { ref: modalRef, className: `${sizeClasses$
|
|
4802
|
+
const modalContent = (jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onMouseDown: handleBackdropMouseDown, onClick: handleBackdropClick, children: jsxRuntime.jsxs("div", { ref: modalRef, className: `${sizeClasses$b[size]} w-full bg-white bg-subtle-grain rounded-xl shadow-2xl border border-paper-200 ${getAnimationClass()}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsxRuntime.jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsxRuntime.jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" }) }))] }), jsxRuntime.jsx("div", { className: `px-6 py-4 ${scrollable || maxHeight ? 'overflow-y-auto' : ''}`, style: {
|
|
4803
4803
|
maxHeight: maxHeight || (scrollable ? 'calc(100vh - 200px)' : undefined),
|
|
4804
4804
|
}, children: children })] }) }));
|
|
4805
4805
|
return reactDom.createPortal(modalContent, document.body);
|
|
@@ -5181,7 +5181,7 @@ function getAvatarColor(name) {
|
|
|
5181
5181
|
return colors[Math.abs(hash) % colors.length];
|
|
5182
5182
|
}
|
|
5183
5183
|
// Get initials from name
|
|
5184
|
-
function getInitials(name) {
|
|
5184
|
+
function getInitials$1(name) {
|
|
5185
5185
|
const parts = name.trim().split(/\s+/);
|
|
5186
5186
|
if (parts.length >= 2) {
|
|
5187
5187
|
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
@@ -5222,7 +5222,7 @@ const CollaboratorAvatars = React.forwardRef(function CollaboratorAvatars({ coll
|
|
|
5222
5222
|
${collaborator.avatar ? '' : getAvatarColor(collaborator.name)}
|
|
5223
5223
|
text-white font-medium
|
|
5224
5224
|
shrink-0
|
|
5225
|
-
`, style: { zIndex: visible.length - index }, children: collaborator.avatar ? (jsxRuntime.jsx("img", { src: collaborator.avatar, alt: collaborator.name, className: "w-full h-full object-cover" })) : (jsxRuntime.jsx("span", { children: getInitials(collaborator.name) })) }, `${collaborator.name}-${index}`))), hasOverflow && (jsxRuntime.jsxs("div", { className: `
|
|
5225
|
+
`, style: { zIndex: visible.length - index }, children: collaborator.avatar ? (jsxRuntime.jsx("img", { src: collaborator.avatar, alt: collaborator.name, className: "w-full h-full object-cover" })) : (jsxRuntime.jsx("span", { children: getInitials$1(collaborator.name) })) }, `${collaborator.name}-${index}`))), hasOverflow && (jsxRuntime.jsxs("div", { className: `
|
|
5226
5226
|
${styles.container}
|
|
5227
5227
|
${styles.overlap}
|
|
5228
5228
|
${styles.border}
|
|
@@ -5870,7 +5870,7 @@ function Alert({ variant = 'info', title, children, onClose, className = '', act
|
|
|
5870
5870
|
return (jsxRuntime.jsx("div", { className: `rounded-lg border p-4 ${styles.container} ${className}`, role: "alert", children: jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-0.5", children: styles.icon }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [title && jsxRuntime.jsx("h4", { className: "text-sm font-medium mb-1", children: title }), jsxRuntime.jsx("div", { className: "text-sm", children: children }), actions.length > 0 && (jsxRuntime.jsx("div", { className: "flex gap-2 mt-3", children: actions.map((action, index) => (jsxRuntime.jsx("button", { onClick: action.onClick, className: getButtonStyles(action.variant), children: action.label }, index))) }))] }), onClose && (jsxRuntime.jsx("button", { onClick: onClose, className: "flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity", "aria-label": "Close alert", children: jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }) }))] }) }));
|
|
5871
5871
|
}
|
|
5872
5872
|
|
|
5873
|
-
const sizeClasses$
|
|
5873
|
+
const sizeClasses$a = {
|
|
5874
5874
|
left: {
|
|
5875
5875
|
sm: 'w-64',
|
|
5876
5876
|
md: 'w-96',
|
|
@@ -5949,7 +5949,7 @@ function Drawer({ isOpen, onClose, title, children, placement = 'right', size =
|
|
|
5949
5949
|
const isHorizontal = placement === 'left' || placement === 'right';
|
|
5950
5950
|
return (jsxRuntime.jsxs("div", { className: "fixed inset-0 z-50 flex", children: [showOverlay && (jsxRuntime.jsx("div", { className: "fixed inset-0 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onClick: handleOverlayClick, "aria-hidden": "true" })), jsxRuntime.jsxs("div", { className: `
|
|
5951
5951
|
fixed ${placementClasses[placement]}
|
|
5952
|
-
${sizeClasses$
|
|
5952
|
+
${sizeClasses$a[placement][size]}
|
|
5953
5953
|
bg-white border-paper-200 shadow-2xl
|
|
5954
5954
|
${isHorizontal ? 'border-r' : 'border-b'}
|
|
5955
5955
|
${animationClasses[placement].enter}
|
|
@@ -6091,14 +6091,14 @@ function useConfirmDialog() {
|
|
|
6091
6091
|
};
|
|
6092
6092
|
}
|
|
6093
6093
|
|
|
6094
|
-
const sizeClasses$
|
|
6094
|
+
const sizeClasses$9 = {
|
|
6095
6095
|
sm: 'h-3.5 w-3.5',
|
|
6096
6096
|
md: 'h-4 w-4',
|
|
6097
6097
|
lg: 'h-5 w-5',
|
|
6098
6098
|
};
|
|
6099
6099
|
function HelpTooltip({ content, icon = 'help', size = 'md', position = 'top', className = '', }) {
|
|
6100
6100
|
const IconComponent = icon === 'info' ? lucideReact.Info : lucideReact.HelpCircle;
|
|
6101
|
-
return (jsxRuntime.jsx(Tooltip, { content: content, position: position, children: jsxRuntime.jsx("span", { className: `inline-flex items-center justify-center text-ink-400 hover:text-ink-600 cursor-help transition-colors ${className}`, role: "button", "aria-label": "Help", tabIndex: 0, children: jsxRuntime.jsx(IconComponent, { className: sizeClasses$
|
|
6101
|
+
return (jsxRuntime.jsx(Tooltip, { content: content, position: position, children: jsxRuntime.jsx("span", { className: `inline-flex items-center justify-center text-ink-400 hover:text-ink-600 cursor-help transition-colors ${className}`, role: "button", "aria-label": "Help", tabIndex: 0, children: jsxRuntime.jsx(IconComponent, { className: sizeClasses$9[size] }) }) }));
|
|
6102
6102
|
}
|
|
6103
6103
|
|
|
6104
6104
|
/**
|
|
@@ -8514,7 +8514,7 @@ const variantClasses$4 = {
|
|
|
8514
8514
|
selected: 'bg-accent-200 border-accent-400 ring-2 ring-accent-300',
|
|
8515
8515
|
},
|
|
8516
8516
|
};
|
|
8517
|
-
const sizeClasses$
|
|
8517
|
+
const sizeClasses$8 = {
|
|
8518
8518
|
sm: {
|
|
8519
8519
|
container: 'h-6 px-2 text-xs gap-1',
|
|
8520
8520
|
icon: 'h-3 w-3',
|
|
@@ -8565,7 +8565,7 @@ const gapClasses = {
|
|
|
8565
8565
|
*/
|
|
8566
8566
|
function Chip({ children, variant = 'secondary', size = 'md', onClose, icon, disabled = false, className = '', onClick, selected = false, maxWidth, chipKey, }) {
|
|
8567
8567
|
const variantStyle = variantClasses$4[variant];
|
|
8568
|
-
const sizeStyle = sizeClasses$
|
|
8568
|
+
const sizeStyle = sizeClasses$8[size];
|
|
8569
8569
|
const isClickable = !disabled && (onClick || onClose);
|
|
8570
8570
|
return (jsxRuntime.jsxs("div", { className: `
|
|
8571
8571
|
inline-flex items-center rounded-full border font-medium
|
|
@@ -8680,7 +8680,7 @@ function ChipGroup({ children, direction = 'horizontal', wrap = false, gap = 'sm
|
|
|
8680
8680
|
`, role: selectionMode !== 'none' ? 'group' : undefined, "aria-label": selectionMode !== 'none' ? 'Chip selection group' : undefined, children: enhancedChildren }));
|
|
8681
8681
|
}
|
|
8682
8682
|
|
|
8683
|
-
const sizeClasses$
|
|
8683
|
+
const sizeClasses$7 = {
|
|
8684
8684
|
sm: {
|
|
8685
8685
|
item: 'py-1.5 px-2',
|
|
8686
8686
|
text: 'text-sm',
|
|
@@ -8813,7 +8813,7 @@ function CheckboxList({ items, selectedKeys, onSelectionChange, groupLabels = {}
|
|
|
8813
8813
|
onSelectionChange(Array.from(newKeys));
|
|
8814
8814
|
}
|
|
8815
8815
|
};
|
|
8816
|
-
const sizeStyle = sizeClasses$
|
|
8816
|
+
const sizeStyle = sizeClasses$7[size];
|
|
8817
8817
|
const enabledItems = filteredItems.filter(item => !item.disabled);
|
|
8818
8818
|
const allSelected = enabledItems.length > 0 && enabledItems.every(item => selectedKeys.includes(item.key));
|
|
8819
8819
|
const someSelected = enabledItems.some(item => selectedKeys.includes(item.key)) && !allSelected;
|
|
@@ -8852,7 +8852,7 @@ function CheckboxListItemRow({ item, selected, onToggle, size, sizeStyle, indent
|
|
|
8852
8852
|
`, children: jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [jsxRuntime.jsx(Checkbox, { checked: selected, onChange: onToggle, disabled: item.disabled, size: size }), jsxRuntime.jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [jsxRuntime.jsx("span", { className: sizeStyle.text, children: item.label }), item.description && (jsxRuntime.jsx("span", { className: `${sizeStyle.description} text-ink-500`, children: item.description }))] })] }) }));
|
|
8853
8853
|
}
|
|
8854
8854
|
|
|
8855
|
-
const sizeClasses$
|
|
8855
|
+
const sizeClasses$6 = {
|
|
8856
8856
|
sm: {
|
|
8857
8857
|
container: 'text-sm',
|
|
8858
8858
|
item: 'py-1.5 px-2',
|
|
@@ -8975,7 +8975,7 @@ function SearchableList({ items, searchPlaceholder = 'Search...', searchValue: c
|
|
|
8975
8975
|
}
|
|
8976
8976
|
}
|
|
8977
8977
|
}, [highlightedIndex]);
|
|
8978
|
-
const sizeStyle = sizeClasses$
|
|
8978
|
+
const sizeStyle = sizeClasses$6[size];
|
|
8979
8979
|
const resultCountText = formatResultCount
|
|
8980
8980
|
? formatResultCount(filteredItems.length, items.length)
|
|
8981
8981
|
: `${filteredItems.length} of ${items.length}`;
|
|
@@ -9000,7 +9000,7 @@ function SearchableList({ items, searchPlaceholder = 'Search...', searchValue: c
|
|
|
9000
9000
|
})] })] }));
|
|
9001
9001
|
}
|
|
9002
9002
|
|
|
9003
|
-
const sizeClasses$
|
|
9003
|
+
const sizeClasses$5 = {
|
|
9004
9004
|
sm: {
|
|
9005
9005
|
input: 'h-8 px-2 text-sm',
|
|
9006
9006
|
button: 'h-8 w-8',
|
|
@@ -9024,7 +9024,7 @@ const NumberInput = React.forwardRef((props, ref) => {
|
|
|
9024
9024
|
const { value = 0, onChange, min, max, step = 1, disabled = false, readOnly = false, label, helperText, error, required = false, size = 'md', className = '', placeholder, id, name, precision, formatValue, } = props;
|
|
9025
9025
|
const [internalValue, setInternalValue] = React.useState(String(value));
|
|
9026
9026
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
9027
|
-
const sizeStyle = sizeClasses$
|
|
9027
|
+
const sizeStyle = sizeClasses$5[size];
|
|
9028
9028
|
// Generate unique IDs for ARIA
|
|
9029
9029
|
const uniqueId = React.useId();
|
|
9030
9030
|
const inputId = id || uniqueId;
|
|
@@ -9869,7 +9869,7 @@ function PriorityAlertBanner({ alerts, onDismiss, sticky = false, className = ''
|
|
|
9869
9869
|
`, role: "alert", "aria-live": "polite", children: alerts.map(renderAlert) }));
|
|
9870
9870
|
}
|
|
9871
9871
|
|
|
9872
|
-
const sizeClasses$
|
|
9872
|
+
const sizeClasses$4 = {
|
|
9873
9873
|
sm: {
|
|
9874
9874
|
header: 'h-10 px-3',
|
|
9875
9875
|
text: 'text-sm',
|
|
@@ -9977,7 +9977,7 @@ function ExpandablePanel({ collapsedContent, children, position = 'bottom', mode
|
|
|
9977
9977
|
document.addEventListener('keydown', handleEscape);
|
|
9978
9978
|
return () => document.removeEventListener('keydown', handleEscape);
|
|
9979
9979
|
}, [closeOnEscape, expanded]);
|
|
9980
|
-
const sizeStyle = sizeClasses$
|
|
9980
|
+
const sizeStyle = sizeClasses$4[size];
|
|
9981
9981
|
const variantStyle = variantClasses$1[variant];
|
|
9982
9982
|
const heightValue = typeof expandedHeight === 'number' ? `${expandedHeight}px` : expandedHeight;
|
|
9983
9983
|
const maxWidthValue = maxWidth
|
|
@@ -11870,6 +11870,639 @@ function StepIndicator({ steps, currentStep, variant = 'horizontal', onStepClick
|
|
|
11870
11870
|
}) }) }));
|
|
11871
11871
|
}
|
|
11872
11872
|
|
|
11873
|
+
// =============================================================================
|
|
11874
|
+
// Color Mappings
|
|
11875
|
+
// =============================================================================
|
|
11876
|
+
const stageColors = {
|
|
11877
|
+
slate: { bg: 'bg-slate-50', text: 'text-slate-700', border: 'border-slate-200', activeBg: 'bg-slate-100' },
|
|
11878
|
+
blue: { bg: 'bg-blue-50', text: 'text-blue-700', border: 'border-blue-200', activeBg: 'bg-blue-100' },
|
|
11879
|
+
indigo: { bg: 'bg-indigo-50', text: 'text-indigo-700', border: 'border-indigo-200', activeBg: 'bg-indigo-100' },
|
|
11880
|
+
purple: { bg: 'bg-purple-50', text: 'text-purple-700', border: 'border-purple-200', activeBg: 'bg-purple-100' },
|
|
11881
|
+
green: { bg: 'bg-green-50', text: 'text-green-700', border: 'border-green-200', activeBg: 'bg-green-100' },
|
|
11882
|
+
red: { bg: 'bg-red-50', text: 'text-red-700', border: 'border-red-200', activeBg: 'bg-red-100' },
|
|
11883
|
+
yellow: { bg: 'bg-yellow-50', text: 'text-yellow-700', border: 'border-yellow-200', activeBg: 'bg-yellow-100' },
|
|
11884
|
+
orange: { bg: 'bg-orange-50', text: 'text-orange-700', border: 'border-orange-200', activeBg: 'bg-orange-100' },
|
|
11885
|
+
teal: { bg: 'bg-teal-50', text: 'text-teal-700', border: 'border-teal-200', activeBg: 'bg-teal-100' },
|
|
11886
|
+
primary: { bg: 'bg-primary-50', text: 'text-primary-700', border: 'border-primary-200', activeBg: 'bg-primary-100' },
|
|
11887
|
+
};
|
|
11888
|
+
const healthIndicator = {
|
|
11889
|
+
good: 'bg-success-500',
|
|
11890
|
+
warning: 'bg-warning-500',
|
|
11891
|
+
critical: 'bg-error-500',
|
|
11892
|
+
};
|
|
11893
|
+
const sizeClasses$3 = {
|
|
11894
|
+
sm: { wrapper: 'py-2 px-3', count: 'text-lg', label: 'text-xs', chevron: 'h-3 w-3' },
|
|
11895
|
+
md: { wrapper: 'py-3 px-4', count: 'text-2xl', label: 'text-sm', chevron: 'h-4 w-4' },
|
|
11896
|
+
lg: { wrapper: 'py-4 px-5', count: 'text-3xl', label: 'text-base', chevron: 'h-5 w-5' },
|
|
11897
|
+
};
|
|
11898
|
+
// =============================================================================
|
|
11899
|
+
// Component
|
|
11900
|
+
// =============================================================================
|
|
11901
|
+
/**
|
|
11902
|
+
* ProcessIndicator — Horizontal process flow visualization
|
|
11903
|
+
*
|
|
11904
|
+
* Shows stages as connected blocks with names, item counts, and health coloring.
|
|
11905
|
+
* Stages are clickable for filtering. Used at the top of process views
|
|
11906
|
+
* (Sales Pipeline, Support Center, Commission Lifecycle).
|
|
11907
|
+
*/
|
|
11908
|
+
function ProcessIndicator({ stages, activeStageId, onStageClick, showConversion = false, size = 'md', className = '', }) {
|
|
11909
|
+
const sizes = sizeClasses$3[size];
|
|
11910
|
+
const totalCount = stages.reduce((sum, s) => sum + s.count, 0);
|
|
11911
|
+
return (jsxRuntime.jsxs("div", { className: `flex items-stretch overflow-x-auto ${className}`, role: "navigation", "aria-label": "Process stages", children: [stages.map((stage, index) => {
|
|
11912
|
+
const colors = stageColors[stage.color || 'slate'];
|
|
11913
|
+
const isActive = stage.id === activeStageId;
|
|
11914
|
+
const isClickable = !!onStageClick;
|
|
11915
|
+
const conversionRate = showConversion && index > 0 && stages[index - 1].count > 0
|
|
11916
|
+
? Math.round((stage.count / stages[index - 1].count) * 100)
|
|
11917
|
+
: null;
|
|
11918
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [index > 0 && (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center px-1 flex-shrink-0", children: [jsxRuntime.jsx(lucideReact.ChevronRight, { className: `${sizes.chevron} text-ink-300` }), conversionRate !== null && (jsxRuntime.jsxs("span", { className: "text-[10px] text-ink-400 mt-0.5", children: [conversionRate, "%"] }))] })), jsxRuntime.jsxs("button", { type: "button", onClick: () => onStageClick?.(stage.id), disabled: !isClickable, className: `
|
|
11919
|
+
flex flex-col items-center justify-center ${sizes.wrapper}
|
|
11920
|
+
rounded-lg border transition-all min-w-0 flex-1
|
|
11921
|
+
${isActive ? `${colors.activeBg} ${colors.border} border-2 shadow-sm` : `${colors.bg} ${colors.border}`}
|
|
11922
|
+
${isClickable ? 'cursor-pointer hover:shadow-sm hover:border-2' : 'cursor-default'}
|
|
11923
|
+
`, "aria-current": isActive ? 'step' : undefined, "aria-label": `${stage.name}: ${stage.count} items`, children: [stage.health && (jsxRuntime.jsx("div", { className: `w-2 h-2 rounded-full ${healthIndicator[stage.health]} mb-1` })), stage.icon && (jsxRuntime.jsx("div", { className: `${colors.text} mb-1 opacity-60`, children: stage.icon })), jsxRuntime.jsx("span", { className: `${sizes.count} font-bold ${colors.text} leading-none`, children: stage.count.toLocaleString() }), jsxRuntime.jsx("span", { className: `${sizes.label} ${colors.text} opacity-80 mt-1 whitespace-nowrap`, children: stage.name })] })] }, stage.id));
|
|
11924
|
+
}), stages.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "flex items-center justify-center px-2 flex-shrink-0", children: jsxRuntime.jsx("div", { className: "w-px h-8 bg-ink-200" }) }), jsxRuntime.jsxs("div", { className: `flex flex-col items-center justify-center ${sizes.wrapper} min-w-0`, children: [jsxRuntime.jsx("span", { className: `${sizes.count} font-bold text-ink-900 leading-none`, children: totalCount.toLocaleString() }), jsxRuntime.jsx("span", { className: `${sizes.label} text-ink-500 mt-1`, children: "Total" })] })] }))] }));
|
|
11925
|
+
}
|
|
11926
|
+
|
|
11927
|
+
// =============================================================================
|
|
11928
|
+
// Helpers
|
|
11929
|
+
// =============================================================================
|
|
11930
|
+
const statusColors$1 = {
|
|
11931
|
+
slate: { bg: 'bg-slate-100', text: 'text-slate-700' },
|
|
11932
|
+
blue: { bg: 'bg-blue-100', text: 'text-blue-700' },
|
|
11933
|
+
indigo: { bg: 'bg-indigo-100', text: 'text-indigo-700' },
|
|
11934
|
+
purple: { bg: 'bg-purple-100', text: 'text-purple-700' },
|
|
11935
|
+
green: { bg: 'bg-green-100', text: 'text-green-700' },
|
|
11936
|
+
red: { bg: 'bg-red-100', text: 'text-red-700' },
|
|
11937
|
+
yellow: { bg: 'bg-yellow-100', text: 'text-yellow-700' },
|
|
11938
|
+
orange: { bg: 'bg-orange-100', text: 'text-orange-700' },
|
|
11939
|
+
teal: { bg: 'bg-teal-100', text: 'text-teal-700' },
|
|
11940
|
+
};
|
|
11941
|
+
function getInitials(name) {
|
|
11942
|
+
const parts = name.trim().split(/\s+/);
|
|
11943
|
+
if (parts.length >= 2)
|
|
11944
|
+
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
11945
|
+
return name.slice(0, 2).toUpperCase();
|
|
11946
|
+
}
|
|
11947
|
+
// =============================================================================
|
|
11948
|
+
// Component
|
|
11949
|
+
// =============================================================================
|
|
11950
|
+
/**
|
|
11951
|
+
* EntityCard — Standardized card for pipeline/board views
|
|
11952
|
+
*
|
|
11953
|
+
* Renders a compact card with title, value, status, assignee, and metadata.
|
|
11954
|
+
* Designed for use in KanbanBoard columns and process view lists.
|
|
11955
|
+
*/
|
|
11956
|
+
function EntityCard({ title, subtitle, value, status, statusColor = 'slate', assignee, progress, metadata, icon, onClick, onContextMenu, selected = false, draggable = false, size = 'md', className = '', confidence, }) {
|
|
11957
|
+
const isCompact = size === 'sm';
|
|
11958
|
+
const colors = statusColors$1[statusColor];
|
|
11959
|
+
return (jsxRuntime.jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
|
|
11960
|
+
onClick(); } : undefined, className: `
|
|
11961
|
+
group relative rounded-lg border bg-white dark:bg-ink-900
|
|
11962
|
+
${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
|
|
11963
|
+
${onClick ? 'cursor-pointer hover:shadow-md hover:border-primary-300 transition-all' : ''}
|
|
11964
|
+
${draggable ? 'cursor-grab active:cursor-grabbing' : ''}
|
|
11965
|
+
${isCompact ? 'p-3' : 'p-4'}
|
|
11966
|
+
${className}
|
|
11967
|
+
`, children: [draggable && (jsxRuntime.jsx("div", { className: "absolute left-1 top-1/2 -translate-y-1/2 w-1 h-6 rounded-full bg-ink-200 opacity-0 group-hover:opacity-100 transition-opacity" })), jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [icon && (jsxRuntime.jsx("div", { className: "flex-shrink-0 text-ink-400 mt-0.5", children: icon })), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsx("h4", { className: `font-medium text-ink-900 dark:text-ink-100 truncate ${isCompact ? 'text-sm' : 'text-base'}`, children: title }), subtitle && (jsxRuntime.jsx("p", { className: `text-ink-500 dark:text-ink-400 truncate ${isCompact ? 'text-xs' : 'text-sm'}`, children: subtitle }))] }), onContextMenu && (jsxRuntime.jsx("button", { type: "button", onClick: (e) => { e.stopPropagation(); onContextMenu(); }, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-paper-100 transition-opacity", "aria-label": "More options", children: jsxRuntime.jsx(lucideReact.MoreHorizontal, { className: "h-4 w-4 text-ink-400" }) }))] }), (value || status) && (jsxRuntime.jsxs("div", { className: `flex items-center justify-between gap-2 ${isCompact ? 'mt-2' : 'mt-3'}`, children: [value && (jsxRuntime.jsx("span", { className: `font-semibold text-ink-900 dark:text-ink-100 ${isCompact ? 'text-sm' : 'text-lg'}`, children: value })), status && colors && (jsxRuntime.jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${colors.bg} ${colors.text}`, children: status }))] })), metadata && metadata.length > 0 && (jsxRuntime.jsx("div", { className: `grid grid-cols-2 gap-x-3 gap-y-1 ${isCompact ? 'mt-2' : 'mt-3'}`, children: metadata.map((item, idx) => (jsxRuntime.jsxs("div", { className: "min-w-0", children: [jsxRuntime.jsx("span", { className: "text-xs text-ink-400", children: item.label }), jsxRuntime.jsx("div", { className: "text-xs text-ink-600 dark:text-ink-300 truncate", children: item.value })] }, idx))) })), (progress !== undefined || assignee || confidence !== undefined) && (jsxRuntime.jsxs("div", { className: `flex items-center justify-between gap-2 ${isCompact ? 'mt-2' : 'mt-3'}`, children: [progress !== undefined && (jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntime.jsx("div", { className: "h-1.5 bg-paper-200 rounded-full overflow-hidden", children: jsxRuntime.jsx("div", { className: "h-full bg-primary-500 rounded-full transition-all", style: { width: `${Math.min(100, Math.max(0, progress))}%` } }) }) })), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [confidence !== undefined && (jsxRuntime.jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded ${confidence >= 80 ? 'bg-success-50 text-success-700' :
|
|
11968
|
+
confidence >= 50 ? 'bg-warning-50 text-warning-700' :
|
|
11969
|
+
'bg-error-50 text-error-700'}`, children: [confidence, "%"] })), assignee && (jsxRuntime.jsx("div", { className: "w-6 h-6 rounded-full bg-primary-100 flex items-center justify-center flex-shrink-0", title: assignee, children: jsxRuntime.jsx("span", { className: "text-xs font-medium text-primary-700", children: getInitials(assignee) }) }))] })] }))] }));
|
|
11970
|
+
}
|
|
11971
|
+
|
|
11972
|
+
// =============================================================================
|
|
11973
|
+
// Component
|
|
11974
|
+
// =============================================================================
|
|
11975
|
+
/**
|
|
11976
|
+
* SplitPane — Resizable two-panel layout
|
|
11977
|
+
*
|
|
11978
|
+
* Renders a left/primary panel and right/secondary panel with a draggable divider.
|
|
11979
|
+
* Used for list+detail patterns (case queue + case detail, statements + line items).
|
|
11980
|
+
*
|
|
11981
|
+
* The right panel can be toggled on/off via `showRight` prop.
|
|
11982
|
+
*/
|
|
11983
|
+
function SplitPane({ left, right, defaultSplit = 0.4, minLeftWidth = 200, minRightWidth = 300, resizable = true, showRight = true, orientation = 'horizontal', onSplitChange, className = '', }) {
|
|
11984
|
+
const containerRef = React.useRef(null);
|
|
11985
|
+
const [splitRatio, setSplitRatio] = React.useState(defaultSplit);
|
|
11986
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
11987
|
+
const handleMouseDown = React.useCallback((e) => {
|
|
11988
|
+
if (!resizable)
|
|
11989
|
+
return;
|
|
11990
|
+
e.preventDefault();
|
|
11991
|
+
setIsDragging(true);
|
|
11992
|
+
}, [resizable]);
|
|
11993
|
+
React.useEffect(() => {
|
|
11994
|
+
if (!isDragging)
|
|
11995
|
+
return;
|
|
11996
|
+
const handleMouseMove = (e) => {
|
|
11997
|
+
if (!containerRef.current)
|
|
11998
|
+
return;
|
|
11999
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
12000
|
+
const isHorizontal = orientation === 'horizontal';
|
|
12001
|
+
const containerSize = isHorizontal ? rect.width : rect.height;
|
|
12002
|
+
const position = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;
|
|
12003
|
+
// Enforce min widths
|
|
12004
|
+
const minLeft = minLeftWidth / containerSize;
|
|
12005
|
+
const maxLeft = 1 - (minRightWidth / containerSize);
|
|
12006
|
+
const newRatio = Math.min(maxLeft, Math.max(minLeft, position / containerSize));
|
|
12007
|
+
setSplitRatio(newRatio);
|
|
12008
|
+
onSplitChange?.(newRatio);
|
|
12009
|
+
};
|
|
12010
|
+
const handleMouseUp = () => {
|
|
12011
|
+
setIsDragging(false);
|
|
12012
|
+
};
|
|
12013
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
12014
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
12015
|
+
return () => {
|
|
12016
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
12017
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
12018
|
+
};
|
|
12019
|
+
}, [isDragging, orientation, minLeftWidth, minRightWidth, onSplitChange]);
|
|
12020
|
+
const isHorizontal = orientation === 'horizontal';
|
|
12021
|
+
if (!showRight) {
|
|
12022
|
+
return (jsxRuntime.jsx("div", { className: `h-full ${className}`, children: left }));
|
|
12023
|
+
}
|
|
12024
|
+
const leftSize = `${(splitRatio * 100).toFixed(1)}%`;
|
|
12025
|
+
const rightSize = `${((1 - splitRatio) * 100).toFixed(1)}%`;
|
|
12026
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: `
|
|
12027
|
+
flex h-full overflow-hidden
|
|
12028
|
+
${isHorizontal ? 'flex-row' : 'flex-col'}
|
|
12029
|
+
${isDragging ? 'select-none' : ''}
|
|
12030
|
+
${className}
|
|
12031
|
+
`, children: [jsxRuntime.jsx("div", { className: "overflow-auto", style: isHorizontal ? { width: leftSize } : { height: leftSize }, children: left }), jsxRuntime.jsx("div", { onMouseDown: handleMouseDown, className: `
|
|
12032
|
+
flex-shrink-0 bg-paper-200 dark:bg-ink-700
|
|
12033
|
+
${isHorizontal ? 'w-px hover:w-1' : 'h-px hover:h-1'}
|
|
12034
|
+
${resizable ? 'cursor-col-resize hover:bg-primary-300 transition-all' : ''}
|
|
12035
|
+
${isDragging ? 'bg-primary-400 w-1' : ''}
|
|
12036
|
+
`, role: "separator", "aria-orientation": isHorizontal ? 'vertical' : 'horizontal' }), jsxRuntime.jsx("div", { className: "overflow-auto", style: isHorizontal ? { width: rightSize } : { height: rightSize }, children: right })] }));
|
|
12037
|
+
}
|
|
12038
|
+
|
|
12039
|
+
// =============================================================================
|
|
12040
|
+
// Helpers
|
|
12041
|
+
// =============================================================================
|
|
12042
|
+
const priorityConfig = {
|
|
12043
|
+
critical: { bg: 'bg-red-50', text: 'text-red-700', label: 'Critical', dot: 'bg-red-500' },
|
|
12044
|
+
high: { bg: 'bg-orange-50', text: 'text-orange-700', label: 'High', dot: 'bg-orange-500' },
|
|
12045
|
+
medium: { bg: 'bg-yellow-50', text: 'text-yellow-700', label: 'Medium', dot: 'bg-yellow-500' },
|
|
12046
|
+
low: { bg: 'bg-blue-50', text: 'text-blue-700', label: 'Low', dot: 'bg-blue-500' },
|
|
12047
|
+
};
|
|
12048
|
+
const statusColors = {
|
|
12049
|
+
slate: { bg: 'bg-slate-100', text: 'text-slate-700' },
|
|
12050
|
+
blue: { bg: 'bg-blue-100', text: 'text-blue-700' },
|
|
12051
|
+
indigo: { bg: 'bg-indigo-100', text: 'text-indigo-700' },
|
|
12052
|
+
purple: { bg: 'bg-purple-100', text: 'text-purple-700' },
|
|
12053
|
+
green: { bg: 'bg-green-100', text: 'text-green-700' },
|
|
12054
|
+
red: { bg: 'bg-red-100', text: 'text-red-700' },
|
|
12055
|
+
yellow: { bg: 'bg-yellow-100', text: 'text-yellow-700' },
|
|
12056
|
+
orange: { bg: 'bg-orange-100', text: 'text-orange-700' },
|
|
12057
|
+
teal: { bg: 'bg-teal-100', text: 'text-teal-700' },
|
|
12058
|
+
};
|
|
12059
|
+
// =============================================================================
|
|
12060
|
+
// Component
|
|
12061
|
+
// =============================================================================
|
|
12062
|
+
/**
|
|
12063
|
+
* CaseQueueItem — Priority-sorted case card for support queue views
|
|
12064
|
+
*
|
|
12065
|
+
* Shows case subject, priority indicator, status, assignee, and SLA countdown.
|
|
12066
|
+
* Designed for use in the Support Center's case queue list.
|
|
12067
|
+
*/
|
|
12068
|
+
function CaseQueueItem({ caseNumber, subject, priority, status, statusColor = 'slate', assignee, account, slaBreach = false, slaTimeRemaining, onClick, selected = false, className = '', }) {
|
|
12069
|
+
const prio = priorityConfig[priority] || priorityConfig.medium;
|
|
12070
|
+
const stColor = statusColors[statusColor];
|
|
12071
|
+
return (jsxRuntime.jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
|
|
12072
|
+
onClick(); } : undefined, className: `
|
|
12073
|
+
group relative rounded-lg border bg-white dark:bg-ink-900 p-4
|
|
12074
|
+
${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
|
|
12075
|
+
${onClick ? 'cursor-pointer hover:shadow-md hover:border-primary-300 transition-all' : ''}
|
|
12076
|
+
${slaBreach ? 'border-l-4 border-l-red-500' : ''}
|
|
12077
|
+
${className}
|
|
12078
|
+
`, "aria-label": `Case ${caseNumber}: ${subject}`, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 mb-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("span", { className: "text-xs font-mono text-ink-400", children: caseNumber }), jsxRuntime.jsxs("span", { className: `inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${prio.bg} ${prio.text}`, children: [jsxRuntime.jsx("span", { className: `w-1.5 h-1.5 rounded-full ${prio.dot}` }), prio.label] })] }), (slaTimeRemaining || slaBreach) && (jsxRuntime.jsxs("div", { className: `flex items-center gap-1 text-xs ${slaBreach ? 'text-red-600 font-medium' : 'text-ink-500'}`, children: [slaBreach ? jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-3 w-3" }) : jsxRuntime.jsx(lucideReact.Clock, { className: "h-3 w-3" }), jsxRuntime.jsx("span", { children: slaBreach ? 'SLA Breached' : slaTimeRemaining })] }))] }), jsxRuntime.jsx("h4", { className: "text-sm font-medium text-ink-900 dark:text-ink-100 mb-1 line-clamp-2", children: subject }), account && (jsxRuntime.jsx("p", { className: "text-xs text-ink-500 mb-2", children: account })), jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [stColor && (jsxRuntime.jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${stColor.bg} ${stColor.text}`, children: status })), assignee && (jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-xs text-ink-500", children: [jsxRuntime.jsx(lucideReact.User, { className: "h-3 w-3" }), jsxRuntime.jsx("span", { children: assignee })] }))] })] }));
|
|
12079
|
+
}
|
|
12080
|
+
|
|
12081
|
+
// =============================================================================
|
|
12082
|
+
// Helpers
|
|
12083
|
+
// =============================================================================
|
|
12084
|
+
const statusConfig$1 = {
|
|
12085
|
+
'on-track': { icon: jsxRuntime.jsx(lucideReact.Clock, { className: "h-4 w-4" }), color: 'text-success-600', bg: 'bg-success-50', text: 'text-success-700', label: 'On Track' },
|
|
12086
|
+
'at-risk': { icon: jsxRuntime.jsx(lucideReact.Clock, { className: "h-4 w-4" }), color: 'text-warning-600', bg: 'bg-warning-50', text: 'text-warning-700', label: 'At Risk' },
|
|
12087
|
+
'breached': { icon: jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4" }), color: 'text-error-600', bg: 'bg-error-50', text: 'text-error-700', label: 'Breached' },
|
|
12088
|
+
'met': { icon: jsxRuntime.jsx(lucideReact.CheckCircle, { className: "h-4 w-4" }), color: 'text-success-600', bg: 'bg-success-50', text: 'text-success-700', label: 'Met' },
|
|
12089
|
+
};
|
|
12090
|
+
const progressColors = {
|
|
12091
|
+
'on-track': 'bg-success-500',
|
|
12092
|
+
'at-risk': 'bg-warning-500',
|
|
12093
|
+
'breached': 'bg-error-500',
|
|
12094
|
+
'met': 'bg-success-500',
|
|
12095
|
+
};
|
|
12096
|
+
// =============================================================================
|
|
12097
|
+
// Component
|
|
12098
|
+
// =============================================================================
|
|
12099
|
+
/**
|
|
12100
|
+
* SLAIndicator — Visual SLA countdown with urgency coloring
|
|
12101
|
+
*
|
|
12102
|
+
* Shows time remaining, progress bar, and status icon.
|
|
12103
|
+
* Used in Support Center case queue items and case detail views.
|
|
12104
|
+
*/
|
|
12105
|
+
function SLAIndicator({ timeRemaining, totalMinutes, elapsedMinutes, status, size = 'md', compact = false, className = '', }) {
|
|
12106
|
+
const config = statusConfig$1[status] || statusConfig$1['on-track'];
|
|
12107
|
+
const progressPercent = totalMinutes && elapsedMinutes
|
|
12108
|
+
? Math.min(100, (elapsedMinutes / totalMinutes) * 100)
|
|
12109
|
+
: undefined;
|
|
12110
|
+
if (compact) {
|
|
12111
|
+
return (jsxRuntime.jsxs("span", { className: `inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium ${config.bg} ${config.text} ${className}`, children: [config.icon, jsxRuntime.jsx("span", { children: timeRemaining || config.label })] }));
|
|
12112
|
+
}
|
|
12113
|
+
const sizeClasses = {
|
|
12114
|
+
sm: { text: 'text-sm', icon: 'h-4 w-4', bar: 'h-1' },
|
|
12115
|
+
md: { text: 'text-base', icon: 'h-5 w-5', bar: 'h-1.5' },
|
|
12116
|
+
lg: { text: 'text-lg', icon: 'h-6 w-6', bar: 'h-2' },
|
|
12117
|
+
};
|
|
12118
|
+
const sizes = sizeClasses[size];
|
|
12119
|
+
return (jsxRuntime.jsxs("div", { className: `${className}`, children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [jsxRuntime.jsxs("div", { className: `flex items-center gap-1.5 ${config.color}`, children: [config.icon, jsxRuntime.jsx("span", { className: `${sizes.text} font-medium`, children: config.label })] }), timeRemaining && (jsxRuntime.jsx("span", { className: `${sizes.text} font-mono ${config.color}`, children: timeRemaining }))] }), progressPercent !== undefined && (jsxRuntime.jsx("div", { className: `${sizes.bar} bg-paper-200 rounded-full overflow-hidden`, children: jsxRuntime.jsx("div", { className: `h-full ${progressColors[status]} rounded-full transition-all`, style: { width: `${progressPercent}%` } }) }))] }));
|
|
12120
|
+
}
|
|
12121
|
+
|
|
12122
|
+
// =============================================================================
|
|
12123
|
+
// Config
|
|
12124
|
+
// =============================================================================
|
|
12125
|
+
const qualityConfig = {
|
|
12126
|
+
exact: { icon: jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }), color: 'text-success-600', dot: 'bg-success-500', label: 'Exact Match' },
|
|
12127
|
+
close: { icon: jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3" }), color: 'text-blue-600', dot: 'bg-blue-500', label: 'Close Match' },
|
|
12128
|
+
possible: { icon: jsxRuntime.jsx(lucideReact.HelpCircle, { className: "h-3 w-3" }), color: 'text-warning-600', dot: 'bg-warning-500', label: 'Possible Match' },
|
|
12129
|
+
unmatched: { icon: jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }), color: 'text-error-600', dot: 'bg-error-500', label: 'Unmatched' },
|
|
12130
|
+
};
|
|
12131
|
+
// =============================================================================
|
|
12132
|
+
// Component
|
|
12133
|
+
// =============================================================================
|
|
12134
|
+
/**
|
|
12135
|
+
* MatchIndicator — Match quality visualization for reconciliation
|
|
12136
|
+
*
|
|
12137
|
+
* Shows a color-coded dot/icon indicating match quality between
|
|
12138
|
+
* statement lines and invoices. Used in the Reconciliation Hub.
|
|
12139
|
+
*/
|
|
12140
|
+
function MatchIndicator({ quality, confidence, showLabel = false, size = 'md', className = '', }) {
|
|
12141
|
+
const config = qualityConfig[quality] || qualityConfig.unmatched;
|
|
12142
|
+
const sizeClasses = {
|
|
12143
|
+
sm: { dot: 'w-2 h-2', text: 'text-xs', icon: 'h-3 w-3' },
|
|
12144
|
+
md: { dot: 'w-2.5 h-2.5', text: 'text-sm', icon: 'h-4 w-4' },
|
|
12145
|
+
lg: { dot: 'w-3 h-3', text: 'text-base', icon: 'h-5 w-5' },
|
|
12146
|
+
};
|
|
12147
|
+
const sizes = sizeClasses[size];
|
|
12148
|
+
return (jsxRuntime.jsxs("div", { className: `inline-flex items-center gap-1.5 ${className}`, title: config.label, children: [jsxRuntime.jsx("span", { className: `${sizes.dot} rounded-full ${config.dot} flex-shrink-0` }), showLabel && (jsxRuntime.jsx("span", { className: `${sizes.text} ${config.color} font-medium`, children: config.label })), confidence !== undefined && (jsxRuntime.jsxs("span", { className: `${sizes.text} text-ink-400`, children: [confidence, "%"] }))] }));
|
|
12149
|
+
}
|
|
12150
|
+
|
|
12151
|
+
// =============================================================================
|
|
12152
|
+
// Helpers
|
|
12153
|
+
// =============================================================================
|
|
12154
|
+
function formatValue(value, format, currency) {
|
|
12155
|
+
switch (format) {
|
|
12156
|
+
case 'currency':
|
|
12157
|
+
return new Intl.NumberFormat('en-US', { style: 'currency', currency, minimumFractionDigits: 2 }).format(value);
|
|
12158
|
+
case 'percentage':
|
|
12159
|
+
return `${value.toFixed(1)}%`;
|
|
12160
|
+
default:
|
|
12161
|
+
return value.toLocaleString();
|
|
12162
|
+
}
|
|
12163
|
+
}
|
|
12164
|
+
// =============================================================================
|
|
12165
|
+
// Component
|
|
12166
|
+
// =============================================================================
|
|
12167
|
+
/**
|
|
12168
|
+
* VarianceDisplay — Expected vs actual comparison with tolerance coloring
|
|
12169
|
+
*
|
|
12170
|
+
* Shows the difference between expected and actual values, color-coded
|
|
12171
|
+
* by tolerance thresholds. Used in the Reconciliation Hub for variance analysis.
|
|
12172
|
+
*/
|
|
12173
|
+
function VarianceDisplay({ expected, actual, format = 'currency', currency = 'USD', tolerancePercent = 1, showValues = true, size = 'md', className = '', }) {
|
|
12174
|
+
const variance = actual - expected;
|
|
12175
|
+
const variancePercent = expected !== 0 ? (variance / expected) * 100 : 0;
|
|
12176
|
+
const absVariancePercent = Math.abs(variancePercent);
|
|
12177
|
+
const isWithinTolerance = absVariancePercent <= tolerancePercent;
|
|
12178
|
+
const isOver = variance > 0;
|
|
12179
|
+
const isExact = variance === 0;
|
|
12180
|
+
const colorClass = isExact ? 'text-success-600' :
|
|
12181
|
+
isWithinTolerance ? 'text-ink-600' :
|
|
12182
|
+
isOver ? 'text-blue-600' : 'text-error-600';
|
|
12183
|
+
const bgClass = isExact ? 'bg-success-50' :
|
|
12184
|
+
isWithinTolerance ? 'bg-paper-100' :
|
|
12185
|
+
isOver ? 'bg-blue-50' : 'bg-error-50';
|
|
12186
|
+
const sizeClasses = {
|
|
12187
|
+
sm: { text: 'text-xs', value: 'text-sm' },
|
|
12188
|
+
md: { text: 'text-sm', value: 'text-base' },
|
|
12189
|
+
lg: { text: 'text-base', value: 'text-lg' },
|
|
12190
|
+
};
|
|
12191
|
+
const sizes = sizeClasses[size];
|
|
12192
|
+
const VarianceIcon = isExact ? lucideReact.Minus : isOver ? lucideReact.ArrowUp : lucideReact.ArrowDown;
|
|
12193
|
+
return (jsxRuntime.jsxs("div", { className: `${className}`, children: [showValues && (jsxRuntime.jsxs("div", { className: `flex items-center justify-between gap-4 mb-1 ${sizes.text}`, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { className: "text-ink-400", children: "Expected: " }), jsxRuntime.jsx("span", { className: "text-ink-700 font-medium", children: formatValue(expected, format, currency) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { className: "text-ink-400", children: "Actual: " }), jsxRuntime.jsx("span", { className: "text-ink-700 font-medium", children: formatValue(actual, format, currency) })] })] })), jsxRuntime.jsxs("div", { className: `inline-flex items-center gap-1 px-2 py-1 rounded ${bgClass} ${colorClass}`, children: [jsxRuntime.jsx(VarianceIcon, { className: "h-3 w-3" }), jsxRuntime.jsxs("span", { className: `${sizes.value} font-medium`, children: [variance >= 0 ? '+' : '', formatValue(variance, format, currency)] }), jsxRuntime.jsxs("span", { className: `${sizes.text} opacity-75`, children: ["(", variancePercent >= 0 ? '+' : '', variancePercent.toFixed(1), "%)"] }), isWithinTolerance && !isExact && (jsxRuntime.jsx("span", { className: `${sizes.text} text-ink-400 ml-1`, children: "within tolerance" }))] })] }));
|
|
12194
|
+
}
|
|
12195
|
+
|
|
12196
|
+
// =============================================================================
|
|
12197
|
+
// Helpers
|
|
12198
|
+
// =============================================================================
|
|
12199
|
+
const priorityStyles = {
|
|
12200
|
+
high: { border: 'border-l-4 border-l-red-400', dot: 'bg-red-500' },
|
|
12201
|
+
medium: { border: 'border-l-4 border-l-yellow-400', dot: 'bg-yellow-500' },
|
|
12202
|
+
low: { border: 'border-l-4 border-l-blue-400', dot: 'bg-blue-500' },
|
|
12203
|
+
};
|
|
12204
|
+
const buttonVariants$1 = {
|
|
12205
|
+
primary: 'bg-primary-600 text-white hover:bg-primary-700',
|
|
12206
|
+
secondary: 'bg-paper-100 text-ink-700 hover:bg-paper-200 border border-paper-300',
|
|
12207
|
+
danger: 'bg-error-600 text-white hover:bg-error-700',
|
|
12208
|
+
ghost: 'text-ink-600 hover:bg-paper-100',
|
|
12209
|
+
};
|
|
12210
|
+
// =============================================================================
|
|
12211
|
+
// Component
|
|
12212
|
+
// =============================================================================
|
|
12213
|
+
/**
|
|
12214
|
+
* ActionCard — Approval workflow card with action buttons
|
|
12215
|
+
*
|
|
12216
|
+
* Shows what needs action, why it was flagged, and provides quick-action buttons.
|
|
12217
|
+
* Used in the Approvals & Review queue across all process domains.
|
|
12218
|
+
*/
|
|
12219
|
+
function ActionCard({ title, description, entityType, entityId, onEntityClick, reasoning, actions, priority, icon, confidence, timestamp, selected = false, className = '', }) {
|
|
12220
|
+
const prioStyle = priority ? priorityStyles[priority] : undefined;
|
|
12221
|
+
return (jsxRuntime.jsxs("div", { className: `
|
|
12222
|
+
rounded-lg border bg-white dark:bg-ink-900 p-4
|
|
12223
|
+
${selected ? 'border-primary-400 ring-2 ring-primary-100' : 'border-paper-200 dark:border-ink-700'}
|
|
12224
|
+
${prioStyle?.border || ''}
|
|
12225
|
+
${className}
|
|
12226
|
+
`, children: [jsxRuntime.jsxs("div", { className: "flex items-start gap-3 mb-3", children: [icon && (jsxRuntime.jsx("div", { className: "flex-shrink-0 text-ink-400 mt-0.5", children: icon })), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("h4", { className: "text-sm font-medium text-ink-900 dark:text-ink-100", children: title }), priority && prioStyle && (jsxRuntime.jsx("span", { className: `w-2 h-2 rounded-full ${prioStyle.dot} flex-shrink-0` }))] }), description && (jsxRuntime.jsx("p", { className: "text-sm text-ink-500 mt-0.5", children: description }))] }), confidence !== undefined && (jsxRuntime.jsxs("span", { className: `text-xs px-2 py-0.5 rounded flex-shrink-0 ${confidence >= 80 ? 'bg-success-50 text-success-700' :
|
|
12227
|
+
confidence >= 50 ? 'bg-warning-50 text-warning-700' :
|
|
12228
|
+
'bg-error-50 text-error-700'}`, children: [confidence, "% confidence"] }))] }), entityType && entityId && (jsxRuntime.jsx("div", { className: "mb-2", children: jsxRuntime.jsxs("button", { type: "button", onClick: onEntityClick, className: "text-xs text-primary-600 hover:text-primary-700 hover:underline", children: [entityType, " #", entityId] }) })), reasoning && (jsxRuntime.jsx("div", { className: "mb-3 px-3 py-2 bg-paper-50 dark:bg-ink-800 rounded text-xs text-ink-600 dark:text-ink-400 border-l-2 border-ink-200", children: reasoning })), jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: actions.map((action, idx) => (jsxRuntime.jsxs("button", { type: "button", onClick: action.onClick, disabled: action.disabled, className: `
|
|
12229
|
+
inline-flex items-center gap-1 px-3 py-1.5 rounded text-xs font-medium
|
|
12230
|
+
transition-colors disabled:opacity-50 disabled:cursor-not-allowed
|
|
12231
|
+
${buttonVariants$1[action.variant || 'secondary']}
|
|
12232
|
+
`, children: [action.icon, action.label] }, idx))) }), timestamp && (jsxRuntime.jsx("span", { className: "text-xs text-ink-400 flex-shrink-0", children: timestamp }))] })] }));
|
|
12233
|
+
}
|
|
12234
|
+
|
|
12235
|
+
// =============================================================================
|
|
12236
|
+
// Helpers
|
|
12237
|
+
// =============================================================================
|
|
12238
|
+
const domainColors = {
|
|
12239
|
+
sales: { bg: 'bg-blue-50', text: 'text-blue-700' },
|
|
12240
|
+
support: { bg: 'bg-teal-50', text: 'text-teal-700' },
|
|
12241
|
+
commission: { bg: 'bg-green-50', text: 'text-green-700' },
|
|
12242
|
+
reconciliation: { bg: 'bg-indigo-50', text: 'text-indigo-700' },
|
|
12243
|
+
};
|
|
12244
|
+
// =============================================================================
|
|
12245
|
+
// Component
|
|
12246
|
+
// =============================================================================
|
|
12247
|
+
/**
|
|
12248
|
+
* SystemActionEntry — Activity feed entry showing what the system did
|
|
12249
|
+
*
|
|
12250
|
+
* Each entry shows: action description, reasoning, affected entity (clickable),
|
|
12251
|
+
* revert button (if applicable), confidence indicator, and timestamp.
|
|
12252
|
+
* Used in the Activity Center system action log.
|
|
12253
|
+
*/
|
|
12254
|
+
function SystemActionEntry({ actionDescription, reasoning, entityType, entityLabel, onEntityClick, isRevertible = false, onRevert, confidence, actor = 'System', timestamp, actionType, domain, icon, reverted = false, className = '', }) {
|
|
12255
|
+
const domainColor = domain ? domainColors[domain] : undefined;
|
|
12256
|
+
return (jsxRuntime.jsxs("div", { className: `
|
|
12257
|
+
group relative flex gap-3 p-4 rounded-lg border
|
|
12258
|
+
bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700
|
|
12259
|
+
${reverted ? 'opacity-60' : ''}
|
|
12260
|
+
${className}
|
|
12261
|
+
`, children: [jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-0.5 text-ink-400", children: icon || jsxRuntime.jsx("div", { className: "w-5 h-5 rounded-full bg-primary-100 flex items-center justify-center", children: jsxRuntime.jsx("span", { className: "text-xs text-primary-600", children: "A" }) }) }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsxRuntime.jsx("p", { className: `text-sm text-ink-900 dark:text-ink-100 ${reverted ? 'line-through' : ''}`, children: actionDescription }), reverted && (jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded bg-paper-100 text-ink-500 flex-shrink-0", children: "Reverted" }))] }), jsxRuntime.jsx("p", { className: "text-xs text-ink-500 mt-1", children: reasoning }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2 flex-wrap", children: [jsxRuntime.jsxs("button", { type: "button", onClick: onEntityClick, className: "inline-flex items-center gap-1 text-xs text-primary-600 hover:text-primary-700 hover:underline", children: [entityType, ": ", entityLabel, jsxRuntime.jsx(lucideReact.ExternalLink, { className: "h-3 w-3" })] }), domainColor && domain && (jsxRuntime.jsx("span", { className: `text-xs px-1.5 py-0.5 rounded ${domainColor.bg} ${domainColor.text}`, children: domain })), confidence !== undefined && (jsxRuntime.jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded ${confidence >= 80 ? 'bg-success-50 text-success-700' :
|
|
12262
|
+
confidence >= 50 ? 'bg-warning-50 text-warning-700' :
|
|
12263
|
+
'bg-error-50 text-error-700'}`, children: [confidence, "%"] }))] }), jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 mt-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-ink-400", children: [jsxRuntime.jsx("span", { children: actor }), jsxRuntime.jsx("span", { children: "\u00B7" }), jsxRuntime.jsx("span", { children: timestamp }), actionType && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { children: "\u00B7" }), jsxRuntime.jsx("span", { children: actionType })] }))] }), isRevertible && !reverted && onRevert && (jsxRuntime.jsxs("button", { type: "button", onClick: onRevert, className: "inline-flex items-center gap-1 text-xs text-ink-500 hover:text-error-600 opacity-0 group-hover:opacity-100 transition-opacity", children: [jsxRuntime.jsx(lucideReact.RotateCcw, { className: "h-3 w-3" }), "Revert"] }))] })] })] }));
|
|
12264
|
+
}
|
|
12265
|
+
|
|
12266
|
+
// =============================================================================
|
|
12267
|
+
// Helpers
|
|
12268
|
+
// =============================================================================
|
|
12269
|
+
const healthDot = {
|
|
12270
|
+
good: 'bg-success-500',
|
|
12271
|
+
warning: 'bg-warning-500',
|
|
12272
|
+
critical: 'bg-error-500',
|
|
12273
|
+
};
|
|
12274
|
+
const healthText = {
|
|
12275
|
+
good: 'text-success-700',
|
|
12276
|
+
warning: 'text-warning-700',
|
|
12277
|
+
critical: 'text-error-700',
|
|
12278
|
+
};
|
|
12279
|
+
const trendSymbol = {
|
|
12280
|
+
up: '\u2191',
|
|
12281
|
+
down: '\u2193',
|
|
12282
|
+
stable: '\u2192',
|
|
12283
|
+
};
|
|
12284
|
+
// =============================================================================
|
|
12285
|
+
// Component
|
|
12286
|
+
// =============================================================================
|
|
12287
|
+
/**
|
|
12288
|
+
* ProcessHealthBar — Compact horizontal process health overview
|
|
12289
|
+
*
|
|
12290
|
+
* Shows traffic-light indicators for a process area's KPIs.
|
|
12291
|
+
* Used in the persona-adaptive dashboard to show overall process health.
|
|
12292
|
+
*/
|
|
12293
|
+
function ProcessHealthBar({ processName, metrics, onClick, className = '', }) {
|
|
12294
|
+
// Overall health: worst of all metrics
|
|
12295
|
+
const overallHealth = metrics.some(m => m.status === 'critical') ? 'critical' :
|
|
12296
|
+
metrics.some(m => m.status === 'warning') ? 'warning' : 'good';
|
|
12297
|
+
return (jsxRuntime.jsxs("div", { onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, onKeyDown: onClick ? (e) => { if (e.key === 'Enter' || e.key === ' ')
|
|
12298
|
+
onClick(); } : undefined, className: `
|
|
12299
|
+
flex items-center gap-4 px-4 py-3 rounded-lg border
|
|
12300
|
+
bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700
|
|
12301
|
+
${onClick ? 'cursor-pointer hover:shadow-sm hover:border-primary-300 transition-all' : ''}
|
|
12302
|
+
${className}
|
|
12303
|
+
`, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-shrink-0", children: [jsxRuntime.jsx("span", { className: `w-3 h-3 rounded-full ${healthDot[overallHealth]}` }), jsxRuntime.jsx("span", { className: "text-sm font-medium text-ink-900 dark:text-ink-100 whitespace-nowrap", children: processName })] }), jsxRuntime.jsx("div", { className: "flex items-center gap-4 overflow-x-auto flex-1", children: metrics.map((metric, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 flex-shrink-0", children: [jsxRuntime.jsx("span", { className: `w-1.5 h-1.5 rounded-full ${healthDot[metric.status]}` }), jsxRuntime.jsxs("span", { className: "text-xs text-ink-500 whitespace-nowrap", children: [metric.name, ":"] }), jsxRuntime.jsxs("span", { className: `text-xs font-medium ${healthText[metric.status]} whitespace-nowrap`, children: [metric.value, metric.trend && (jsxRuntime.jsx("span", { className: "ml-0.5", children: trendSymbol[metric.trend] }))] })] }, idx))) })] }));
|
|
12304
|
+
}
|
|
12305
|
+
|
|
12306
|
+
// =============================================================================
|
|
12307
|
+
// Default Colors
|
|
12308
|
+
// =============================================================================
|
|
12309
|
+
const defaultColors = [
|
|
12310
|
+
'#6366f1', // indigo
|
|
12311
|
+
'#8b5cf6', // violet
|
|
12312
|
+
'#a78bfa', // violet lighter
|
|
12313
|
+
'#c084fc', // purple lighter
|
|
12314
|
+
'#d8b4fe', // purple lightest
|
|
12315
|
+
'#e9d5ff', // purple very light
|
|
12316
|
+
'#f3e8ff', // purple ultra light
|
|
12317
|
+
];
|
|
12318
|
+
// =============================================================================
|
|
12319
|
+
// Component
|
|
12320
|
+
// =============================================================================
|
|
12321
|
+
/**
|
|
12322
|
+
* FunnelChart — SVG funnel visualization for pipeline stages
|
|
12323
|
+
*
|
|
12324
|
+
* Renders a vertical funnel where each stage's width is proportional
|
|
12325
|
+
* to its count relative to the first (widest) stage.
|
|
12326
|
+
* Shows stage names, counts, values, and optional conversion rates.
|
|
12327
|
+
*/
|
|
12328
|
+
function FunnelChart({ stages, height = 300, showConversion = true, onStageClick, className = '', }) {
|
|
12329
|
+
if (stages.length === 0)
|
|
12330
|
+
return null;
|
|
12331
|
+
const maxCount = Math.max(...stages.map(s => s.count), 1);
|
|
12332
|
+
const stageHeight = height / stages.length;
|
|
12333
|
+
const svgWidth = 400;
|
|
12334
|
+
const padding = 20;
|
|
12335
|
+
const funnelWidth = svgWidth - padding * 2 - 160; // Leave room for labels
|
|
12336
|
+
return (jsxRuntime.jsx("div", { className: className, children: jsxRuntime.jsx("svg", { width: "100%", viewBox: `0 0 ${svgWidth} ${height}`, preserveAspectRatio: "xMidYMid meet", children: stages.map((stage, idx) => {
|
|
12337
|
+
const ratio = stage.count / maxCount;
|
|
12338
|
+
const nextRatio = idx < stages.length - 1 ? stages[idx + 1].count / maxCount : ratio;
|
|
12339
|
+
const y = idx * stageHeight;
|
|
12340
|
+
const topWidth = funnelWidth * ratio;
|
|
12341
|
+
const bottomWidth = funnelWidth * nextRatio;
|
|
12342
|
+
const centerX = padding + funnelWidth / 2;
|
|
12343
|
+
const color = stage.color || defaultColors[idx % defaultColors.length];
|
|
12344
|
+
// Conversion rate
|
|
12345
|
+
const conversionRate = idx > 0 && stages[idx - 1].count > 0
|
|
12346
|
+
? Math.round((stage.count / stages[idx - 1].count) * 100)
|
|
12347
|
+
: null;
|
|
12348
|
+
// Trapezoid path
|
|
12349
|
+
const path = `
|
|
12350
|
+
M ${centerX - topWidth / 2} ${y + 2}
|
|
12351
|
+
L ${centerX + topWidth / 2} ${y + 2}
|
|
12352
|
+
L ${centerX + bottomWidth / 2} ${y + stageHeight - 2}
|
|
12353
|
+
L ${centerX - bottomWidth / 2} ${y + stageHeight - 2}
|
|
12354
|
+
Z
|
|
12355
|
+
`;
|
|
12356
|
+
return (jsxRuntime.jsxs("g", { onClick: () => onStageClick?.(stage.name), style: onStageClick ? { cursor: 'pointer' } : undefined, role: onStageClick ? 'button' : undefined, children: [jsxRuntime.jsx("path", { d: path, fill: color, opacity: 0.85, className: "transition-opacity hover:opacity-100" }), jsxRuntime.jsx("text", { x: centerX, y: y + stageHeight / 2 + 1, textAnchor: "middle", dominantBaseline: "middle", className: "fill-white text-xs font-bold", style: { fontSize: '12px' }, children: stage.count.toLocaleString() }), jsxRuntime.jsx("text", { x: centerX + funnelWidth / 2 + 12, y: y + stageHeight / 2 - 6, className: "fill-ink-700 dark:fill-ink-300", style: { fontSize: '11px', fontWeight: 500 }, children: stage.name }), stage.value && (jsxRuntime.jsx("text", { x: centerX + funnelWidth / 2 + 12, y: y + stageHeight / 2 + 8, className: "fill-ink-400", style: { fontSize: '10px' }, children: stage.value })), showConversion && conversionRate !== null && (jsxRuntime.jsxs("text", { x: centerX - funnelWidth / 2 - 8, y: y + 4, textAnchor: "end", className: "fill-ink-400", style: { fontSize: '10px' }, children: [conversionRate, "%"] }))] }, stage.name));
|
|
12357
|
+
}) }) }));
|
|
12358
|
+
}
|
|
12359
|
+
|
|
12360
|
+
// =============================================================================
|
|
12361
|
+
// Helpers
|
|
12362
|
+
// =============================================================================
|
|
12363
|
+
const sizeClasses$2 = {
|
|
12364
|
+
sm: 'col-span-1',
|
|
12365
|
+
md: 'col-span-1 md:col-span-2',
|
|
12366
|
+
lg: 'col-span-1 md:col-span-2 lg:col-span-3',
|
|
12367
|
+
full: 'col-span-full',
|
|
12368
|
+
};
|
|
12369
|
+
// =============================================================================
|
|
12370
|
+
// Component
|
|
12371
|
+
// =============================================================================
|
|
12372
|
+
/**
|
|
12373
|
+
* PersonaDashboard — Adaptive dashboard shell for persona-specific widgets
|
|
12374
|
+
*
|
|
12375
|
+
* Provides the common dashboard structure:
|
|
12376
|
+
* 1. System action summary (hero, persona-filtered)
|
|
12377
|
+
* 2. Pending attention items
|
|
12378
|
+
* 3. Process health indicators
|
|
12379
|
+
* 4. Persona-specific widgets in a responsive grid
|
|
12380
|
+
*
|
|
12381
|
+
* Used as the layout container on the Home page, populated with
|
|
12382
|
+
* role-specific widgets based on the resolved persona.
|
|
12383
|
+
*/
|
|
12384
|
+
function PersonaDashboard({ personaName, systemSummary, pendingAttention, processHealth, widgets, className = '', }) {
|
|
12385
|
+
return (jsxRuntime.jsxs("div", { className: `space-y-6 ${className}`, children: [systemSummary && (jsxRuntime.jsx("section", { "aria-label": "System actions", children: systemSummary })), pendingAttention && (jsxRuntime.jsx("section", { "aria-label": "Items needing attention", children: pendingAttention })), processHealth && (jsxRuntime.jsx("section", { "aria-label": "Process health", children: processHealth })), widgets.length > 0 && (jsxRuntime.jsx("section", { "aria-label": `${personaName} dashboard widgets`, children: jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: widgets.map(widget => (jsxRuntime.jsx("div", { className: sizeClasses$2[widget.size], children: widget.render() }, widget.id))) }) }))] }));
|
|
12386
|
+
}
|
|
12387
|
+
|
|
12388
|
+
// =============================================================================
|
|
12389
|
+
// Component
|
|
12390
|
+
// =============================================================================
|
|
12391
|
+
/**
|
|
12392
|
+
* ConfidenceIndicator — Circular gauge showing confidence percentage
|
|
12393
|
+
*
|
|
12394
|
+
* Renders a circular progress arc with color based on score thresholds:
|
|
12395
|
+
* - >= 80: green (high confidence)
|
|
12396
|
+
* - >= 50: yellow (medium confidence)
|
|
12397
|
+
* - < 50: red (low confidence)
|
|
12398
|
+
*
|
|
12399
|
+
* Used in review workflows and process views to show system confidence
|
|
12400
|
+
* in automated actions.
|
|
12401
|
+
*/
|
|
12402
|
+
function ConfidenceIndicator({ score, label, size = 80, strokeWidth = 6, className = '', }) {
|
|
12403
|
+
const normalizedScore = Math.min(100, Math.max(0, score));
|
|
12404
|
+
const radius = (size - strokeWidth) / 2;
|
|
12405
|
+
const circumference = 2 * Math.PI * radius;
|
|
12406
|
+
const offset = circumference - (normalizedScore / 100) * circumference;
|
|
12407
|
+
const center = size / 2;
|
|
12408
|
+
const color = normalizedScore >= 80 ? '#10b981' : // success green
|
|
12409
|
+
normalizedScore >= 50 ? '#f59e0b' : // warning amber
|
|
12410
|
+
'#ef4444'; // error red
|
|
12411
|
+
const bgColor = normalizedScore >= 80 ? '#d1fae5' :
|
|
12412
|
+
normalizedScore >= 50 ? '#fef3c7' :
|
|
12413
|
+
'#fee2e2';
|
|
12414
|
+
return (jsxRuntime.jsxs("div", { className: `inline-flex flex-col items-center ${className}`, children: [jsxRuntime.jsxs("div", { className: "relative", style: { width: size, height: size }, children: [jsxRuntime.jsxs("svg", { width: size, height: size, className: "transform -rotate-90", children: [jsxRuntime.jsx("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: bgColor, strokeWidth: strokeWidth }), jsxRuntime.jsx("circle", { cx: center, cy: center, r: radius, fill: "none", stroke: color, strokeWidth: strokeWidth, strokeLinecap: "round", strokeDasharray: circumference, strokeDashoffset: offset, className: "transition-all duration-500 ease-out" })] }), jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: jsxRuntime.jsxs("span", { className: "font-bold text-ink-900 dark:text-ink-100", style: { fontSize: size * 0.22 }, children: [normalizedScore, "%"] }) })] }), label && (jsxRuntime.jsx("span", { className: "text-xs text-ink-500 mt-1", children: label }))] }));
|
|
12415
|
+
}
|
|
12416
|
+
|
|
12417
|
+
// =============================================================================
|
|
12418
|
+
// Component
|
|
12419
|
+
// =============================================================================
|
|
12420
|
+
/**
|
|
12421
|
+
* ConfidenceBadge — Compact inline confidence display
|
|
12422
|
+
*
|
|
12423
|
+
* Shows a color-coded badge with optional score text.
|
|
12424
|
+
* Used in table cells, Kanban cards, and list items where
|
|
12425
|
+
* the full ConfidenceIndicator gauge would be too large.
|
|
12426
|
+
*/
|
|
12427
|
+
function ConfidenceBadge({ score, showScore = true, size = 'md', className = '', }) {
|
|
12428
|
+
const normalizedScore = Math.min(100, Math.max(0, score));
|
|
12429
|
+
const colorClasses = normalizedScore >= 80
|
|
12430
|
+
? 'bg-success-50 text-success-700 border-success-200'
|
|
12431
|
+
: normalizedScore >= 50
|
|
12432
|
+
? 'bg-warning-50 text-warning-700 border-warning-200'
|
|
12433
|
+
: 'bg-error-50 text-error-700 border-error-200';
|
|
12434
|
+
const dotColor = normalizedScore >= 80
|
|
12435
|
+
? 'bg-success-500'
|
|
12436
|
+
: normalizedScore >= 50
|
|
12437
|
+
? 'bg-warning-500'
|
|
12438
|
+
: 'bg-error-500';
|
|
12439
|
+
const sizeClasses = {
|
|
12440
|
+
sm: { wrapper: 'px-1.5 py-0.5 text-[10px]', dot: 'w-1.5 h-1.5' },
|
|
12441
|
+
md: { wrapper: 'px-2 py-0.5 text-xs', dot: 'w-2 h-2' },
|
|
12442
|
+
};
|
|
12443
|
+
const sizes = sizeClasses[size];
|
|
12444
|
+
return (jsxRuntime.jsxs("span", { className: `inline-flex items-center gap-1 rounded-full border font-medium ${sizes.wrapper} ${colorClasses} ${className}`, title: `${normalizedScore}% confidence`, children: [jsxRuntime.jsx("span", { className: `${sizes.dot} rounded-full ${dotColor} flex-shrink-0` }), showScore && jsxRuntime.jsxs("span", { children: [normalizedScore, "%"] })] }));
|
|
12445
|
+
}
|
|
12446
|
+
|
|
12447
|
+
// =============================================================================
|
|
12448
|
+
// Helpers
|
|
12449
|
+
// =============================================================================
|
|
12450
|
+
const buttonVariants = {
|
|
12451
|
+
primary: 'bg-primary-600 text-white hover:bg-primary-700',
|
|
12452
|
+
secondary: 'bg-paper-100 text-ink-700 hover:bg-paper-200 border border-paper-300',
|
|
12453
|
+
danger: 'bg-error-600 text-white hover:bg-error-700',
|
|
12454
|
+
ghost: 'text-ink-600 hover:bg-paper-100',
|
|
12455
|
+
};
|
|
12456
|
+
// =============================================================================
|
|
12457
|
+
// Component
|
|
12458
|
+
// =============================================================================
|
|
12459
|
+
/**
|
|
12460
|
+
* ReviewDecisionCard — Action card with confidence breakdown
|
|
12461
|
+
*
|
|
12462
|
+
* Extended ActionCard pattern that includes a confidence gauge and
|
|
12463
|
+
* per-factor confidence breakdown. Used in the Approvals & Review queue
|
|
12464
|
+
* for items requiring human judgment.
|
|
12465
|
+
*/
|
|
12466
|
+
function ReviewDecisionCard({ title, description, confidence, breakdown, recommendation, actions, entityType, entityLabel, onEntityClick, notes, timestamp, className = '', }) {
|
|
12467
|
+
return (jsxRuntime.jsxs("div", { className: `
|
|
12468
|
+
rounded-lg border bg-white dark:bg-ink-900 border-paper-200 dark:border-ink-700 p-5
|
|
12469
|
+
${className}
|
|
12470
|
+
`, children: [jsxRuntime.jsxs("div", { className: "flex gap-4", children: [jsxRuntime.jsx("div", { className: "flex-shrink-0", children: jsxRuntime.jsx(ConfidenceIndicator, { score: confidence, size: 72, strokeWidth: 5 }) }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsx("h4", { className: "text-base font-medium text-ink-900 dark:text-ink-100", children: title }), description && (jsxRuntime.jsx("p", { className: "text-sm text-ink-500 mt-0.5", children: description })), entityType && entityLabel && (jsxRuntime.jsxs("button", { type: "button", onClick: onEntityClick, className: "text-xs text-primary-600 hover:underline mt-1", children: [entityType, ": ", entityLabel] })), recommendation && (jsxRuntime.jsxs("div", { className: "mt-3 px-3 py-2 bg-primary-50 dark:bg-primary-900/20 rounded text-sm text-primary-700 dark:text-primary-300", children: [jsxRuntime.jsx("span", { className: "font-medium", children: "Recommendation: " }), recommendation] }))] })] }), breakdown && breakdown.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-4 pt-3 border-t border-paper-200 dark:border-ink-700", children: [jsxRuntime.jsx("h5", { className: "text-xs font-medium text-ink-500 mb-2", children: "Confidence Breakdown" }), jsxRuntime.jsx("div", { className: "space-y-2", children: breakdown.map((factor, idx) => (jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [jsxRuntime.jsx("span", { className: "text-xs text-ink-600 w-28 flex-shrink-0", children: factor.factor }), jsxRuntime.jsx("div", { className: "flex-1 h-2 bg-paper-200 rounded-full overflow-hidden", children: jsxRuntime.jsx("div", { className: `h-full rounded-full transition-all ${factor.score >= 80 ? 'bg-success-500' :
|
|
12471
|
+
factor.score >= 50 ? 'bg-warning-500' :
|
|
12472
|
+
'bg-error-500'}`, style: { width: `${factor.score}%` } }) }), jsxRuntime.jsxs("span", { className: "text-xs text-ink-400 w-10 text-right", children: [factor.score, "%"] })] }, idx))) })] })), notes && (jsxRuntime.jsx("div", { className: "mt-3 px-3 py-2 bg-paper-50 dark:bg-ink-800 rounded text-xs text-ink-600 border-l-2 border-ink-200", children: notes })), jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 mt-4 pt-3 border-t border-paper-200 dark:border-ink-700", children: [jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: actions.map((action, idx) => (jsxRuntime.jsxs("button", { type: "button", onClick: action.onClick, className: `
|
|
12473
|
+
inline-flex items-center gap-1.5 px-4 py-2 rounded text-sm font-medium
|
|
12474
|
+
transition-colors
|
|
12475
|
+
${buttonVariants[action.variant || 'secondary']}
|
|
12476
|
+
`, children: [action.icon, action.label] }, idx))) }), timestamp && (jsxRuntime.jsx("span", { className: "text-xs text-ink-400", children: timestamp }))] })] }));
|
|
12477
|
+
}
|
|
12478
|
+
|
|
12479
|
+
// =============================================================================
|
|
12480
|
+
// Helpers
|
|
12481
|
+
// =============================================================================
|
|
12482
|
+
const severityConfig = {
|
|
12483
|
+
info: { bg: 'bg-blue-50 dark:bg-blue-900/20', border: 'border-blue-200 dark:border-blue-800', text: 'text-blue-800 dark:text-blue-200', icon: 'text-blue-500' },
|
|
12484
|
+
warning: { bg: 'bg-warning-50 dark:bg-warning-900/20', border: 'border-warning-200 dark:border-warning-800', text: 'text-warning-800 dark:text-warning-200', icon: 'text-warning-500' },
|
|
12485
|
+
critical: { bg: 'bg-error-50 dark:bg-error-900/20', border: 'border-error-200 dark:border-error-800', text: 'text-error-800 dark:text-error-200', icon: 'text-error-500' },
|
|
12486
|
+
};
|
|
12487
|
+
// =============================================================================
|
|
12488
|
+
// Component
|
|
12489
|
+
// =============================================================================
|
|
12490
|
+
/**
|
|
12491
|
+
* AnomalyBanner — Alert banner for anomaly detection
|
|
12492
|
+
*
|
|
12493
|
+
* Shows a prominent banner when the system detects unusual patterns.
|
|
12494
|
+
* Severity levels: info (FYI), warning (review recommended), critical (immediate action).
|
|
12495
|
+
* Used at the top of process views and dashboards.
|
|
12496
|
+
*/
|
|
12497
|
+
function AnomalyBanner({ title, description, severity = 'warning', affectedCount, actionLabel, onAction, onDismiss, className = '', }) {
|
|
12498
|
+
const config = severityConfig[severity];
|
|
12499
|
+
return (jsxRuntime.jsxs("div", { className: `
|
|
12500
|
+
flex items-start gap-3 px-4 py-3 rounded-lg border
|
|
12501
|
+
${config.bg} ${config.border}
|
|
12502
|
+
${className}
|
|
12503
|
+
`, role: "alert", children: [jsxRuntime.jsx(lucideReact.AlertTriangle, { className: `h-5 w-5 flex-shrink-0 mt-0.5 ${config.icon}` }), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("h4", { className: `text-sm font-medium ${config.text}`, children: title }), affectedCount !== undefined && (jsxRuntime.jsxs("span", { className: `text-xs px-1.5 py-0.5 rounded-full ${config.bg} ${config.text} font-medium`, children: [affectedCount, " affected"] }))] }), description && (jsxRuntime.jsx("p", { className: `text-sm mt-1 ${config.text} opacity-80`, children: description })), actionLabel && onAction && (jsxRuntime.jsxs("button", { type: "button", onClick: onAction, className: `inline-flex items-center gap-1 text-sm font-medium mt-2 ${config.text} hover:underline`, children: [actionLabel, jsxRuntime.jsx(lucideReact.ArrowRight, { className: "h-3 w-3" })] }))] }), onDismiss && (jsxRuntime.jsx("button", { type: "button", onClick: onDismiss, className: `flex-shrink-0 p-1 rounded hover:bg-white/50 transition-colors ${config.text} opacity-60 hover:opacity-100`, "aria-label": "Dismiss", children: jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }) }))] }));
|
|
12504
|
+
}
|
|
12505
|
+
|
|
11873
12506
|
/**
|
|
11874
12507
|
* Avatar component that displays:
|
|
11875
12508
|
* - User initials in a colored circle (default)
|
|
@@ -61970,10 +62603,12 @@ exports.ActionBarCenter = ActionBarCenter;
|
|
|
61970
62603
|
exports.ActionBarLeft = ActionBarLeft;
|
|
61971
62604
|
exports.ActionBarRight = ActionBarRight;
|
|
61972
62605
|
exports.ActionButton = ActionButton;
|
|
62606
|
+
exports.ActionCard = ActionCard;
|
|
61973
62607
|
exports.ActivityFeed = ActivityFeed;
|
|
61974
62608
|
exports.AdminModal = AdminModal;
|
|
61975
62609
|
exports.Alert = Alert;
|
|
61976
62610
|
exports.AlertDialog = AlertDialog;
|
|
62611
|
+
exports.AnomalyBanner = AnomalyBanner;
|
|
61977
62612
|
exports.AppLayout = AppLayout;
|
|
61978
62613
|
exports.Autocomplete = Autocomplete;
|
|
61979
62614
|
exports.Avatar = Avatar;
|
|
@@ -61998,6 +62633,7 @@ exports.CardHeader = CardHeader;
|
|
|
61998
62633
|
exports.CardTitle = CardTitle;
|
|
61999
62634
|
exports.CardView = CardView;
|
|
62000
62635
|
exports.Carousel = Carousel;
|
|
62636
|
+
exports.CaseQueueItem = CaseQueueItem;
|
|
62001
62637
|
exports.Celebration = Celebration;
|
|
62002
62638
|
exports.Checkbox = Checkbox;
|
|
62003
62639
|
exports.CheckboxList = CheckboxList;
|
|
@@ -62011,6 +62647,8 @@ exports.Combobox = Combobox;
|
|
|
62011
62647
|
exports.ComingSoon = ComingSoon;
|
|
62012
62648
|
exports.CommandPalette = CommandPalette;
|
|
62013
62649
|
exports.CompactStat = CompactStat;
|
|
62650
|
+
exports.ConfidenceBadge = ConfidenceBadge;
|
|
62651
|
+
exports.ConfidenceIndicator = ConfidenceIndicator;
|
|
62014
62652
|
exports.ConfirmDialog = ConfirmDialog;
|
|
62015
62653
|
exports.ContextMenu = ContextMenu;
|
|
62016
62654
|
exports.ControlBar = ControlBar;
|
|
@@ -62033,6 +62671,7 @@ exports.DropZone = DropZone;
|
|
|
62033
62671
|
exports.Dropdown = Dropdown;
|
|
62034
62672
|
exports.DropdownTrigger = DropdownTrigger;
|
|
62035
62673
|
exports.EmptyState = EmptyState;
|
|
62674
|
+
exports.EntityCard = EntityCard;
|
|
62036
62675
|
exports.ErrorBoundary = ErrorBoundary;
|
|
62037
62676
|
exports.ExpandablePanel = ExpandablePanel;
|
|
62038
62677
|
exports.ExpandablePanelContainer = ExpandablePanelContainer;
|
|
@@ -62054,6 +62693,7 @@ exports.Form = Form;
|
|
|
62054
62693
|
exports.FormContext = FormContext;
|
|
62055
62694
|
exports.FormControl = FormControl;
|
|
62056
62695
|
exports.FormWizard = FormWizard;
|
|
62696
|
+
exports.FunnelChart = FunnelChart;
|
|
62057
62697
|
exports.Grid = Grid;
|
|
62058
62698
|
exports.GridItem = GridItem;
|
|
62059
62699
|
exports.HelpTooltip = HelpTooltip;
|
|
@@ -62070,6 +62710,7 @@ exports.LoadingOverlay = LoadingOverlay;
|
|
|
62070
62710
|
exports.Logo = Logo;
|
|
62071
62711
|
exports.MarkdownEditor = MarkdownEditor;
|
|
62072
62712
|
exports.MaskedInput = MaskedInput;
|
|
62713
|
+
exports.MatchIndicator = MatchIndicator;
|
|
62073
62714
|
exports.Menu = Menu;
|
|
62074
62715
|
exports.MenuDivider = MenuDivider;
|
|
62075
62716
|
exports.MobileHeader = MobileHeader;
|
|
@@ -62093,9 +62734,12 @@ exports.PageNavigation = PageNavigation;
|
|
|
62093
62734
|
exports.Pagination = Pagination;
|
|
62094
62735
|
exports.PasswordInput = PasswordInput;
|
|
62095
62736
|
exports.PermissionBadge = PermissionBadge;
|
|
62737
|
+
exports.PersonaDashboard = PersonaDashboard;
|
|
62096
62738
|
exports.PivotTable = PivotTable;
|
|
62097
62739
|
exports.Popover = Popover;
|
|
62098
62740
|
exports.PriorityAlertBanner = PriorityAlertBanner;
|
|
62741
|
+
exports.ProcessHealthBar = ProcessHealthBar;
|
|
62742
|
+
exports.ProcessIndicator = ProcessIndicator;
|
|
62099
62743
|
exports.Progress = Progress;
|
|
62100
62744
|
exports.ProgressCelebration = ProgressCelebration;
|
|
62101
62745
|
exports.PullToRefresh = PullToRefresh;
|
|
@@ -62103,7 +62747,9 @@ exports.QueryTransparency = QueryTransparency;
|
|
|
62103
62747
|
exports.RadioGroup = RadioGroup;
|
|
62104
62748
|
exports.Rating = Rating;
|
|
62105
62749
|
exports.Responsive = Responsive;
|
|
62750
|
+
exports.ReviewDecisionCard = ReviewDecisionCard;
|
|
62106
62751
|
exports.RichTextEditor = RichTextEditor;
|
|
62752
|
+
exports.SLAIndicator = SLAIndicator;
|
|
62107
62753
|
exports.SearchBar = SearchBar;
|
|
62108
62754
|
exports.SearchableList = SearchableList;
|
|
62109
62755
|
exports.Select = Select;
|
|
@@ -62117,6 +62763,7 @@ exports.SkeletonCard = SkeletonCard$1;
|
|
|
62117
62763
|
exports.SkeletonTable = SkeletonTable;
|
|
62118
62764
|
exports.SkipLink = SkipLink;
|
|
62119
62765
|
exports.Slider = Slider;
|
|
62766
|
+
exports.SplitPane = SplitPane;
|
|
62120
62767
|
exports.Spreadsheet = Spreadsheet;
|
|
62121
62768
|
exports.SpreadsheetReport = SpreadsheetReport;
|
|
62122
62769
|
exports.Stack = Stack;
|
|
@@ -62135,6 +62782,7 @@ exports.SwipeActions = SwipeActions;
|
|
|
62135
62782
|
exports.SwipeableCard = SwipeableCard;
|
|
62136
62783
|
exports.SwipeableListItem = SwipeableListItem;
|
|
62137
62784
|
exports.Switch = Switch;
|
|
62785
|
+
exports.SystemActionEntry = SystemActionEntry;
|
|
62138
62786
|
exports.Tabs = Tabs;
|
|
62139
62787
|
exports.TabsContent = TabsContent;
|
|
62140
62788
|
exports.TabsList = TabsList;
|
|
@@ -62153,6 +62801,7 @@ exports.Transfer = Transfer;
|
|
|
62153
62801
|
exports.TreeView = TreeView;
|
|
62154
62802
|
exports.TwoColumnContent = TwoColumnContent;
|
|
62155
62803
|
exports.UserProfileButton = UserProfileButton;
|
|
62804
|
+
exports.VarianceDisplay = VarianceDisplay;
|
|
62156
62805
|
exports.addErrorMessage = addErrorMessage;
|
|
62157
62806
|
exports.addInfoMessage = addInfoMessage;
|
|
62158
62807
|
exports.addSuccessMessage = addSuccessMessage;
|