@knime/product-features 2.0.2 → 2.1.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 (36) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/ai.css +151 -52
  3. package/dist/ai.js +480 -32
  4. package/dist/ai.js.map +1 -1
  5. package/dist/dataTransfer.js +2 -2
  6. package/dist/{dist-BrNh9vG-.js → dist-D6REgugT.js} +104 -15
  7. package/dist/dist-D6REgugT.js.map +1 -0
  8. package/dist/{rfcErrors-Dw7NLSDp.js → rfcErrors-DZsECPcA.js} +2 -2
  9. package/dist/{rfcErrors-Dw7NLSDp.js.map → rfcErrors-DZsECPcA.js.map} +1 -1
  10. package/dist/rfcErrors.js +1 -1
  11. package/dist/src/ai/KdsPromptInput/AttachableSurface.vue.d.ts +29 -0
  12. package/dist/src/ai/KdsPromptInput/AttachableSurface.vue.d.ts.map +1 -0
  13. package/dist/src/ai/KdsPromptInput/InlineStatusBanner.vue.d.ts.map +1 -1
  14. package/dist/src/ai/KdsPromptInput/KdsPromptInput.vue.d.ts +3 -1
  15. package/dist/src/ai/KdsPromptInput/KdsPromptInput.vue.d.ts.map +1 -1
  16. package/dist/src/ai/KdsPromptInput/enums.d.ts +5 -0
  17. package/dist/src/ai/KdsPromptInput/enums.d.ts.map +1 -1
  18. package/dist/src/ai/KdsPromptInput/inquiries/InquiryStack.vue.d.ts +27 -0
  19. package/dist/src/ai/KdsPromptInput/inquiries/InquiryStack.vue.d.ts.map +1 -0
  20. package/dist/src/ai/KdsPromptInput/inquiries/PermissionCard.vue.d.ts +12 -0
  21. package/dist/src/ai/KdsPromptInput/inquiries/PermissionCard.vue.d.ts.map +1 -0
  22. package/dist/src/ai/KdsPromptInput/inquiries/QuestionCard.vue.d.ts +32 -0
  23. package/dist/src/ai/KdsPromptInput/inquiries/QuestionCard.vue.d.ts.map +1 -0
  24. package/dist/src/ai/KdsPromptInput/inquiries/index.d.ts +2 -0
  25. package/dist/src/ai/KdsPromptInput/inquiries/index.d.ts.map +1 -0
  26. package/dist/src/ai/KdsPromptInput/inquiries/usePermissionPhase.d.ts +20 -0
  27. package/dist/src/ai/KdsPromptInput/inquiries/usePermissionPhase.d.ts.map +1 -0
  28. package/dist/src/ai/KdsPromptInput/inquiries/useQuestionPhase.d.ts +26 -0
  29. package/dist/src/ai/KdsPromptInput/inquiries/useQuestionPhase.d.ts.map +1 -0
  30. package/dist/src/ai/KdsPromptInput/types.d.ts +96 -1
  31. package/dist/src/ai/KdsPromptInput/types.d.ts.map +1 -1
  32. package/dist/src/versions/VersionHistory/VersionHistory.vue.d.ts +2 -2
  33. package/dist/toasts.js +1 -1
  34. package/dist/versions.js +1 -1
  35. package/package.json +3 -3
  36. package/dist/dist-BrNh9vG-.js.map +0 -1
package/dist/ai.js CHANGED
@@ -1,10 +1,28 @@
1
1
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
2
- import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, normalizeClass, openBlock, toDisplayString, unref, useModel, useTemplateRef, vModelText, watch, withDirectives, withModifiers } from "vue";
2
+ import { KeepAlive, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, normalizeClass, onMounted, openBlock, reactive, ref, renderSlot, toDisplayString, unref, useModel, useTemplateRef, vModelText, watch, withCtx, withDirectives, withModifiers } from "vue";
3
3
  import { useResizeObserver } from "@vueuse/core";
