@pablo2410/shared-ui 0.18.1 → 0.19.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/README.md +18 -15
- package/dist/{HealthFooter-C5K9s38i.d.ts → HealthFooter-BoOozbWG.d.ts} +4 -4
- package/dist/{chunk-G7XJLTNY.js → chunk-5RY3AJKI.js} +8 -9
- package/dist/{chunk-G7XJLTNY.js.map → chunk-5RY3AJKI.js.map} +1 -1
- package/dist/{chunk-3G43UG63.js → chunk-A6UTXAPS.js} +11 -3
- package/dist/chunk-A6UTXAPS.js.map +1 -0
- package/dist/{chunk-R4NOLCSI.js → chunk-BKGUIIN2.js} +1 -1
- package/dist/{chunk-R4NOLCSI.js.map → chunk-BKGUIIN2.js.map} +1 -1
- package/dist/{chunk-IEBZGU6X.js → chunk-DMUQ5WNO.js} +2 -4
- package/dist/chunk-DMUQ5WNO.js.map +1 -0
- package/dist/{chunk-PLCWXXUE.js → chunk-K6FHU4HN.js} +9 -15
- package/dist/chunk-K6FHU4HN.js.map +1 -0
- package/dist/{chunk-KXUNOSMZ.js → chunk-NLQ45OYS.js} +193 -91
- package/dist/chunk-NLQ45OYS.js.map +1 -0
- package/dist/{chunk-WTR6SNOE.js → chunk-VJEXXX2P.js} +158 -40
- package/dist/chunk-VJEXXX2P.js.map +1 -0
- package/dist/components/index.d.ts +7 -8
- package/dist/components/index.js +85 -63
- package/dist/components/index.js.map +1 -1
- package/dist/hierarchy/core.js +1 -1
- package/dist/hierarchy/index.d.ts +3 -3
- package/dist/hierarchy/index.js +5 -5
- package/dist/insights/index.d.ts +8 -8
- package/dist/insights/index.js +150 -61
- package/dist/insights/index.js.map +1 -1
- package/dist/layout/index.d.ts +8 -8
- package/dist/layout/index.js +6 -6
- package/dist/primitives/index.d.ts +288 -289
- package/dist/primitives/index.js +2 -2
- package/dist/rbac/index.js.map +1 -1
- package/dist/reporting/index.d.ts +101 -43
- package/dist/reporting/index.js +208 -187
- package/dist/reporting/index.js.map +1 -1
- package/dist/services/index.js +2 -2
- package/dist/shell/index.d.ts +2 -3
- package/dist/shell/index.js +7 -7
- package/dist/shell/oplytics-shell.css +2 -2
- package/dist/theme/oplytics-theme.css +4 -4
- package/package.json +48 -46
- package/dist/chunk-3G43UG63.js.map +0 -1
- package/dist/chunk-IEBZGU6X.js.map +0 -1
- package/dist/chunk-KXUNOSMZ.js.map +0 -1
- package/dist/chunk-PLCWXXUE.js.map +0 -1
- package/dist/chunk-WTR6SNOE.js.map +0 -1
package/dist/reporting/index.js
CHANGED
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
SelectItem,
|
|
13
13
|
SelectTrigger,
|
|
14
14
|
SelectValue,
|
|
15
|
+
Switch,
|
|
15
16
|
Textarea
|
|
16
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-K6FHU4HN.js";
|
|
17
18
|
import {
|
|
18
19
|
cn
|
|
19
20
|
} from "../chunk-JT3XLKKD.js";
|
|
@@ -26,10 +27,10 @@ import {
|
|
|
26
27
|
DialogHeader,
|
|
27
28
|
DialogTitle,
|
|
28
29
|
Label
|
|
29
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-BKGUIIN2.js";
|
|
30
31
|
|
|
31
32
|
// src/reporting/ReportingToolbar.tsx
|
|
32
|
-
import { useState } from "react";
|
|
33
|
+
import { useRef, useState } from "react";
|
|
33
34
|
import {
|
|
34
35
|
ShieldAlert,
|
|
35
36
|
Leaf,
|
|
@@ -38,6 +39,8 @@ import {
|
|
|
38
39
|
Lightbulb,
|
|
39
40
|
ChevronDown,
|
|
40
41
|
Send,
|
|
42
|
+
ImagePlus,
|
|
43
|
+
X,
|
|
41
44
|
UserCog
|
|
42
45
|
} from "lucide-react";
|
|
43
46
|
import { toast } from "sonner";
|
|
@@ -68,7 +71,7 @@ var ALL_REPORT_OPTIONS = [
|
|
|
68
71
|
var ALL_FEEDBACK_OPTIONS = [
|
|
69
72
|
{
|
|
70
73
|
category: "problem",
|
|
71
|
-
label: "Report Problem",
|
|
74
|
+
label: "Report a Problem",
|
|
72
75
|
description: "Something isn't working",
|
|
73
76
|
icon: Bug,
|
|
74
77
|
color: "#EF4444"
|
|
@@ -76,17 +79,11 @@ var ALL_FEEDBACK_OPTIONS = [
|
|
|
76
79
|
{
|
|
77
80
|
category: "suggestion",
|
|
78
81
|
label: "Suggestion",
|
|
79
|
-
description: "
|
|
82
|
+
description: "An idea for improvement",
|
|
80
83
|
icon: Lightbulb,
|
|
81
84
|
color: "#8C34E9"
|
|
82
85
|
}
|
|
83
86
|
];
|
|
84
|
-
var SEVERITY_OPTIONS = [
|
|
85
|
-
{ value: "critical", label: "Critical", color: "#EF4444" },
|
|
86
|
-
{ value: "high", label: "High", color: "#F59E0B" },
|
|
87
|
-
{ value: "medium", label: "Medium", color: "#3b82f6" },
|
|
88
|
-
{ value: "low", label: "Low", color: "#22C55E" }
|
|
89
|
-
];
|
|
90
87
|
function ReportingToolbar({
|
|
91
88
|
moduleName = "Oplytics",
|
|
92
89
|
showIncidentReporting = true,
|
|
@@ -95,7 +92,12 @@ function ReportingToolbar({
|
|
|
95
92
|
feedbackCategories = ["problem", "suggestion"],
|
|
96
93
|
onReportSubmit,
|
|
97
94
|
onFeedbackSubmit,
|
|
98
|
-
|
|
95
|
+
hierarchyContext,
|
|
96
|
+
currentUser,
|
|
97
|
+
services = OPLYTICS_SERVICES,
|
|
98
|
+
defaultServiceSlug,
|
|
99
|
+
enableScreenshot = true,
|
|
100
|
+
reportsComingSoon = true,
|
|
99
101
|
className
|
|
100
102
|
}) {
|
|
101
103
|
const reportOptions = ALL_REPORT_OPTIONS.filter(
|
|
@@ -104,91 +106,82 @@ function ReportingToolbar({
|
|
|
104
106
|
const feedbackOptions = ALL_FEEDBACK_OPTIONS.filter(
|
|
105
107
|
(opt) => feedbackCategories.includes(opt.category)
|
|
106
108
|
);
|
|
107
|
-
const [
|
|
108
|
-
const [
|
|
109
|
-
const [
|
|
110
|
-
const [
|
|
111
|
-
const [
|
|
112
|
-
const [
|
|
113
|
-
const [
|
|
114
|
-
const [
|
|
115
|
-
const [
|
|
116
|
-
const [feedbackDescription, setFeedbackDescription] = useState("");
|
|
109
|
+
const firstServiceSlug = defaultServiceSlug ?? services[0]?.slug ?? "portal";
|
|
110
|
+
const [feedbackOpen, setFeedbackOpen] = useState(false);
|
|
111
|
+
const [category, setCategory] = useState("problem");
|
|
112
|
+
const [serviceSlug, setServiceSlug] = useState(firstServiceSlug);
|
|
113
|
+
const [isBlocking, setIsBlocking] = useState(false);
|
|
114
|
+
const [summary, setSummary] = useState("");
|
|
115
|
+
const [details, setDetails] = useState("");
|
|
116
|
+
const [screenshot, setScreenshot] = useState(null);
|
|
117
|
+
const [screenshotName, setScreenshotName] = useState(null);
|
|
117
118
|
const [submitting, setSubmitting] = useState(false);
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
setFeedbackSubject("");
|
|
129
|
-
setFeedbackDescription("");
|
|
130
|
-
setFeedbackDialogOpen(true);
|
|
119
|
+
const fileInputRef = useRef(null);
|
|
120
|
+
const openFeedback = (c) => {
|
|
121
|
+
setCategory(c);
|
|
122
|
+
setServiceSlug(firstServiceSlug);
|
|
123
|
+
setIsBlocking(false);
|
|
124
|
+
setSummary("");
|
|
125
|
+
setDetails("");
|
|
126
|
+
setScreenshot(null);
|
|
127
|
+
setScreenshotName(null);
|
|
128
|
+
setFeedbackOpen(true);
|
|
131
129
|
};
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
const handlePickFile = async (e) => {
|
|
131
|
+
const file = e.target.files?.[0];
|
|
132
|
+
e.target.value = "";
|
|
133
|
+
if (!file) return;
|
|
134
|
+
const check = isAcceptableScreenshot(file);
|
|
135
|
+
if (!check.ok) {
|
|
136
|
+
toast.error(check.reason);
|
|
135
137
|
return;
|
|
136
138
|
}
|
|
137
|
-
setSubmitting(true);
|
|
138
139
|
try {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
location: reportLocation || void 0,
|
|
143
|
-
severity: reportSeverity,
|
|
144
|
-
immediateAction: reportImmediateAction || void 0,
|
|
145
|
-
moduleName,
|
|
146
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
147
|
-
};
|
|
148
|
-
await onReportSubmit(report);
|
|
149
|
-
toast.success("Report submitted successfully", {
|
|
150
|
-
description: selectedReportCategory === "stop-work" ? "Stop Work authority raised \u2014 management has been notified" : "Your report has been logged and assigned for review"
|
|
151
|
-
});
|
|
152
|
-
setReportDialogOpen(false);
|
|
140
|
+
const shot = await readFileAsScreenshot(file);
|
|
141
|
+
setScreenshot(shot);
|
|
142
|
+
setScreenshotName(file.name);
|
|
153
143
|
} catch (err) {
|
|
154
|
-
console.error("[ReportingToolbar]
|
|
155
|
-
toast.error("
|
|
156
|
-
} finally {
|
|
157
|
-
setSubmitting(false);
|
|
144
|
+
console.error("[ReportingToolbar] screenshot read failed:", err);
|
|
145
|
+
toast.error("Could not read that image.");
|
|
158
146
|
}
|
|
159
147
|
};
|
|
160
|
-
const
|
|
161
|
-
if (!
|
|
162
|
-
toast.error("Please
|
|
148
|
+
const submitFeedback = async () => {
|
|
149
|
+
if (!details.trim()) {
|
|
150
|
+
toast.error("Please describe the problem or idea.");
|
|
163
151
|
return;
|
|
164
152
|
}
|
|
165
153
|
setSubmitting(true);
|
|
166
154
|
try {
|
|
167
155
|
const feedback = {
|
|
168
|
-
category
|
|
169
|
-
|
|
170
|
-
|
|
156
|
+
category,
|
|
157
|
+
serviceSlug,
|
|
158
|
+
summary: summary.trim() || void 0,
|
|
159
|
+
details: details.trim(),
|
|
160
|
+
isBlocking,
|
|
171
161
|
moduleName,
|
|
172
162
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
173
|
-
pageContext: typeof window !== "undefined" ? window.location.pathname : void 0
|
|
163
|
+
pageContext: typeof window !== "undefined" ? window.location.pathname : void 0,
|
|
164
|
+
submittedBy: currentUser,
|
|
165
|
+
screenshot: screenshot ?? void 0
|
|
174
166
|
};
|
|
175
167
|
await onFeedbackSubmit(feedback);
|
|
176
168
|
toast.success(
|
|
177
|
-
|
|
169
|
+
category === "problem" ? "Thanks \u2014 we've logged it. You'll get a confirmation email." : "Thanks for the suggestion \u2014 you'll get a confirmation email."
|
|
178
170
|
);
|
|
179
|
-
|
|
171
|
+
setFeedbackOpen(false);
|
|
180
172
|
} catch (err) {
|
|
181
173
|
console.error("[ReportingToolbar] feedback submit failed:", err);
|
|
182
|
-
toast.error("
|
|
174
|
+
toast.error("Couldn't submit that. Please try again.");
|
|
183
175
|
} finally {
|
|
184
176
|
setSubmitting(false);
|
|
185
177
|
}
|
|
186
178
|
};
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
);
|
|
179
|
+
const showReportGroup = showIncidentReporting && reportOptions.length > 0;
|
|
180
|
+
const showFeedbackGroup = showFeedback && feedbackOptions.length > 0;
|
|
181
|
+
if (!showReportGroup && !showFeedbackGroup) return null;
|
|
182
|
+
void hierarchyContext;
|
|
190
183
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
191
|
-
/* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), children:
|
|
184
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
192
185
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
193
186
|
Button,
|
|
194
187
|
{
|
|
@@ -202,16 +195,37 @@ function ReportingToolbar({
|
|
|
202
195
|
]
|
|
203
196
|
}
|
|
204
197
|
) }),
|
|
205
|
-
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-
|
|
206
|
-
|
|
207
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-60", children: [
|
|
199
|
+
showReportGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
200
|
+
/* @__PURE__ */ jsxs(DropdownMenuLabel, { className: "flex items-center gap-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: [
|
|
201
|
+
"Report",
|
|
202
|
+
reportsComingSoon && /* @__PURE__ */ jsx(
|
|
203
|
+
Badge,
|
|
204
|
+
{
|
|
205
|
+
variant: "outline",
|
|
206
|
+
className: "border-[#8C34E9]/40 text-[9px] font-normal text-[#C084FC]",
|
|
207
|
+
children: "Coming soon"
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] }),
|
|
208
211
|
reportOptions.map((opt) => /* @__PURE__ */ jsxs(
|
|
209
212
|
DropdownMenuItem,
|
|
210
213
|
{
|
|
211
|
-
|
|
214
|
+
disabled: reportsComingSoon,
|
|
215
|
+
onClick: () => {
|
|
216
|
+
if (!reportsComingSoon) {
|
|
217
|
+
void onReportSubmit;
|
|
218
|
+
}
|
|
219
|
+
},
|
|
212
220
|
className: "gap-3 py-2.5",
|
|
213
221
|
children: [
|
|
214
|
-
/* @__PURE__ */ jsx(
|
|
222
|
+
/* @__PURE__ */ jsx(
|
|
223
|
+
opt.icon,
|
|
224
|
+
{
|
|
225
|
+
className: "h-4 w-4",
|
|
226
|
+
style: { color: opt.color }
|
|
227
|
+
}
|
|
228
|
+
),
|
|
215
229
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
216
230
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: opt.label }),
|
|
217
231
|
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground", children: opt.description })
|
|
@@ -221,16 +235,22 @@ function ReportingToolbar({
|
|
|
221
235
|
opt.category
|
|
222
236
|
))
|
|
223
237
|
] }),
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
showReportGroup && showFeedbackGroup && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
239
|
+
showFeedbackGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
226
240
|
/* @__PURE__ */ jsx(DropdownMenuLabel, { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "Feedback" }),
|
|
227
241
|
feedbackOptions.map((opt) => /* @__PURE__ */ jsxs(
|
|
228
242
|
DropdownMenuItem,
|
|
229
243
|
{
|
|
230
|
-
onClick: () =>
|
|
244
|
+
onClick: () => openFeedback(opt.category),
|
|
231
245
|
className: "gap-3 py-2.5",
|
|
232
246
|
children: [
|
|
233
|
-
/* @__PURE__ */ jsx(
|
|
247
|
+
/* @__PURE__ */ jsx(
|
|
248
|
+
opt.icon,
|
|
249
|
+
{
|
|
250
|
+
className: "h-4 w-4",
|
|
251
|
+
style: { color: opt.color }
|
|
252
|
+
}
|
|
253
|
+
),
|
|
234
254
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
235
255
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: opt.label }),
|
|
236
256
|
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground", children: opt.description })
|
|
@@ -241,154 +261,117 @@ function ReportingToolbar({
|
|
|
241
261
|
))
|
|
242
262
|
] })
|
|
243
263
|
] })
|
|
244
|
-
] })
|
|
245
|
-
/* @__PURE__ */ jsx(Dialog, { open:
|
|
264
|
+
] }) }),
|
|
265
|
+
/* @__PURE__ */ jsx(Dialog, { open: feedbackOpen, onOpenChange: setFeedbackOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[520px]", children: [
|
|
246
266
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
247
267
|
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
selectedReportCategory === "stop-work" && /* @__PURE__ */ jsx(Badge, { className: "bg-[#F59E0B] text-white text-[9px] border-0", children: "URGENT" })
|
|
268
|
+
category === "problem" ? /* @__PURE__ */ jsx(Bug, { className: "h-5 w-5 text-[#EF4444]" }) : /* @__PURE__ */ jsx(Lightbulb, { className: "h-5 w-5 text-[#8C34E9]" }),
|
|
269
|
+
category === "problem" ? "Report a Problem" : "Share a Suggestion"
|
|
251
270
|
] }),
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
reportConfig?.description,
|
|
254
|
-
". All reports are logged and tracked."
|
|
255
|
-
] })
|
|
271
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: category === "problem" ? "Tell us what went wrong. We triage within 24 hours." : "We review every suggestion and schedule improvements against the roadmap." })
|
|
256
272
|
] }),
|
|
257
273
|
/* @__PURE__ */ jsxs("div", { className: "space-y-4 py-2", children: [
|
|
258
274
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
259
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "
|
|
260
|
-
/* @__PURE__ */ jsxs(
|
|
261
|
-
|
|
262
|
-
{
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
className: "h-2 w-2 rounded-full",
|
|
272
|
-
style: { backgroundColor: s.color }
|
|
273
|
-
}
|
|
274
|
-
),
|
|
275
|
-
s.label
|
|
276
|
-
] }) }, s.value)) })
|
|
277
|
-
]
|
|
278
|
-
}
|
|
279
|
-
)
|
|
275
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Which service?" }),
|
|
276
|
+
/* @__PURE__ */ jsxs(Select, { value: serviceSlug, onValueChange: setServiceSlug, children: [
|
|
277
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-9", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
278
|
+
/* @__PURE__ */ jsx(SelectContent, { children: services.map((s) => /* @__PURE__ */ jsx(SelectItem, { value: s.slug, children: s.label }, s.slug)) })
|
|
279
|
+
] })
|
|
280
|
+
] }),
|
|
281
|
+
category === "problem" && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-md border border-[#1E2738] px-3 py-2", children: [
|
|
282
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
283
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Is this blocking you?" }),
|
|
284
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground", children: "Blocking issues are treated as high priority." })
|
|
285
|
+
] }),
|
|
286
|
+
/* @__PURE__ */ jsx(Switch, { checked: isBlocking, onCheckedChange: setIsBlocking })
|
|
280
287
|
] }),
|
|
281
288
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
282
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "
|
|
289
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Summary" }),
|
|
283
290
|
/* @__PURE__ */ jsx(
|
|
284
291
|
Input,
|
|
285
292
|
{
|
|
286
|
-
value:
|
|
287
|
-
onChange: (e) =>
|
|
288
|
-
placeholder: "
|
|
293
|
+
value: summary,
|
|
294
|
+
onChange: (e) => setSummary(e.target.value),
|
|
295
|
+
placeholder: category === "problem" ? "Brief summary of the issue" : "Brief summary of your idea",
|
|
289
296
|
className: "h-9"
|
|
290
297
|
}
|
|
291
298
|
)
|
|
292
299
|
] }),
|
|
293
300
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
294
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "
|
|
301
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Details *" }),
|
|
295
302
|
/* @__PURE__ */ jsx(
|
|
296
303
|
Textarea,
|
|
297
304
|
{
|
|
298
|
-
value:
|
|
299
|
-
onChange: (e) =>
|
|
300
|
-
placeholder: "
|
|
301
|
-
rows:
|
|
305
|
+
value: details,
|
|
306
|
+
onChange: (e) => setDetails(e.target.value),
|
|
307
|
+
placeholder: category === "problem" ? "What were you trying to do? What happened instead?" : "Describe your suggestion and how it would help\u2026",
|
|
308
|
+
rows: 5
|
|
302
309
|
}
|
|
303
310
|
)
|
|
304
311
|
] }),
|
|
305
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
306
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "
|
|
312
|
+
enableScreenshot && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
313
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Screenshot (optional)" }),
|
|
307
314
|
/* @__PURE__ */ jsx(
|
|
308
|
-
|
|
315
|
+
"input",
|
|
309
316
|
{
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
317
|
+
ref: fileInputRef,
|
|
318
|
+
type: "file",
|
|
319
|
+
accept: "image/*",
|
|
320
|
+
className: "hidden",
|
|
321
|
+
onChange: handlePickFile
|
|
314
322
|
}
|
|
315
|
-
)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
)
|
|
336
|
-
] })
|
|
337
|
-
] }) }),
|
|
338
|
-
/* @__PURE__ */ jsx(Dialog, { open: feedbackDialogOpen, onOpenChange: setFeedbackDialogOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [
|
|
339
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
340
|
-
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
341
|
-
selectedFeedbackCategory === "problem" ? /* @__PURE__ */ jsx(Bug, { className: "h-5 w-5 text-[#EF4444]" }) : /* @__PURE__ */ jsx(Lightbulb, { className: "h-5 w-5 text-[#8C34E9]" }),
|
|
342
|
-
selectedFeedbackCategory === "problem" ? "Report a Problem" : "Submit a Suggestion"
|
|
343
|
-
] }),
|
|
344
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: selectedFeedbackCategory === "problem" ? "Help us fix issues \u2014 describe what went wrong." : "We'd love to hear your ideas for improving Oplytics." })
|
|
345
|
-
] }),
|
|
346
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-4 py-2", children: [
|
|
347
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
348
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Subject" }),
|
|
349
|
-
/* @__PURE__ */ jsx(
|
|
350
|
-
Input,
|
|
351
|
-
{
|
|
352
|
-
value: feedbackSubject,
|
|
353
|
-
onChange: (e) => setFeedbackSubject(e.target.value),
|
|
354
|
-
placeholder: selectedFeedbackCategory === "problem" ? "Brief summary of the issue" : "Brief summary of your idea",
|
|
355
|
-
className: "h-9"
|
|
356
|
-
}
|
|
357
|
-
)
|
|
358
|
-
] }),
|
|
359
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
360
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium", children: "Description *" }),
|
|
361
|
-
/* @__PURE__ */ jsx(
|
|
362
|
-
Textarea,
|
|
323
|
+
),
|
|
324
|
+
screenshot ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border border-[#1E2738] px-3 py-2", children: [
|
|
325
|
+
/* @__PURE__ */ jsx(ImagePlus, { className: "h-4 w-4 text-[#8C34E9]" }),
|
|
326
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-xs text-[#E2E8F0]", children: screenshotName ?? "screenshot" }),
|
|
327
|
+
/* @__PURE__ */ jsx(
|
|
328
|
+
"button",
|
|
329
|
+
{
|
|
330
|
+
type: "button",
|
|
331
|
+
onClick: () => {
|
|
332
|
+
setScreenshot(null);
|
|
333
|
+
setScreenshotName(null);
|
|
334
|
+
},
|
|
335
|
+
className: "text-muted-foreground hover:text-[#E2E8F0]",
|
|
336
|
+
"aria-label": "Remove screenshot",
|
|
337
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
338
|
+
}
|
|
339
|
+
)
|
|
340
|
+
] }) : /* @__PURE__ */ jsxs(
|
|
341
|
+
Button,
|
|
363
342
|
{
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
343
|
+
type: "button",
|
|
344
|
+
variant: "outline",
|
|
345
|
+
size: "sm",
|
|
346
|
+
className: "h-9 gap-1.5",
|
|
347
|
+
onClick: () => fileInputRef.current?.click(),
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsx(ImagePlus, { className: "h-3.5 w-3.5" }),
|
|
350
|
+
"Attach an image"
|
|
351
|
+
]
|
|
368
352
|
}
|
|
369
353
|
)
|
|
370
354
|
] }),
|
|
371
|
-
/* @__PURE__ */ jsxs("
|
|
372
|
-
"Module: ",
|
|
355
|
+
/* @__PURE__ */ jsxs("p", { className: "text-[10px] text-muted-foreground", children: [
|
|
373
356
|
moduleName,
|
|
374
|
-
" \
|
|
357
|
+
" \xB7 you'll get a confirmation email once this is logged."
|
|
375
358
|
] })
|
|
376
359
|
] }),
|
|
377
360
|
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
378
|
-
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () =>
|
|
361
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setFeedbackOpen(false), children: "Cancel" }),
|
|
379
362
|
/* @__PURE__ */ jsxs(
|
|
380
363
|
Button,
|
|
381
364
|
{
|
|
382
|
-
onClick:
|
|
383
|
-
disabled: submitting || !
|
|
365
|
+
onClick: submitFeedback,
|
|
366
|
+
disabled: submitting || !details.trim(),
|
|
384
367
|
className: "gap-2",
|
|
385
368
|
style: {
|
|
386
|
-
backgroundColor:
|
|
369
|
+
backgroundColor: category === "problem" ? "#EF4444" : "#8C34E9",
|
|
387
370
|
color: "white"
|
|
388
371
|
},
|
|
389
372
|
children: [
|
|
390
373
|
/* @__PURE__ */ jsx(Send, { className: "h-3.5 w-3.5" }),
|
|
391
|
-
submitting ? "Submitting
|
|
374
|
+
submitting ? "Submitting\u2026" : "Submit"
|
|
392
375
|
]
|
|
393
376
|
}
|
|
394
377
|
)
|
|
@@ -398,6 +381,14 @@ function ReportingToolbar({
|
|
|
398
381
|
}
|
|
399
382
|
|
|
400
383
|
// src/reporting/index.ts
|
|
384
|
+
var OPLYTICS_SERVICES = [
|
|
385
|
+
{ slug: "sqdcp", label: "SQDCP" },
|
|
386
|
+
{ slug: "oee-manager", label: "OEE Manager" },
|
|
387
|
+
{ slug: "action-manager", label: "Action Manager" },
|
|
388
|
+
{ slug: "policy-deployment", label: "Policy Deployment" },
|
|
389
|
+
{ slug: "connect", label: "Connect" },
|
|
390
|
+
{ slug: "portal", label: "Portal" }
|
|
391
|
+
];
|
|
401
392
|
var REPORT_BUTTONS = [
|
|
402
393
|
{
|
|
403
394
|
category: "safety",
|
|
@@ -447,10 +438,40 @@ function createReportingConfig(moduleName, handlers) {
|
|
|
447
438
|
...handlers
|
|
448
439
|
};
|
|
449
440
|
}
|
|
441
|
+
var FEEDBACK_SCREENSHOT_MAX_BYTES = 300 * 1024;
|
|
442
|
+
function isAcceptableScreenshot(file, maxBytes = FEEDBACK_SCREENSHOT_MAX_BYTES) {
|
|
443
|
+
if (!file.type.startsWith("image/")) {
|
|
444
|
+
return { ok: false, reason: "Please choose an image file." };
|
|
445
|
+
}
|
|
446
|
+
if (file.size > maxBytes) {
|
|
447
|
+
return {
|
|
448
|
+
ok: false,
|
|
449
|
+
reason: `Image is too large (max ${Math.round(maxBytes / 1024)} KB).`
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
return { ok: true };
|
|
453
|
+
}
|
|
454
|
+
function readFileAsScreenshot(file) {
|
|
455
|
+
return new Promise((resolve, reject) => {
|
|
456
|
+
const reader = new FileReader();
|
|
457
|
+
reader.onerror = () => reject(new Error("Could not read the file."));
|
|
458
|
+
reader.onload = () => {
|
|
459
|
+
const result = String(reader.result || "");
|
|
460
|
+
const comma = result.indexOf(",");
|
|
461
|
+
const dataBase64 = comma >= 0 ? result.slice(comma + 1) : result;
|
|
462
|
+
resolve({ dataBase64, mime: file.type || "image/png" });
|
|
463
|
+
};
|
|
464
|
+
reader.readAsDataURL(file);
|
|
465
|
+
});
|
|
466
|
+
}
|
|
450
467
|
export {
|
|
451
468
|
FEEDBACK_BUTTONS,
|
|
469
|
+
FEEDBACK_SCREENSHOT_MAX_BYTES,
|
|
470
|
+
OPLYTICS_SERVICES,
|
|
452
471
|
REPORT_BUTTONS,
|
|
453
472
|
ReportingToolbar,
|
|
454
|
-
createReportingConfig
|
|
473
|
+
createReportingConfig,
|
|
474
|
+
isAcceptableScreenshot,
|
|
475
|
+
readFileAsScreenshot
|
|
455
476
|
};
|
|
456
477
|
//# sourceMappingURL=index.js.map
|