@uipath/apollo-react 7.2.1 → 7.3.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.
Files changed (73) hide show
  1. package/dist/canvas/components/Guardrails/__fixtures__/classifier-questions.fixtures.d.ts +3 -0
  2. package/dist/canvas/components/Guardrails/__fixtures__/classifier-questions.fixtures.d.ts.map +1 -0
  3. package/dist/canvas/components/Guardrails/__fixtures__/definitions-wire.fixtures.d.ts +2 -0
  4. package/dist/canvas/components/Guardrails/__fixtures__/definitions-wire.fixtures.d.ts.map +1 -1
  5. package/dist/canvas/components/Guardrails/__fixtures__/host-copy-baselines.d.ts.map +1 -1
  6. package/dist/canvas/components/Guardrails/classifier-custom-questions-editor.cjs +220 -0
  7. package/dist/canvas/components/Guardrails/classifier-custom-questions-editor.d.ts +13 -0
  8. package/dist/canvas/components/Guardrails/classifier-custom-questions-editor.d.ts.map +1 -0
  9. package/dist/canvas/components/Guardrails/classifier-custom-questions-editor.js +186 -0
  10. package/dist/canvas/components/Guardrails/classifier-question-picker.cjs +316 -0
  11. package/dist/canvas/components/Guardrails/classifier-question-picker.d.ts +15 -0
  12. package/dist/canvas/components/Guardrails/classifier-question-picker.d.ts.map +1 -0
  13. package/dist/canvas/components/Guardrails/classifier-question-picker.js +282 -0
  14. package/dist/canvas/components/Guardrails/classifier-utils.cjs +139 -0
  15. package/dist/canvas/components/Guardrails/classifier-utils.d.ts +25 -0
  16. package/dist/canvas/components/Guardrails/classifier-utils.d.ts.map +1 -0
  17. package/dist/canvas/components/Guardrails/classifier-utils.js +87 -0
  18. package/dist/canvas/components/Guardrails/components/classifier-threshold-slider.cjs +98 -0
  19. package/dist/canvas/components/Guardrails/components/classifier-threshold-slider.d.ts +9 -0
  20. package/dist/canvas/components/Guardrails/components/classifier-threshold-slider.d.ts.map +1 -0
  21. package/dist/canvas/components/Guardrails/components/classifier-threshold-slider.js +64 -0
  22. package/dist/canvas/components/Guardrails/components/parameter-label.d.ts +1 -1
  23. package/dist/canvas/components/Guardrails/components/parameter-label.d.ts.map +1 -1
  24. package/dist/canvas/components/Guardrails/definitions-copy.cjs +66 -1
  25. package/dist/canvas/components/Guardrails/definitions-copy.d.ts +1 -0
  26. package/dist/canvas/components/Guardrails/definitions-copy.d.ts.map +1 -1
  27. package/dist/canvas/components/Guardrails/definitions-copy.js +66 -1
  28. package/dist/canvas/components/Guardrails/definitions-parse.cjs +66 -1
  29. package/dist/canvas/components/Guardrails/definitions-parse.d.ts +11 -1
  30. package/dist/canvas/components/Guardrails/definitions-parse.d.ts.map +1 -1
  31. package/dist/canvas/components/Guardrails/definitions-parse.js +63 -1
  32. package/dist/canvas/components/Guardrails/definitions-wire.d.ts +11 -0
  33. package/dist/canvas/components/Guardrails/definitions-wire.d.ts.map +1 -1
  34. package/dist/canvas/components/Guardrails/guardrail-builder.cjs +12 -4
  35. package/dist/canvas/components/Guardrails/guardrail-builder.d.ts.map +1 -1
  36. package/dist/canvas/components/Guardrails/guardrail-builder.js +12 -4
  37. package/dist/canvas/components/Guardrails/guardrail-validator-form.cjs +4 -1
  38. package/dist/canvas/components/Guardrails/guardrail-validator-form.d.ts.map +1 -1
  39. package/dist/canvas/components/Guardrails/guardrail-validator-form.js +4 -1
  40. package/dist/canvas/components/Guardrails/i18n.cjs +181 -3
  41. package/dist/canvas/components/Guardrails/i18n.d.ts +39 -0
  42. package/dist/canvas/components/Guardrails/i18n.d.ts.map +1 -1
  43. package/dist/canvas/components/Guardrails/i18n.js +168 -2
  44. package/dist/canvas/components/Guardrails/index.cjs +54 -4
  45. package/dist/canvas/components/Guardrails/index.d.ts +14 -3
  46. package/dist/canvas/components/Guardrails/index.d.ts.map +1 -1
  47. package/dist/canvas/components/Guardrails/index.js +7 -2
  48. package/dist/canvas/components/Guardrails/use-classifier-guardrail-parameters.cjs +136 -0
  49. package/dist/canvas/components/Guardrails/use-classifier-guardrail-parameters.d.ts +18 -0
  50. package/dist/canvas/components/Guardrails/use-classifier-guardrail-parameters.d.ts.map +1 -0
  51. package/dist/canvas/components/Guardrails/use-classifier-guardrail-parameters.js +102 -0
  52. package/dist/canvas/components/Guardrails/use-classifier-questions.cjs +97 -0
  53. package/dist/canvas/components/Guardrails/use-classifier-questions.d.ts +34 -0
  54. package/dist/canvas/components/Guardrails/use-classifier-questions.d.ts.map +1 -0
  55. package/dist/canvas/components/Guardrails/use-classifier-questions.js +60 -0
  56. package/dist/canvas/components/Guardrails/use-guardrail-definitions.cjs +8 -81
  57. package/dist/canvas/components/Guardrails/use-guardrail-definitions.d.ts +2 -8
  58. package/dist/canvas/components/Guardrails/use-guardrail-definitions.d.ts.map +1 -1
  59. package/dist/canvas/components/Guardrails/use-guardrail-definitions.js +9 -82
  60. package/dist/canvas/components/Guardrails/use-guardrails-request.cjs +133 -0
  61. package/dist/canvas/components/Guardrails/use-guardrails-request.d.ts +23 -0
  62. package/dist/canvas/components/Guardrails/use-guardrails-request.d.ts.map +1 -0
  63. package/dist/canvas/components/Guardrails/use-guardrails-request.js +99 -0
  64. package/dist/canvas/components/Guardrails/utils.cjs +4 -2
  65. package/dist/canvas/components/Guardrails/utils.d.ts +4 -1
  66. package/dist/canvas/components/Guardrails/utils.d.ts.map +1 -1
  67. package/dist/canvas/components/Guardrails/utils.js +4 -2
  68. package/dist/canvas/locales/en.cjs +1 -1
  69. package/dist/canvas/locales/en.d.ts.map +1 -1
  70. package/dist/canvas/locales/en.js +1 -1
  71. package/dist/canvas/styles/tailwind.canvas.css +1 -1
  72. package/dist/chat/styles/tailwind.chat.css +1 -1
  73. package/package.json +2 -2
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ ClassifierQuestionPicker: ()=>ClassifierQuestionPicker
28
+ });
29
+ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
30
+ const apollo_wind_namespaceObject = require("@uipath/apollo-wind");
31
+ const external_lucide_react_namespaceObject = require("lucide-react");
32
+ const external_react_namespaceObject = require("react");
33
+ const external_classifier_utils_cjs_namespaceObject = require("./classifier-utils.cjs");
34
+ const classifier_threshold_slider_cjs_namespaceObject = require("./components/classifier-threshold-slider.cjs");
35
+ const parameter_label_cjs_namespaceObject = require("./components/parameter-label.cjs");
36
+ const external_i18n_cjs_namespaceObject = require("./i18n.cjs");
37
+ const levelToThreshold = (level, count)=>count <= 1 ? 1 : level / (count - 1);
38
+ const thresholdToLevel = (threshold, count)=>count <= 1 ? 1 : Math.min(count - 1, Math.max(1, Math.ceil(threshold * (count - 1) - 1e-9)));
39
+ const MIDDLE_TIERS = [
40
+ 'severityLow',
41
+ 'severityModerate',
42
+ 'severityHigh'
43
+ ];
44
+ function tierKey(level, count) {
45
+ if (level >= count - 1) return 'severityCritical';
46
+ const position = count - 2 > 1 ? (level - 1) / (count - 3) : 0;
47
+ return MIDDLE_TIERS[Math.round(position * (MIDDLE_TIERS.length - 1))] ?? 'severityLow';
48
+ }
49
+ const isScore = (question)=>'score' === question.type && (question.levels?.length ?? 0) > 1;
50
+ const ROW_HOVER_CHECKBOX = 'group-hover/row:border-muted-foreground';
51
+ function ClassifierQuestionPicker({ parameter, categories, selectedQuestions, questionThresholds, onChange, error, labels: labelOverrides, className }) {
52
+ const labels = (0, external_i18n_cjs_namespaceObject.useGuardrailClassifierLabels)(labelOverrides);
53
+ const uid = (0, external_react_namespaceObject.useId)();
54
+ const [search, setSearch] = (0, external_react_namespaceObject.useState)('');
55
+ const [expanded, setExpanded] = (0, external_react_namespaceObject.useState)(()=>new Set());
56
+ const selected = (0, external_react_namespaceObject.useMemo)(()=>new Set(selectedQuestions), [
57
+ selectedQuestions
58
+ ]);
59
+ const query = search.trim().toLowerCase();
60
+ const visibleCategories = categories.map((category)=>({
61
+ ...category,
62
+ questions: category.questions.filter((q)=>q.question.toLowerCase().includes(query))
63
+ })).filter((category)=>category.questions.length > 0);
64
+ const toggle = (names, checked)=>{
65
+ if (checked) return void onChange([
66
+ ...selectedQuestions,
67
+ ...names.filter((n)=>!selected.has(n))
68
+ ], {
69
+ ...questionThresholds
70
+ });
71
+ const removed = new Set(names);
72
+ onChange(selectedQuestions.filter((n)=>!removed.has(n)), Object.fromEntries(Object.entries(questionThresholds).filter(([n])=>!removed.has(n))));
73
+ };
74
+ const setThreshold = (name, threshold)=>onChange([
75
+ ...selectedQuestions
76
+ ], {
77
+ ...questionThresholds,
78
+ [name]: threshold
79
+ });
80
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(apollo_wind_namespaceObject.FormField, {
81
+ "data-slot": "classifier-question-picker",
82
+ className: (0, apollo_wind_namespaceObject.cn)('gap-3', className),
83
+ children: [
84
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
85
+ className: "grid gap-0.5",
86
+ children: [
87
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(parameter_label_cjs_namespaceObject.ParameterLabel, {
88
+ id: `${uid}-label`,
89
+ paramDef: parameter,
90
+ labels: labels,
91
+ asTextHeader: true
92
+ }),
93
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
94
+ className: "text-xs text-muted-foreground",
95
+ children: (0, external_i18n_cjs_namespaceObject.formatGuardrailFormMessage)(labels.pickerSummary, {
96
+ count: selectedQuestions.length
97
+ })
98
+ })
99
+ ]
100
+ }),
101
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.Search, {
102
+ value: search,
103
+ onChange: setSearch,
104
+ placeholder: labels.searchPlaceholder,
105
+ "aria-label": labels.searchLabel,
106
+ showClearButton: false
107
+ }),
108
+ '' !== query && 0 === visibleCategories.length && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
109
+ className: "text-xs text-muted-foreground",
110
+ children: labels.noMatches
111
+ }),
112
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("fieldset", {
113
+ "aria-labelledby": `${uid}-label`,
114
+ "aria-describedby": error ? `${uid}-error` : void 0,
115
+ className: "m-0 grid min-w-0 border-0 p-0",
116
+ children: visibleCategories.map((category, index)=>{
117
+ const names = category.questions.map((q)=>q.name);
118
+ const count = names.filter((n)=>selected.has(n)).length;
119
+ const open = '' !== query || expanded.has(category.id);
120
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(apollo_wind_namespaceObject.Collapsible, {
121
+ open: open,
122
+ onOpenChange: ()=>setExpanded((previous)=>{
123
+ const next = new Set(previous);
124
+ if (!next.delete(category.id)) next.add(category.id);
125
+ return next;
126
+ }),
127
+ className: (0, apollo_wind_namespaceObject.cn)(index > 0 && 'mt-2 border-t border-border pt-2'),
128
+ children: [
129
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
130
+ className: "group/row flex items-center gap-2 rounded-md px-1 hover:bg-accent",
131
+ children: [
132
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.Checkbox, {
133
+ className: ROW_HOVER_CHECKBOX,
134
+ checked: count === names.length ? true : count > 0 ? 'indeterminate' : false,
135
+ "aria-label": (0, external_i18n_cjs_namespaceObject.formatGuardrailFormMessage)(labels.selectAllInCategory, {
136
+ category: category.label
137
+ }),
138
+ onCheckedChange: (checked)=>toggle(names, true === checked)
139
+ }),
140
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(apollo_wind_namespaceObject.CollapsibleTrigger, {
141
+ className: "flex min-h-8 flex-1 items-center gap-2 rounded-sm text-left text-sm font-semibold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
142
+ children: [
143
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
144
+ children: [
145
+ category.label,
146
+ ' ',
147
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
148
+ className: "text-xs font-normal text-muted-foreground",
149
+ children: [
150
+ count,
151
+ "/",
152
+ names.length
153
+ ]
154
+ })
155
+ ]
156
+ }),
157
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.ChevronDown, {
158
+ "aria-hidden": "true",
159
+ className: (0, apollo_wind_namespaceObject.cn)('ml-auto size-4 shrink-0 text-muted-foreground transition-transform', open && 'rotate-180')
160
+ })
161
+ ]
162
+ })
163
+ ]
164
+ }),
165
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.CollapsibleContent, {
166
+ children: category.questions.map((question)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(QuestionRow, {
167
+ id: `${uid}-question-${question.name}`,
168
+ question: question,
169
+ selected: selected.has(question.name),
170
+ threshold: questionThresholds[question.name] ?? external_classifier_utils_cjs_namespaceObject.CLASSIFIER_DEFAULT_THRESHOLD,
171
+ labels: labels,
172
+ onToggle: (checked)=>toggle([
173
+ question.name
174
+ ], checked),
175
+ onThreshold: (threshold)=>setThreshold(question.name, threshold)
176
+ }, question.name))
177
+ })
178
+ ]
179
+ }, category.id);
180
+ })
181
+ }),
182
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.FormFieldError, {
183
+ id: `${uid}-error`,
184
+ children: error
185
+ })
186
+ ]
187
+ });
188
+ }
189
+ function QuestionRow({ id, question, selected, threshold, labels, onToggle, onThreshold }) {
190
+ const levels = question.levels ?? [];
191
+ const tier = (level)=>labels[tierKey(level, levels.length)];
192
+ const level = thresholdToLevel(threshold, levels.length);
193
+ const named = (template)=>(0, external_i18n_cjs_namespaceObject.formatGuardrailFormMessage)(template, {
194
+ name: question.name
195
+ });
196
+ const details = isScore(question) ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
197
+ children: [
198
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
199
+ className: "text-muted-foreground",
200
+ children: labels.levelsIntro
201
+ }),
202
+ levels.map((text, index)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
203
+ children: index > 0 ? `${tier(index)} — ${text}` : text
204
+ }, text))
205
+ ]
206
+ }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
207
+ children: [
208
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("p", {
209
+ children: [
210
+ labels.criteriaYes,
211
+ " ",
212
+ question.criteriaTrue
213
+ ]
214
+ }),
215
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("p", {
216
+ children: [
217
+ labels.criteriaNo,
218
+ " ",
219
+ question.criteriaFalse
220
+ ]
221
+ })
222
+ ]
223
+ });
224
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
225
+ className: "group/row grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-2 rounded-md py-1 pr-1 pl-7 hover:bg-accent",
226
+ children: [
227
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.Checkbox, {
228
+ id: id,
229
+ className: ROW_HOVER_CHECKBOX,
230
+ checked: selected,
231
+ onCheckedChange: (checked)=>onToggle(true === checked)
232
+ }),
233
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
234
+ className: "flex min-w-0 items-center gap-2",
235
+ children: [
236
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("label", {
237
+ htmlFor: id,
238
+ className: "min-w-0 flex-1 cursor-pointer text-sm",
239
+ children: question.question
240
+ }),
241
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.InfoTooltip, {
242
+ "aria-label": named(labels.questionDetails),
243
+ content: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
244
+ className: "grid gap-0.5 text-xs",
245
+ children: [
246
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
247
+ className: "mb-1 font-semibold",
248
+ children: question.question
249
+ }),
250
+ details
251
+ ]
252
+ })
253
+ })
254
+ ]
255
+ }),
256
+ selected && isScore(question) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
257
+ className: "col-span-2 flex flex-wrap items-center gap-x-2 gap-y-1 pt-1 pb-1.5",
258
+ children: [
259
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
260
+ className: "text-xs text-muted-foreground",
261
+ children: labels.severityCutoffLabel
262
+ }),
263
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(apollo_wind_namespaceObject.Select, {
264
+ value: String(level),
265
+ onValueChange: (next)=>onThreshold(levelToThreshold(Number(next), levels.length)),
266
+ children: [
267
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.SelectTrigger, {
268
+ className: "min-w-32 flex-1",
269
+ "aria-label": named(labels.severityCutoff),
270
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.SelectValue, {
271
+ children: tier(level)
272
+ })
273
+ }),
274
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.SelectContent, {
275
+ className: "max-w-sm",
276
+ children: levels.slice(1).map((text, index)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(apollo_wind_namespaceObject.SelectItem, {
277
+ value: String(index + 1),
278
+ textValue: tier(index + 1),
279
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
280
+ className: "grid gap-0.5 whitespace-normal",
281
+ children: [
282
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
283
+ className: "font-semibold",
284
+ children: tier(index + 1)
285
+ }),
286
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
287
+ className: "text-xs text-muted-foreground",
288
+ children: text
289
+ })
290
+ ]
291
+ })
292
+ }, text))
293
+ })
294
+ ]
295
+ })
296
+ ]
297
+ }),
298
+ selected && !isScore(question) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
299
+ className: "col-span-2 pt-1",
300
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(classifier_threshold_slider_cjs_namespaceObject.ClassifierThresholdSlider, {
301
+ value: threshold,
302
+ ariaLabel: named(labels.questionStrictness),
303
+ labels: labels,
304
+ onChange: onThreshold
305
+ })
306
+ })
307
+ ]
308
+ });
309
+ }
310
+ exports.ClassifierQuestionPicker = __webpack_exports__.ClassifierQuestionPicker;
311
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
312
+ "ClassifierQuestionPicker"
313
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
314
+ Object.defineProperty(exports, '__esModule', {
315
+ value: true
316
+ });
@@ -0,0 +1,15 @@
1
+ import { type GuardrailClassifierLabels } from './i18n';
2
+ import type { GuardrailParameterDefinition } from './types';
3
+ import type { ClassifierQuestionCategory } from './use-classifier-questions';
4
+ export interface ClassifierQuestionPickerProps {
5
+ parameter: GuardrailParameterDefinition;
6
+ categories: readonly ClassifierQuestionCategory[];
7
+ selectedQuestions: readonly string[];
8
+ questionThresholds: Readonly<Record<string, number>>;
9
+ onChange: (selectedQuestions: string[], questionThresholds: Record<string, number>) => void;
10
+ error?: string;
11
+ labels?: Partial<GuardrailClassifierLabels>;
12
+ className?: string;
13
+ }
14
+ export declare function ClassifierQuestionPicker({ parameter, categories, selectedQuestions, questionThresholds, onChange, error, labels: labelOverrides, className, }: ClassifierQuestionPickerProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=classifier-question-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classifier-question-picker.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Guardrails/classifier-question-picker.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAEL,KAAK,yBAAyB,EAE/B,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAsB,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAEjG,MAAM,WAAW,6BAA6B;IAE5C,SAAS,EAAE,4BAA4B,CAAC;IAExC,UAAU,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAClD,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAErD,QAAQ,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,KAAK,EACL,MAAM,EAAE,cAAc,EACtB,SAAS,GACV,EAAE,6BAA6B,2CAuH/B"}
@@ -0,0 +1,282 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, FormField, FormFieldError, InfoTooltip, Search, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, cn } from "@uipath/apollo-wind";
3
+ import { ChevronDown } from "lucide-react";
4
+ import { useId, useMemo, useState } from "react";
5
+ import { CLASSIFIER_DEFAULT_THRESHOLD } from "./classifier-utils.js";
6
+ import { ClassifierThresholdSlider } from "./components/classifier-threshold-slider.js";
7
+ import { ParameterLabel } from "./components/parameter-label.js";
8
+ import { formatGuardrailFormMessage, useGuardrailClassifierLabels } from "./i18n.js";
9
+ const levelToThreshold = (level, count)=>count <= 1 ? 1 : level / (count - 1);
10
+ const thresholdToLevel = (threshold, count)=>count <= 1 ? 1 : Math.min(count - 1, Math.max(1, Math.ceil(threshold * (count - 1) - 1e-9)));
11
+ const MIDDLE_TIERS = [
12
+ 'severityLow',
13
+ 'severityModerate',
14
+ 'severityHigh'
15
+ ];
16
+ function tierKey(level, count) {
17
+ if (level >= count - 1) return 'severityCritical';
18
+ const position = count - 2 > 1 ? (level - 1) / (count - 3) : 0;
19
+ return MIDDLE_TIERS[Math.round(position * (MIDDLE_TIERS.length - 1))] ?? 'severityLow';
20
+ }
21
+ const isScore = (question)=>'score' === question.type && (question.levels?.length ?? 0) > 1;
22
+ const ROW_HOVER_CHECKBOX = 'group-hover/row:border-muted-foreground';
23
+ function ClassifierQuestionPicker({ parameter, categories, selectedQuestions, questionThresholds, onChange, error, labels: labelOverrides, className }) {
24
+ const labels = useGuardrailClassifierLabels(labelOverrides);
25
+ const uid = useId();
26
+ const [search, setSearch] = useState('');
27
+ const [expanded, setExpanded] = useState(()=>new Set());
28
+ const selected = useMemo(()=>new Set(selectedQuestions), [
29
+ selectedQuestions
30
+ ]);
31
+ const query = search.trim().toLowerCase();
32
+ const visibleCategories = categories.map((category)=>({
33
+ ...category,
34
+ questions: category.questions.filter((q)=>q.question.toLowerCase().includes(query))
35
+ })).filter((category)=>category.questions.length > 0);
36
+ const toggle = (names, checked)=>{
37
+ if (checked) return void onChange([
38
+ ...selectedQuestions,
39
+ ...names.filter((n)=>!selected.has(n))
40
+ ], {
41
+ ...questionThresholds
42
+ });
43
+ const removed = new Set(names);
44
+ onChange(selectedQuestions.filter((n)=>!removed.has(n)), Object.fromEntries(Object.entries(questionThresholds).filter(([n])=>!removed.has(n))));
45
+ };
46
+ const setThreshold = (name, threshold)=>onChange([
47
+ ...selectedQuestions
48
+ ], {
49
+ ...questionThresholds,
50
+ [name]: threshold
51
+ });
52
+ return /*#__PURE__*/ jsxs(FormField, {
53
+ "data-slot": "classifier-question-picker",
54
+ className: cn('gap-3', className),
55
+ children: [
56
+ /*#__PURE__*/ jsxs("div", {
57
+ className: "grid gap-0.5",
58
+ children: [
59
+ /*#__PURE__*/ jsx(ParameterLabel, {
60
+ id: `${uid}-label`,
61
+ paramDef: parameter,
62
+ labels: labels,
63
+ asTextHeader: true
64
+ }),
65
+ /*#__PURE__*/ jsx("p", {
66
+ className: "text-xs text-muted-foreground",
67
+ children: formatGuardrailFormMessage(labels.pickerSummary, {
68
+ count: selectedQuestions.length
69
+ })
70
+ })
71
+ ]
72
+ }),
73
+ /*#__PURE__*/ jsx(Search, {
74
+ value: search,
75
+ onChange: setSearch,
76
+ placeholder: labels.searchPlaceholder,
77
+ "aria-label": labels.searchLabel,
78
+ showClearButton: false
79
+ }),
80
+ '' !== query && 0 === visibleCategories.length && /*#__PURE__*/ jsx("p", {
81
+ className: "text-xs text-muted-foreground",
82
+ children: labels.noMatches
83
+ }),
84
+ /*#__PURE__*/ jsx("fieldset", {
85
+ "aria-labelledby": `${uid}-label`,
86
+ "aria-describedby": error ? `${uid}-error` : void 0,
87
+ className: "m-0 grid min-w-0 border-0 p-0",
88
+ children: visibleCategories.map((category, index)=>{
89
+ const names = category.questions.map((q)=>q.name);
90
+ const count = names.filter((n)=>selected.has(n)).length;
91
+ const open = '' !== query || expanded.has(category.id);
92
+ return /*#__PURE__*/ jsxs(Collapsible, {
93
+ open: open,
94
+ onOpenChange: ()=>setExpanded((previous)=>{
95
+ const next = new Set(previous);
96
+ if (!next.delete(category.id)) next.add(category.id);
97
+ return next;
98
+ }),
99
+ className: cn(index > 0 && 'mt-2 border-t border-border pt-2'),
100
+ children: [
101
+ /*#__PURE__*/ jsxs("div", {
102
+ className: "group/row flex items-center gap-2 rounded-md px-1 hover:bg-accent",
103
+ children: [
104
+ /*#__PURE__*/ jsx(Checkbox, {
105
+ className: ROW_HOVER_CHECKBOX,
106
+ checked: count === names.length ? true : count > 0 ? 'indeterminate' : false,
107
+ "aria-label": formatGuardrailFormMessage(labels.selectAllInCategory, {
108
+ category: category.label
109
+ }),
110
+ onCheckedChange: (checked)=>toggle(names, true === checked)
111
+ }),
112
+ /*#__PURE__*/ jsxs(CollapsibleTrigger, {
113
+ className: "flex min-h-8 flex-1 items-center gap-2 rounded-sm text-left text-sm font-semibold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
114
+ children: [
115
+ /*#__PURE__*/ jsxs("span", {
116
+ children: [
117
+ category.label,
118
+ ' ',
119
+ /*#__PURE__*/ jsxs("span", {
120
+ className: "text-xs font-normal text-muted-foreground",
121
+ children: [
122
+ count,
123
+ "/",
124
+ names.length
125
+ ]
126
+ })
127
+ ]
128
+ }),
129
+ /*#__PURE__*/ jsx(ChevronDown, {
130
+ "aria-hidden": "true",
131
+ className: cn('ml-auto size-4 shrink-0 text-muted-foreground transition-transform', open && 'rotate-180')
132
+ })
133
+ ]
134
+ })
135
+ ]
136
+ }),
137
+ /*#__PURE__*/ jsx(CollapsibleContent, {
138
+ children: category.questions.map((question)=>/*#__PURE__*/ jsx(QuestionRow, {
139
+ id: `${uid}-question-${question.name}`,
140
+ question: question,
141
+ selected: selected.has(question.name),
142
+ threshold: questionThresholds[question.name] ?? CLASSIFIER_DEFAULT_THRESHOLD,
143
+ labels: labels,
144
+ onToggle: (checked)=>toggle([
145
+ question.name
146
+ ], checked),
147
+ onThreshold: (threshold)=>setThreshold(question.name, threshold)
148
+ }, question.name))
149
+ })
150
+ ]
151
+ }, category.id);
152
+ })
153
+ }),
154
+ /*#__PURE__*/ jsx(FormFieldError, {
155
+ id: `${uid}-error`,
156
+ children: error
157
+ })
158
+ ]
159
+ });
160
+ }
161
+ function QuestionRow({ id, question, selected, threshold, labels, onToggle, onThreshold }) {
162
+ const levels = question.levels ?? [];
163
+ const tier = (level)=>labels[tierKey(level, levels.length)];
164
+ const level = thresholdToLevel(threshold, levels.length);
165
+ const named = (template)=>formatGuardrailFormMessage(template, {
166
+ name: question.name
167
+ });
168
+ const details = isScore(question) ? /*#__PURE__*/ jsxs(Fragment, {
169
+ children: [
170
+ /*#__PURE__*/ jsx("p", {
171
+ className: "text-muted-foreground",
172
+ children: labels.levelsIntro
173
+ }),
174
+ levels.map((text, index)=>/*#__PURE__*/ jsx("p", {
175
+ children: index > 0 ? `${tier(index)} — ${text}` : text
176
+ }, text))
177
+ ]
178
+ }) : /*#__PURE__*/ jsxs(Fragment, {
179
+ children: [
180
+ /*#__PURE__*/ jsxs("p", {
181
+ children: [
182
+ labels.criteriaYes,
183
+ " ",
184
+ question.criteriaTrue
185
+ ]
186
+ }),
187
+ /*#__PURE__*/ jsxs("p", {
188
+ children: [
189
+ labels.criteriaNo,
190
+ " ",
191
+ question.criteriaFalse
192
+ ]
193
+ })
194
+ ]
195
+ });
196
+ return /*#__PURE__*/ jsxs("div", {
197
+ className: "group/row grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-2 rounded-md py-1 pr-1 pl-7 hover:bg-accent",
198
+ children: [
199
+ /*#__PURE__*/ jsx(Checkbox, {
200
+ id: id,
201
+ className: ROW_HOVER_CHECKBOX,
202
+ checked: selected,
203
+ onCheckedChange: (checked)=>onToggle(true === checked)
204
+ }),
205
+ /*#__PURE__*/ jsxs("div", {
206
+ className: "flex min-w-0 items-center gap-2",
207
+ children: [
208
+ /*#__PURE__*/ jsx("label", {
209
+ htmlFor: id,
210
+ className: "min-w-0 flex-1 cursor-pointer text-sm",
211
+ children: question.question
212
+ }),
213
+ /*#__PURE__*/ jsx(InfoTooltip, {
214
+ "aria-label": named(labels.questionDetails),
215
+ content: /*#__PURE__*/ jsxs("div", {
216
+ className: "grid gap-0.5 text-xs",
217
+ children: [
218
+ /*#__PURE__*/ jsx("p", {
219
+ className: "mb-1 font-semibold",
220
+ children: question.question
221
+ }),
222
+ details
223
+ ]
224
+ })
225
+ })
226
+ ]
227
+ }),
228
+ selected && isScore(question) && /*#__PURE__*/ jsxs("div", {
229
+ className: "col-span-2 flex flex-wrap items-center gap-x-2 gap-y-1 pt-1 pb-1.5",
230
+ children: [
231
+ /*#__PURE__*/ jsx("span", {
232
+ className: "text-xs text-muted-foreground",
233
+ children: labels.severityCutoffLabel
234
+ }),
235
+ /*#__PURE__*/ jsxs(Select, {
236
+ value: String(level),
237
+ onValueChange: (next)=>onThreshold(levelToThreshold(Number(next), levels.length)),
238
+ children: [
239
+ /*#__PURE__*/ jsx(SelectTrigger, {
240
+ className: "min-w-32 flex-1",
241
+ "aria-label": named(labels.severityCutoff),
242
+ children: /*#__PURE__*/ jsx(SelectValue, {
243
+ children: tier(level)
244
+ })
245
+ }),
246
+ /*#__PURE__*/ jsx(SelectContent, {
247
+ className: "max-w-sm",
248
+ children: levels.slice(1).map((text, index)=>/*#__PURE__*/ jsx(SelectItem, {
249
+ value: String(index + 1),
250
+ textValue: tier(index + 1),
251
+ children: /*#__PURE__*/ jsxs("span", {
252
+ className: "grid gap-0.5 whitespace-normal",
253
+ children: [
254
+ /*#__PURE__*/ jsx("span", {
255
+ className: "font-semibold",
256
+ children: tier(index + 1)
257
+ }),
258
+ /*#__PURE__*/ jsx("span", {
259
+ className: "text-xs text-muted-foreground",
260
+ children: text
261
+ })
262
+ ]
263
+ })
264
+ }, text))
265
+ })
266
+ ]
267
+ })
268
+ ]
269
+ }),
270
+ selected && !isScore(question) && /*#__PURE__*/ jsx("div", {
271
+ className: "col-span-2 pt-1",
272
+ children: /*#__PURE__*/ jsx(ClassifierThresholdSlider, {
273
+ value: threshold,
274
+ ariaLabel: named(labels.questionStrictness),
275
+ labels: labels,
276
+ onChange: onThreshold
277
+ })
278
+ })
279
+ ]
280
+ });
281
+ }
282
+ export { ClassifierQuestionPicker };