4
- import { KdsButton, KdsIcon, KdsLink, KdsProgressBar } from "@knime/kds-components";
5
- import './ai.css';//#region src/ai/KdsPromptInput/InlineStatusBanner.vue?vue&type=script&setup=true&lang.ts
6
- var _hoisted_1$1 = ["role"];
7
- var _hoisted_2$1 = {
4
+ import { KdsButton, KdsCheckbox, KdsCheckboxGroup, KdsIcon, KdsLink, KdsProgressBar, KdsRadioButtonGroup, KdsTextInput } from "@knime/kds-components";
5
+ import './ai.css';//#endregion
6
+ //#region src/ai/KdsPromptInput/AttachableSurface.vue
7
+ var AttachableSurface_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
8
+ __name: "AttachableSurface",
9
+ props: { tone: { default: "neutral" } },
10
+ setup(__props) {
11
+ /**
12
+ * Wrapper for a surface that attaches directly above the prompt input
13
+ * (or above another attachable surface).
14
+ *
15
+ * Used by the status banner and inquiry cards.
16
+ */
17
+ return (_ctx, _cache) => {
18
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["attachable-surface", __props.tone]) }, [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 2);
19
+ };
20
+ }
21
+ }), [["__scopeId", "data-v-4cf4affc"]]);
22
+ //#endregion
23
+ //#region src/ai/KdsPromptInput/InlineStatusBanner.vue?vue&type=script&setup=true&lang.ts
24
+ var _hoisted_1$4 = ["role"];
25
+ var _hoisted_2$3 = {
8
26
  class: "text",
9
27
  tabindex: "0"
10
28
  };
@@ -16,29 +34,443 @@ var InlineStatusBanner_default = /*#__PURE__*/ _plugin_vue_export_helper_default
16
34
  emits: ["buttonClick"],
