@flamingo-stack/openframe-frontend-core 0.0.536 → 0.0.537-1788.4718.1
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/{chunk-FFJL6FEB.js → chunk-3GXMS4OP.js} +2 -2
- package/dist/{chunk-LUZPF7NX.js → chunk-5JPSQOZQ.js} +2 -2
- package/dist/{chunk-6SV4XZMD.js → chunk-7EHGP4QK.js} +843 -720
- package/dist/chunk-7EHGP4QK.js.map +1 -0
- package/dist/{chunk-IOXNHTGX.js → chunk-7FXZHI5D.js} +2 -2
- package/dist/{chunk-ZZDRBFEV.cjs → chunk-7WNJ7RFO.cjs} +14 -14
- package/dist/{chunk-ZZDRBFEV.cjs.map → chunk-7WNJ7RFO.cjs.map} +1 -1
- package/dist/{chunk-AECHSFLC.js → chunk-C4LEH3VE.js} +2 -2
- package/dist/{chunk-NCUZ64LM.cjs → chunk-CATY4DVR.cjs} +87 -87
- package/dist/{chunk-NCUZ64LM.cjs.map → chunk-CATY4DVR.cjs.map} +1 -1
- package/dist/{chunk-BHB7F4EN.js → chunk-CQQXB25K.js} +2 -2
- package/dist/{chunk-QAMRW5TG.js → chunk-CZHCXCWL.js} +2 -2
- package/dist/{chunk-L73PC7MW.cjs → chunk-DHSVBGOX.cjs} +9 -9
- package/dist/{chunk-L73PC7MW.cjs.map → chunk-DHSVBGOX.cjs.map} +1 -1
- package/dist/{chunk-MM5C6NID.js → chunk-HRC56BQW.js} +5 -5
- package/dist/{chunk-PA5NMP6K.cjs → chunk-KKZ2QMQD.cjs} +26 -26
- package/dist/{chunk-PA5NMP6K.cjs.map → chunk-KKZ2QMQD.cjs.map} +1 -1
- package/dist/{chunk-X6UHNN3E.js → chunk-LFMIAPBP.js} +2 -2
- package/dist/{chunk-3XSSW3IZ.cjs → chunk-MDP3YKFI.cjs} +5 -5
- package/dist/{chunk-3XSSW3IZ.cjs.map → chunk-MDP3YKFI.cjs.map} +1 -1
- package/dist/{chunk-ONWQ52QG.js → chunk-MOIHWYSA.js} +2 -2
- package/dist/{chunk-C257223X.cjs → chunk-OYTM3YXO.cjs} +7 -7
- package/dist/{chunk-C257223X.cjs.map → chunk-OYTM3YXO.cjs.map} +1 -1
- package/dist/{chunk-MTLFROMV.cjs → chunk-QPPG3KHW.cjs} +3 -3
- package/dist/{chunk-MTLFROMV.cjs.map → chunk-QPPG3KHW.cjs.map} +1 -1
- package/dist/{chunk-2PJ442HY.js → chunk-SGNWSUL3.js} +6 -6
- package/dist/{chunk-32SKUKQO.cjs → chunk-SKIM263K.cjs} +37 -37
- package/dist/{chunk-32SKUKQO.cjs.map → chunk-SKIM263K.cjs.map} +1 -1
- package/dist/{chunk-BEZFZ2CS.js → chunk-TCSSYTDN.js} +4 -4
- package/dist/{chunk-EEOLXN4D.cjs → chunk-V4D5MPB7.cjs} +4 -4
- package/dist/{chunk-EEOLXN4D.cjs.map → chunk-V4D5MPB7.cjs.map} +1 -1
- package/dist/{chunk-3ROYMRZE.cjs → chunk-VSIHO7DJ.cjs} +61 -61
- package/dist/{chunk-3ROYMRZE.cjs.map → chunk-VSIHO7DJ.cjs.map} +1 -1
- package/dist/{chunk-NEV7TKMB.js → chunk-WHUEUACV.js} +2 -2
- package/dist/{chunk-SL2GDMZR.cjs → chunk-WJIBB3KT.cjs} +31 -31
- package/dist/{chunk-SL2GDMZR.cjs.map → chunk-WJIBB3KT.cjs.map} +1 -1
- package/dist/{chunk-FIPHDAD2.cjs → chunk-YEKXTTAC.cjs} +26 -26
- package/dist/{chunk-FIPHDAD2.cjs.map → chunk-YEKXTTAC.cjs.map} +1 -1
- package/dist/{chunk-GM72KRPS.js → chunk-YIDGB5KP.js} +4 -4
- package/dist/{chunk-TRLZV7WM.cjs → chunk-YMPRMZDD.cjs} +413 -290
- package/dist/{chunk-TRLZV7WM.cjs.map → chunk-YMPRMZDD.cjs.map} +1 -1
- package/dist/{chunk-4TO3WDKH.cjs → chunk-YPI3JIR6.cjs} +11 -11
- package/dist/{chunk-4TO3WDKH.cjs.map → chunk-YPI3JIR6.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +134 -132
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +13 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/assignee-dropdown.d.ts +6 -0
- package/dist/components/ui/assignee-dropdown.d.ts.map +1 -1
- package/dist/components/ui/index.cjs +4 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +3 -1
- package/dist/components/ui/take-over-ticket-modal.d.ts +44 -0
- package/dist/components/ui/take-over-ticket-modal.d.ts.map +1 -0
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -1
- package/package.json +1 -1
- package/src/components/ui/assignee-dropdown.tsx +21 -0
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/take-over-ticket-modal.tsx +183 -0
- package/dist/chunk-6SV4XZMD.js.map +0 -1
- /package/dist/{chunk-FFJL6FEB.js.map → chunk-3GXMS4OP.js.map} +0 -0
- /package/dist/{chunk-LUZPF7NX.js.map → chunk-5JPSQOZQ.js.map} +0 -0
- /package/dist/{chunk-IOXNHTGX.js.map → chunk-7FXZHI5D.js.map} +0 -0
- /package/dist/{chunk-AECHSFLC.js.map → chunk-C4LEH3VE.js.map} +0 -0
- /package/dist/{chunk-BHB7F4EN.js.map → chunk-CQQXB25K.js.map} +0 -0
- /package/dist/{chunk-QAMRW5TG.js.map → chunk-CZHCXCWL.js.map} +0 -0
- /package/dist/{chunk-MM5C6NID.js.map → chunk-HRC56BQW.js.map} +0 -0
- /package/dist/{chunk-X6UHNN3E.js.map → chunk-LFMIAPBP.js.map} +0 -0
- /package/dist/{chunk-ONWQ52QG.js.map → chunk-MOIHWYSA.js.map} +0 -0
- /package/dist/{chunk-2PJ442HY.js.map → chunk-SGNWSUL3.js.map} +0 -0
- /package/dist/{chunk-BEZFZ2CS.js.map → chunk-TCSSYTDN.js.map} +0 -0
- /package/dist/{chunk-NEV7TKMB.js.map → chunk-WHUEUACV.js.map} +0 -0
- /package/dist/{chunk-GM72KRPS.js.map → chunk-YIDGB5KP.js.map} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { CheckIcon } from '../icons-v2-generated';
|
|
5
|
+
import { Autocomplete, type AutocompleteOption } from './autocomplete';
|
|
6
|
+
import { Button } from './button';
|
|
7
|
+
import { ColorSwatch } from './color-swatch';
|
|
8
|
+
import { ModalV2, ModalV2Footer, ModalV2Header, ModalV2Title } from './modal-v2';
|
|
9
|
+
import { SquareAvatar } from './square-avatar';
|
|
10
|
+
import { TruncateText } from './truncate-text';
|
|
11
|
+
|
|
12
|
+
export interface TakeOverStatusOption extends AutocompleteOption {
|
|
13
|
+
color: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TakeOverAssigneeOption extends AutocompleteOption {
|
|
17
|
+
/** Full (already resolved) avatar URL. */
|
|
18
|
+
imageUrl?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TakeOverTicketSelection {
|
|
22
|
+
statusId: string;
|
|
23
|
+
assigneeId: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TakeOverTicketModalProps {
|
|
27
|
+
isOpen: boolean;
|
|
28
|
+
onClose: () => void;
|
|
29
|
+
/** Highlighted ticket reference in the description, e.g. "1003: Email client synchronization issues". */
|
|
30
|
+
ticketRef: string;
|
|
31
|
+
/** Allowed target statuses, in display order (consumer decides grouping, e.g. custom statuses first). */
|
|
32
|
+
statusOptions: TakeOverStatusOption[];
|
|
33
|
+
/** Assignable users, in display order (consumer decides ordering, e.g. signed-in user first). */
|
|
34
|
+
assigneeOptions: TakeOverAssigneeOption[];
|
|
35
|
+
assigneesLoading?: boolean;
|
|
36
|
+
/** Pre-selected status; falls back to the first status option. */
|
|
37
|
+
initialStatusId?: string | null;
|
|
38
|
+
/** Pre-selected assignee; no fallback — pass the signed-in user id for the design default. */
|
|
39
|
+
initialAssigneeId?: string | null;
|
|
40
|
+
/** Confirm in-flight: buttons lock and the modal refuses to close. */
|
|
41
|
+
isPending?: boolean;
|
|
42
|
+
onConfirm: (selection: TakeOverTicketSelection) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function renderStatusOption(option: AutocompleteOption, isSelected: boolean): React.ReactNode {
|
|
46
|
+
const { label, color } = option as TakeOverStatusOption;
|
|
47
|
+
return (
|
|
48
|
+
<div className="flex items-center justify-between w-full min-w-0 gap-[var(--spacing-system-xs)]">
|
|
49
|
+
<div className="flex items-center gap-[var(--spacing-system-xs)] min-w-0">
|
|
50
|
+
<ColorSwatch color={color} />
|
|
51
|
+
<div className="min-w-0">
|
|
52
|
+
<TruncateText className="text-inherit">{label}</TruncateText>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
{isSelected && <CheckIcon className="text-ods-accent" size={20} />}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function renderAssigneeOption(option: AutocompleteOption, isSelected: boolean): React.ReactNode {
|
|
61
|
+
const { label, imageUrl } = option as TakeOverAssigneeOption;
|
|
62
|
+
return (
|
|
63
|
+
<div className="flex items-center justify-between w-full min-w-0 gap-[var(--spacing-system-xs)]">
|
|
64
|
+
<div className="flex items-center gap-[var(--spacing-system-xs)] min-w-0">
|
|
65
|
+
<SquareAvatar src={imageUrl} alt={label} fallback={label} size="sm" variant="round" />
|
|
66
|
+
<div className="min-w-0">
|
|
67
|
+
<TruncateText className="text-inherit">{label}</TruncateText>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
{isSelected && <CheckIcon className="text-ods-accent" size={20} />}
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Take Over Ticket confirmation dialog (Figma openframe---tickets 8482-112154 /
|
|
77
|
+
* 8482-112169): shown when a technician takes a ticket over from the AI
|
|
78
|
+
* assistant. Presentational — the consumer supplies the option lists, their
|
|
79
|
+
* ordering and default selections, and performs the actual take-over in
|
|
80
|
+
* `onConfirm` (status transition + assignment + switching the dialog to direct
|
|
81
|
+
* mode, or an atomic backend mutation once available).
|
|
82
|
+
*
|
|
83
|
+
* Desktop footer shows only the accent Take Over button (X closes); mobile
|
|
84
|
+
* bottom-sheet adds a Cancel button, per design.
|
|
85
|
+
*/
|
|
86
|
+
export function TakeOverTicketModal({
|
|
87
|
+
isOpen,
|
|
88
|
+
onClose,
|
|
89
|
+
ticketRef,
|
|
90
|
+
statusOptions,
|
|
91
|
+
assigneeOptions,
|
|
92
|
+
assigneesLoading,
|
|
93
|
+
initialStatusId,
|
|
94
|
+
initialAssigneeId,
|
|
95
|
+
isPending = false,
|
|
96
|
+
onConfirm,
|
|
97
|
+
}: TakeOverTicketModalProps) {
|
|
98
|
+
const [statusId, setStatusId] = React.useState<string | null>(null);
|
|
99
|
+
const [assigneeId, setAssigneeId] = React.useState<string | null>(null);
|
|
100
|
+
|
|
101
|
+
// Re-seed the selections every time the modal opens.
|
|
102
|
+
React.useEffect(() => {
|
|
103
|
+
if (!isOpen) return;
|
|
104
|
+
setStatusId(initialStatusId ?? null);
|
|
105
|
+
setAssigneeId(initialAssigneeId ?? null);
|
|
106
|
+
}, [isOpen, initialStatusId, initialAssigneeId]);
|
|
107
|
+
|
|
108
|
+
const selectedStatusId = statusId ?? statusOptions[0]?.value ?? null;
|
|
109
|
+
const selectedStatus = statusOptions.find(o => o.value === selectedStatusId);
|
|
110
|
+
const selectedAssignee = assigneeOptions.find(o => o.value === assigneeId);
|
|
111
|
+
|
|
112
|
+
const handleConfirm = () => {
|
|
113
|
+
if (!selectedStatusId || !assigneeId || isPending) return;
|
|
114
|
+
onConfirm({ statusId: selectedStatusId, assigneeId });
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<ModalV2 isOpen={isOpen} onClose={isPending ? () => {} : onClose} className="text-left md:max-w-[600px]">
|
|
119
|
+
<ModalV2Header>
|
|
120
|
+
<ModalV2Title>Take Over Ticket</ModalV2Title>
|
|
121
|
+
</ModalV2Header>
|
|
122
|
+
|
|
123
|
+
<p className="text-h4 text-ods-text-primary">
|
|
124
|
+
The ticket <span className="text-ods-accent">{ticketRef}</span> will move to the selected status and be assigned
|
|
125
|
+
to the technician. A direct chat with the user will start, and the AI assistant will stop working on this
|
|
126
|
+
ticket.
|
|
127
|
+
</p>
|
|
128
|
+
|
|
129
|
+
<div className="flex flex-col md:flex-row gap-[var(--spacing-system-l)] w-full">
|
|
130
|
+
<div className="flex-1 min-w-0">
|
|
131
|
+
<Autocomplete
|
|
132
|
+
label="Status"
|
|
133
|
+
options={statusOptions}
|
|
134
|
+
value={selectedStatusId}
|
|
135
|
+
onChange={setStatusId}
|
|
136
|
+
placeholder="Select Status"
|
|
137
|
+
startAdornment={selectedStatus ? <ColorSwatch color={selectedStatus.color} /> : undefined}
|
|
138
|
+
renderOption={renderStatusOption}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
<div className="flex-1 min-w-0">
|
|
142
|
+
<Autocomplete
|
|
143
|
+
label="Assigned"
|
|
144
|
+
options={assigneeOptions}
|
|
145
|
+
value={assigneeId}
|
|
146
|
+
onChange={setAssigneeId}
|
|
147
|
+
placeholder="Select Technician"
|
|
148
|
+
loading={assigneesLoading}
|
|
149
|
+
startAdornment={
|
|
150
|
+
selectedAssignee ? (
|
|
151
|
+
<SquareAvatar
|
|
152
|
+
src={selectedAssignee.imageUrl}
|
|
153
|
+
alt={selectedAssignee.label}
|
|
154
|
+
fallback={selectedAssignee.label}
|
|
155
|
+
size="sm"
|
|
156
|
+
variant="round"
|
|
157
|
+
/>
|
|
158
|
+
) : undefined
|
|
159
|
+
}
|
|
160
|
+
renderOption={renderAssigneeOption}
|
|
161
|
+
/>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<ModalV2Footer>
|
|
166
|
+
<Button type="button" variant="outline" onClick={onClose} disabled={isPending} className="flex-1 md:hidden">
|
|
167
|
+
Cancel
|
|
168
|
+
</Button>
|
|
169
|
+
<div className="hidden md:block flex-1" />
|
|
170
|
+
<Button
|
|
171
|
+
type="button"
|
|
172
|
+
variant="accent"
|
|
173
|
+
onClick={handleConfirm}
|
|
174
|
+
loading={isPending}
|
|
175
|
+
disabled={!selectedStatusId || !assigneeId}
|
|
176
|
+
className="flex-1"
|
|
177
|
+
>
|
|
178
|
+
Take Over
|
|
179
|
+
</Button>
|
|
180
|
+
</ModalV2Footer>
|
|
181
|
+
</ModalV2>
|
|
182
|
+
);
|
|
183
|
+
}
|