17
35
  setup(__props, { emit: __emit }) {
18
36
  const emit = __emit;
37
+ return (_ctx, _cache) => {
38
+ return openBlock(), createBlock(AttachableSurface_default, { tone: __props.status.type === "error" ? "danger" : "info" }, {
39
+ default: withCtx(() => [createElementVNode("div", {
40
+ class: normalizeClass(["inline-status-banner", __props.status.type]),
41
+ role: __props.status.type === "error" ? "alert" : "status"
42
+ }, [
43
+ createVNode(unref(KdsIcon), {
44
+ name: __props.status.type === "error" ? "circle-error" : "circle-info",
45
+ size: "small",
46
+ class: "icon"
47
+ }, null, 8, ["name"]),
48
+ createElementVNode("span", _hoisted_2$3, toDisplayString(__props.status.message), 1),
49
+ __props.status.buttonLabel ? (openBlock(), createBlock(unref(KdsButton), {
50
+ key: 0,
51
+ class: "action",
52
+ size: "small",
53
+ variant: "filled",
54
+ label: __props.status.buttonLabel,
55
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("buttonClick"))
56
+ }, null, 8, ["label"])) : createCommentVNode("", true)
57
+ ], 10, _hoisted_1$4)]),
58
+ _: 1
59
+ }, 8, ["tone"]);
60
+ };
61
+ }
62
+ }), [["__scopeId", "data-v-df3926bc"]]);
63
+ //#endregion
64
+ //#region src/ai/KdsPromptInput/inquiries/PermissionCard.vue?vue&type=script&setup=true&lang.ts
65
+ var _hoisted_1$3 = { class: "title" };
66
+ var _hoisted_2$2 = { class: "content" };
67
+ var _hoisted_3$2 = {
68
+ key: 0,
69
+ class: "description"
70
+ };
71
+ var _hoisted_4$2 = { class: "action-buttons" };
72
+ //#endregion
73
+ //#region src/ai/KdsPromptInput/inquiries/PermissionCard.vue
74
+ var PermissionCard_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
75
+ __name: "PermissionCard",
76
+ props: { permission: {} },
77
+ emits: ["decide"],
78
+ setup(__props, { emit: __emit }) {
79
+ const emit = __emit;
80
+ const isRememberChoiceChecked = ref(false);
81
+ const decide = (decision) => {
82
+ emit("decide", {
83
+ decision,
84
+ ...__props.permission.remember && { remember: isRememberChoiceChecked.value }
85
+ });
86
+ };
87
+ const allowButtonRef = useTemplateRef("allowButton");
88
+ onMounted(() => {
89
+ (allowButtonRef.value?.$el)?.focus();
90
+ });
91
+ const handleKeydown = (event) => {
92
+ if (event.key === "Enter") {
93
+ event.preventDefault();
94
+ decide("allow");
95
+ } else if (event.key === "Escape") {
96
+ event.preventDefault();
97
+ decide("deny");
98
+ }
99
+ };
19
100
  return (_ctx, _cache) => {
20
101
  return openBlock(), createElementBlock("div", {
21
- class: normalizeClass(["inline-status-banner", __props.status.type]),
22
- role: __props.status.type === "error" ? "alert" : "status"
23
- }, [
24
- createVNode(unref(KdsIcon), {
25
- name: __props.status.type === "error" ? "circle-error" : "circle-info",
102
+ class: "inquiry-card",
103
+ onKeydown: handleKeydown
104
+ }, [createElementVNode("span", _hoisted_1$3, toDisplayString(__props.permission.headline), 1), createElementVNode("div", _hoisted_2$2, [
105
+ __props.permission.description ? (openBlock(), createElementBlock("p", _hoisted_3$2, toDisplayString(__props.permission.description), 1)) : createCommentVNode("", true),
106
+ __props.permission.remember ? (openBlock(), createBlock(unref(KdsCheckbox), {
107
+ key: 1,
108
+ modelValue: isRememberChoiceChecked.value,
109
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRememberChoiceChecked.value = $event),
110
+ label: __props.permission.remember.label,
111
+ "sub-text": __props.permission.remember.subtext
112
+ }, null, 8, [
113
+ "modelValue",
114
+ "label",
115
+ "sub-text"
116
+ ])) : createCommentVNode("", true),
117
+ createElementVNode("div", _hoisted_4$2, [createVNode(unref(KdsButton), {
118
+ variant: "transparent",
119
+ size: "small",
120
+ label: "Deny",
121
+ onClick: _cache[1] || (_cache[1] = ($event) => decide("deny"))
122
+ }), createVNode(unref(KdsButton), {
123
+ ref: "allowButton",
124
+ variant: "outlined",
26
125
  size: "small",
27
- class: "icon"
28
- }, null, 8, ["name"]),
29
- createElementVNode("span", _hoisted_2$1, toDisplayString(__props.status.message), 1),
30
- __props.status.buttonLabel ? (openBlock(), createBlock(unref(KdsButton), {
126
+ label: "Allow",
127
+ onClick: _cache[2] || (_cache[2] = ($event) => decide("allow"))
128
+ }, null, 512)])
129
+ ])], 32);
130
+ };
131
+ }
132
+ }), [["__scopeId", "data-v-495449c9"]]);
133
+ //#endregion
134
+ //#region src/ai/KdsPromptInput/inquiries/QuestionCard.vue?vue&type=script&setup=true&lang.ts
135
+ var _hoisted_1$2 = { class: "title-row" };
136
+ var _hoisted_2$1 = { class: "title" };
137
+ var _hoisted_3$1 = {
138
+ key: 0,
139
+ class: "skipped-tag"
140
+ };
141
+ var _hoisted_4$1 = {
142
+ key: 0,
143
+ class: "pagination"
144
+ };
145
+ var _hoisted_5$1 = { class: "content" };
146
+ var _hoisted_6$1 = {
147
+ key: 0,
148
+ class: "description"
149
+ };
150
+ var _hoisted_7$1 = { class: "action-buttons" };
151
+ var _hoisted_8$1 = { class: "nav-secondary" };
152
+ var _hoisted_9 = { class: "nav-primary" };
153
+ /**
154
+ * A single pending question, shown one at a time and paginated by the parent
155
+ * stack.
156
+ */
157
+ var FREEFORM_OPTION_ID = "__kds-prompt-input-freeform__";
158
+ //#endregion
159
+ //#region src/ai/KdsPromptInput/inquiries/QuestionCard.vue
160
+ var QuestionCard_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
161
+ __name: "QuestionCard",
162
+ props: {
163
+ question: {},
164
+ pageIndex: {},
165
+ pageCount: {},
166
+ othersAnswered: { type: Boolean }
167
+ },
168
+ emits: [
169
+ "back",
170
+ "skip",
171
+ "next",
172
+ "submit"
173
+ ],
174
+ setup(__props, { emit: __emit }) {
175
+ const props = __props;
176
+ const emit = __emit;
177
+ /**
178
+ * Synthetic id of the trailing "Type your own answer" option. Prefixed so it
179
+ * cannot collide with consumer-provided option ids.
180
+ */
181
+ const hasOptions = computed(() => (props.question.options ?? []).length > 0);
182
+ const optionValues = computed(() => [...(props.question.options ?? []).map((option) => ({
183
+ id: option.id,
184
+ text: option.label,
185
+ helperText: option.subText
186
+ })), {
187
+ id: FREEFORM_OPTION_ID,
188
+ text: "Type your own answer"
189
+ }]);
190
+ const selectedSingleId = ref("");
191
+ const selectedMultiIds = ref([]);
192
+ const freeformText = ref("");
193
+ const isSkipped = ref(false);
194
+ const selectedIds = computed(() => {
195
+ if (props.question.multiple) return selectedMultiIds.value;
196
+ return selectedSingleId.value ? [selectedSingleId.value] : [];
197
+ });
198
+ const isFreeformActive = computed(() => !hasOptions.value || selectedIds.value.includes(FREEFORM_OPTION_ID));
199
+ const selectedOptionIds = computed(() => selectedIds.value.filter((id) => id !== FREEFORM_OPTION_ID));
200
+ const canAnswer = computed(() => selectedOptionIds.value.length > 0 || isFreeformActive.value && freeformText.value.trim().length > 0);
201
+ watch(canAnswer, (answerable) => {
202
+ if (answerable) isSkipped.value = false;
203
+ });
204
+ const isLast = computed(() => props.pageIndex === props.pageCount - 1);
205
+ const showPagination = computed(() => props.pageCount > 1);
206
+ const showBack = computed(() => props.pageIndex > 0);
207
+ const primaryLabel = computed(() => isLast.value ? "Submit" : "Next");
208
+ const currentResolved = computed(() => canAnswer.value || isSkipped.value);
209
+ const canProceed = computed(() => isLast.value ? props.othersAnswered && currentResolved.value : currentResolved.value);
210
+ const buildAnswer = () => {
211
+ if (isSkipped.value) return {
212
+ selectedOptionIds: [],
213
+ skipped: true
214
+ };
215
+ const freeform = isFreeformActive.value ? freeformText.value.trim() : "";
216
+ return {
217
+ selectedOptionIds: selectedOptionIds.value,
218
+ ...freeform && { freeformInput: freeform }
219
+ };
220
+ };
221
+ const proceed = () => {
222
+ if (!canProceed.value) return;
223
+ if (isLast.value) emit("submit", buildAnswer());
224
+ else emit("next", buildAnswer());
225
+ };
226
+ const skip = () => {
227
+ selectedSingleId.value = "";
228
+ selectedMultiIds.value = [];
229
+ freeformText.value = "";
230
+ isSkipped.value = true;
231
+ emit("skip");
232
+ };
233
+ const handleKeydown = (event) => {
234
+ if (event.key === "Enter") {
235
+ event.preventDefault();
236
+ proceed();
237
+ } else if (event.key === "Escape") {
238
+ event.preventDefault();
239
+ skip();
240
+ }
241
+ };
242
+ return (_ctx, _cache) => {
243
+ return openBlock(), createElementBlock("div", {
244
+ class: "inquiry-card",
245
+ onKeydown: handleKeydown
246
+ }, [createElementVNode("div", _hoisted_1$2, [createElementVNode("span", _hoisted_2$1, [createTextVNode(toDisplayString(__props.question.headline), 1), isSkipped.value ? (openBlock(), createElementBlock("span", _hoisted_3$1, "(Skipped)")) : createCommentVNode("", true)]), showPagination.value ? (openBlock(), createElementBlock("span", _hoisted_4$1, toDisplayString(__props.pageIndex + 1) + " of " + toDisplayString(__props.pageCount), 1)) : createCommentVNode("", true)]), createElementVNode("div", _hoisted_5$1, [
247
+ __props.question.description ? (openBlock(), createElementBlock("p", _hoisted_6$1, toDisplayString(__props.question.description), 1)) : createCommentVNode("", true),
248
+ !__props.question.multiple && hasOptions.value ? (openBlock(), createBlock(unref(KdsRadioButtonGroup), {
249
+ key: 1,
250
+ modelValue: selectedSingleId.value,
251
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedSingleId.value = $event),
252
+ "possible-values": optionValues.value,
253
+ alignment: "vertical"
254
+ }, null, 8, ["modelValue", "possible-values"])) : createCommentVNode("", true),
255
+ __props.question.multiple && hasOptions.value ? (openBlock(), createBlock(unref(KdsCheckboxGroup), {
256
+ key: 2,
257
+ modelValue: selectedMultiIds.value,
258
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => selectedMultiIds.value = $event),
259
+ "possible-values": optionValues.value,
260
+ alignment: "vertical"
261
+ }, null, 8, ["modelValue", "possible-values"])) : createCommentVNode("", true),
262
+ isFreeformActive.value ? (openBlock(), createBlock(unref(KdsTextInput), {
263
+ key: 3,
264
+ modelValue: freeformText.value,
265
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => freeformText.value = $event),
266
+ ariaLabel: "Type your own answer",
267
+ placeholder: "Type your own answer..."
268
+ }, null, 8, ["modelValue"])) : createCommentVNode("", true),
269
+ createElementVNode("div", _hoisted_7$1, [createElementVNode("div", _hoisted_8$1, [showBack.value ? (openBlock(), createBlock(unref(KdsButton), {
31
270
  key: 0,
32
- class: "action",
271
+ variant: "transparent",
272
+ size: "small",
273
+ label: "Back",
274
+ onClick: _cache[3] || (_cache[3] = ($event) => emit("back"))
275
+ })) : createCommentVNode("", true)]), createElementVNode("div", _hoisted_9, [createVNode(unref(KdsButton), {
276
+ variant: "transparent",
33
277
  size: "small",
34
- variant: "filled",
35
- label: __props.status.buttonLabel,
36
- onClick: _cache[0] || (_cache[0] = ($event) => emit("buttonClick"))
37
- }, null, 8, ["label"])) : createCommentVNode("", true)
38
- ], 10, _hoisted_1$1);
278
+ label: "Skip",
279
+ onClick: skip
280
+ }), createVNode(unref(KdsButton), {
281
+ variant: "outlined",
282
+ size: "small",
283
+ label: primaryLabel.value,
284
+ disabled: !canProceed.value,
285
+ onClick: proceed
286
+ }, null, 8, ["label", "disabled"])])])
287
+ ])], 32);
39
288
  };
40
289
  }
41
- }), [["__scopeId", "data-v-506380c6"]]);
290
+ }), [["__scopeId", "data-v-3293effe"]]);
291
+ //#endregion
292
+ //#region src/ai/KdsPromptInput/inquiries/usePermissionPhase.ts
293
+ /**
294
+ * The permission phase: pending permissions resolved like a stack, with no
295
+ * pager. The current permission is always the first still-undecided one;
296
+ * deciding it pops it off and reveals the next. Buffered decisions persist
297
+ * until {@link reset} so the parent can gather them into a single `respond`
298
+ * once every phase is complete.
299
+ *
300
+ * @param permissions Getter for the pending permissions (kept reactive).
301
+ */
302
+ function usePermissionPhase(permissions) {
303
+ const decisions = reactive(/* @__PURE__ */ new Map());
304
+ /** The first permission not yet decided, or `undefined` once none remain. */
305
+ const current = computed(() => permissions().find((permission) => !decisions.has(permission.id)));
306
+ const isComplete = computed(() => permissions().every((permission) => decisions.has(permission.id)));
307
+ /**
308
+ * Record a decision for `permission`. Returns `false` (a no-op) when the
309
+ * permission was already decided — e.g. a double click landing before the
310
+ * stack pops the card off — so the caller can avoid emitting `respond` twice.
311
+ *
312
+ * A remembered decision also resolves every other undecided permission of the
313
+ * same `remember.group` (e.g. repeated calls of one tool), so the user is not
314
+ * asked again for a choice they just saved. Those never surface — the group
315
+ * is popped silently.
316
+ */
317
+ const decide = (permission, value) => {
318
+ if (decisions.has(permission.id)) return false;
319
+ decisions.set(permission.id, value);
320
+ const group = permission.remember?.group;
321
+ if (group && value.remember) {
322
+ for (const other of permissions()) if (other.remember?.group === group && !decisions.has(other.id)) decisions.set(other.id, value);
323
+ }
324
+ return true;
325
+ };
326
+ /** Buffered decisions in prop order, ready for the `respond` payload. */
327
+ const toOrderedDecisions = () => permissions().map((permission) => ({
328
+ id: permission.id,
329
+ ...decisions.get(permission.id)
330
+ }));
331
+ const reset = () => decisions.clear();
332
+ return {
333
+ current,
334
+ isComplete,
335
+ decide,
336
+ toOrderedDecisions,
337
+ reset
338
+ };
339
+ }
340
+ //#endregion
341
+ //#region src/ai/KdsPromptInput/inquiries/useQuestionPhase.ts
342
+ /**
343
+ * The question phase: pending questions paginated one at a time. The user moves
344
+ * forward with {@link answer} + {@link advance} (or {@link skip}) and back with
345
+ * {@link back}, changing earlier selections freely. Buffered answers persist
346
+ * until {@link reset} so the parent can gather them into a single `respond`
347
+ * once every phase is complete.
348
+ *
349
+ * @param questions Getter for the pending questions (kept reactive).
350
+ */
351
+ function useQuestionPhase(questions) {
352
+ const answers = reactive(/* @__PURE__ */ new Map());
353
+ const index = ref(0);
354
+ const current = computed(() => questions()[index.value]);
355
+ const pageCount = computed(() => questions().length);
356
+ const isComplete = computed(() => questions().every((question) => answers.has(question.id)));
357
+ /**
358
+ * True when every question *other than the current one* has been resolved.
359
+ * The current card supplies its own answer live, so together they decide
360
+ * whether "Submit" is enabled on the last page.
361
+ */
362
+ const othersAnswered = computed(() => questions().every((question, i) => i === index.value || answers.has(question.id)));
363
+ const advance = () => {
364
+ index.value = Math.min(index.value + 1, questions().length - 1);
365
+ };
366
+ const back = () => {
367
+ if (index.value > 0) index.value -= 1;
368
+ };
369
+ const answer = (question, value) => {
370
+ answers.set(question.id, value);
371
+ };
372
+ const skip = (question) => {
373
+ answers.set(question.id, {
374
+ selectedOptionIds: [],
375
+ skipped: true
376
+ });
377
+ };
378
+ /** Buffered answers in prop order, ready for the `respond` payload. */
379
+ const toOrderedAnswers = () => questions().map((question) => ({
380
+ id: question.id,
381
+ ...answers.get(question.id)
382
+ }));
383
+ const reset = () => {
384
+ answers.clear();
385
+ index.value = 0;
386
+ };
387
+ return {
388
+ current,
389
+ index,
390
+ pageCount,
391
+ isComplete,
392
+ othersAnswered,
393
+ advance,
394
+ back,
395
+ answer,
396
+ skip,
397
+ toOrderedAnswers,
398
+ reset
399
+ };
400
+ }
401
+ //#endregion
402
+ //#region src/ai/KdsPromptInput/inquiries/InquiryStack.vue?vue&type=script&setup=true&lang.ts
403
+ var _hoisted_1$1 = { class: "inquiry-stack" };
404
+ //#endregion
405
+ //#region src/ai/KdsPromptInput/inquiries/InquiryStack.vue
406
+ var InquiryStack_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
407
+ __name: "InquiryStack",
408
+ props: {
409
+ permissions: {},
410
+ questions: {}
411
+ },
412
+ emits: ["respond"],
413
+ setup(__props, { emit: __emit }) {
414
+ const emit = __emit;
415
+ const { current: currentPermission, isComplete: permissionsComplete, decide: decidePermission, toOrderedDecisions, reset: resetPermissions } = usePermissionPhase(() => __props.permissions);
416
+ const { current: currentQuestion, index: questionIndex, pageCount: questionCount, isComplete: questionsComplete, othersAnswered, advance: advanceQuestion, back: goBack, answer: recordAnswer, skip: skipQuestion, toOrderedAnswers, reset: resetQuestions } = useQuestionPhase(() => __props.questions);
417
+ watch(() => [...__props.permissions, ...__props.questions].map((inquiry) => inquiry.id).join(","), () => {
418
+ resetPermissions();
419
+ resetQuestions();
420
+ });
421
+ const respondIfComplete = () => {
422
+ if (!permissionsComplete.value || !questionsComplete.value) return;
423
+ emit("respond", {
424
+ permissions: toOrderedDecisions(),
425
+ questions: toOrderedAnswers()
426
+ });
427
+ };
428
+ const onDecidePermission = (permission, decision) => {
429
+ if (decidePermission(permission, decision)) respondIfComplete();
430
+ };
431
+ const onQuestionNext = (question, answer) => {
432
+ recordAnswer(question, answer);
433
+ advanceQuestion();
434
+ };
435
+ const onQuestionSkip = (question) => {
436
+ skipQuestion(question);
437
+ advanceQuestion();
438
+ };
439
+ const onQuestionSubmit = (question, answer) => {
440
+ recordAnswer(question, answer);
441
+ respondIfComplete();
442
+ };
443
+ return (_ctx, _cache) => {
444
+ return unref(currentPermission) || unref(currentQuestion) ? (openBlock(), createBlock(AttachableSurface_default, {
445
+ key: 0,
446
+ tone: "neutral"
447
+ }, {
448
+ default: withCtx(() => [createElementVNode("div", _hoisted_1$1, [unref(currentPermission) ? (openBlock(), createBlock(PermissionCard_default, {
449
+ key: unref(currentPermission).id,
450
+ permission: unref(currentPermission),
451
+ onDecide: _cache[0] || (_cache[0] = (decision) => onDecidePermission(unref(currentPermission), decision))
452
+ }, null, 8, ["permission"])) : unref(currentQuestion) ? (openBlock(), createBlock(KeepAlive, { key: 1 }, [(openBlock(), createBlock(QuestionCard_default, {
453
+ key: unref(currentQuestion).id,
454
+ question: unref(currentQuestion),
455
+ "page-index": unref(questionIndex),
456
+ "page-count": unref(questionCount),
457
+ "others-answered": unref(othersAnswered),
458
+ onBack: unref(goBack),
459
+ onSkip: _cache[1] || (_cache[1] = ($event) => onQuestionSkip(unref(currentQuestion))),
460
+ onNext: _cache[2] || (_cache[2] = (answer) => onQuestionNext(unref(currentQuestion), answer)),
461
+ onSubmit: _cache[3] || (_cache[3] = (answer) => onQuestionSubmit(unref(currentQuestion), answer))
462
+ }, null, 8, [
463
+ "question",
464
+ "page-index",
465
+ "page-count",
466
+ "others-answered",
467
+ "onBack"
468
+ ]))], 1024)) : createCommentVNode("", true)])]),
469
+ _: 1
470
+ })) : createCommentVNode("", true);
471
+ };
472
+ }
473
+ }), [["__scopeId", "data-v-fa0d07a4"]]);
42
474
  //#endregion
43
475
  //#region src/ai/KdsPromptInput/KdsPromptInput.vue?vue&type=script&setup=true&lang.ts
44
476
  var _hoisted_1 = { class: "prompt-input" };
@@ -50,7 +482,7 @@ var _hoisted_3 = [
50
482
  ];
51
483
  var _hoisted_4 = { class: "action" };
52
484
  var _hoisted_5 = {
53
- key: 1,
485
+ key: 2,
54
486
  class: "subtext"
55
487
  };
56
488
  var _hoisted_6 = {
@@ -80,7 +512,9 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
80
512
  ariaLabel: { default: "Prompt" },
81
513
  leftSubtext: { default: () => void 0 },
82
514
  rightSubtext: { default: () => void 0 },
83
- link: { default: () => void 0 }
515
+ link: { default: () => void 0 },
516
+ permissions: { default: () => [] },
517
+ questions: { default: () => [] }
84
518
  }, {
85
519
  "modelValue": { default: "" },
86
520
  "modelModifiers": {}
@@ -88,13 +522,16 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
88
522
  emits: /*@__PURE__*/ mergeModels([
89
523
  "submit",
90
524
  "stop",
91
- "statusButtonClick"
525
+ "statusButtonClick",
526
+ "respond"
92
527
  ], ["update:modelValue"]),
93
528
  setup(__props, { expose: __expose, emit: __emit }) {
94
529
  const emit = __emit;
95
530
  const modelValue = useModel(__props, "modelValue");
96
531
  const textareaRef = useTemplateRef("textareaRef");
97
- const canSubmit = computed(() => !__props.disabled && !__props.loading && modelValue.value.trim().length > 0);
532
+ const hasInquiries = computed(() => __props.permissions.length > 0 || __props.questions.length > 0);
533
+ const isDisabled = computed(() => __props.disabled || hasInquiries.value);
534
+ const canSubmit = computed(() => !isDisabled.value && !__props.loading && modelValue.value.trim().length > 0);
98
535
  function resizeTextarea() {
99
536
  const el = textareaRef.value;
100
537
  if (!el) return;
@@ -126,9 +563,15 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
126
563
  status: __props.status,
127
564
  onButtonClick: _cache[0] || (_cache[0] = ($event) => emit("statusButtonClick"))
128
565
  }, null, 8, ["status"])) : createCommentVNode("", true),
566
+ hasInquiries.value ? (openBlock(), createBlock(unref(InquiryStack_default), {
567
+ key: 1,
568
+ permissions: __props.permissions,
569
+ questions: __props.questions,
570
+ onRespond: _cache[1] || (_cache[1] = ($event) => emit("respond", $event))
571
+ }, null, 8, ["permissions", "questions"])) : createCommentVNode("", true),
129
572
  createElementVNode("div", {
130
- class: normalizeClass(["input-container", { disabled: __props.disabled }]),
131
- onClick: _cache[3] || (_cache[3] = ($event) => textareaRef.value?.focus())
573
+ class: normalizeClass(["input-container", { disabled: isDisabled.value }]),
574
+ onClick: _cache[4] || (_cache[4] = ($event) => textareaRef.value?.focus())
132
575
  }, [
133
576
  __props.loading ? (openBlock(), createBlock(unref(KdsProgressBar), {
134
577
  key: 0,
@@ -138,11 +581,11 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
138
581
  createElementVNode("div", _hoisted_2, [withDirectives(createElementVNode("textarea", {
139
582
  ref_key: "textareaRef",
140
583
  ref: textareaRef,
141
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => modelValue.value = $event),
584
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => modelValue.value = $event),
142
585
  class: "text-input",
143
586
  rows: "1",
144
587
  placeholder: __props.placeholder,
145
- disabled: __props.disabled,
588
+ disabled: isDisabled.value,
146
589
  "aria-label": __props.ariaLabel,
147
590
  onKeydown
148
591
  }, null, 40, _hoisted_3), [[vModelText, modelValue.value]])]),
@@ -152,7 +595,7 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
152
595
  "leading-icon": "stop",
153
596
  size: "medium",
154
597
  ariaLabel: "Stop",
155
- onClick: _cache[2] || (_cache[2] = withModifiers(($event) => emit("stop"), ["stop"]))
598
+ onClick: _cache[3] || (_cache[3] = withModifiers(($event) => emit("stop"), ["stop"]))
156
599
  })) : (openBlock(), createBlock(unref(KdsButton), {
157
600
  key: 1,
158
601
  variant: "filled",
@@ -172,7 +615,7 @@ var KdsPromptInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
172
615
  ]);
173
616
  };
174
617
  }
175
- }), [["__scopeId", "data-v-e6b41a78"]]);
618
+ }), [["__scopeId", "data-v-92a6ac4b"]]);
176
619
  //#endregion
177
620
  //#region src/ai/KdsPromptInput/enums.ts
178
621
  var kdsPromptInputStatusType = {
@@ -180,7 +623,12 @@ var kdsPromptInputStatusType = {
180
623
  NOTE: "note"
181
624
  };
182
625
  var kdsPromptInputStatusTypes = Object.values(kdsPromptInputStatusType);
626
+ var kdsPromptInputPermissionDecision = {
627
+ ALLOW: "allow",
628
+ DENY: "deny"
629
+ };
630
+ var kdsPromptInputPermissionDecisions = Object.values(kdsPromptInputPermissionDecision);
183
631
  //#endregion
184
- export { KdsPromptInput_default as KdsPromptInput, kdsPromptInputStatusType, kdsPromptInputStatusTypes };
632
+ export { KdsPromptInput_default as KdsPromptInput, kdsPromptInputPermissionDecision, kdsPromptInputPermissionDecisions, kdsPromptInputStatusType, kdsPromptInputStatusTypes };
185
633
 
186
634
  //# sourceMappingURL=ai.js.map