@revenexx/studio-integrations 2.8.0 → 2.8.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @revenexx/studio-integrations
|
|
2
2
|
|
|
3
|
+
## 2.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 46507f8: Escape in an open option list closes the list and stops there. In a node's dialog, the searchable list of a setting whose options come from the platform let Escape through to the dialog, which took it as Cancel and threw away every setting entered in it (PO-655). Escape with no list open still cancels the dialog.
|
|
8
|
+
|
|
3
9
|
## 2.8.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/module.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, ref } from "vue";
|
|
2
|
+
import { computed, nextTick, ref, watch } from "vue";
|
|
3
3
|
import { isVersionExecutable } from "../../data/integrationNodeCatalog";
|
|
4
4
|
import { ChevronDown } from "lucide-vue-next";
|
|
5
5
|
import { Input } from "@revenexx/studio";
|
|
@@ -33,14 +33,44 @@ const options = computed(() => q.data.value?.options ?? []);
|
|
|
33
33
|
const isMulti = computed(() => props.field.type === "multiselect");
|
|
34
34
|
const disabledControlClass = "flex h-8 items-center rounded-md border border-black/[0.08] bg-white px-2 text-sm text-muted-foreground opacity-50";
|
|
35
35
|
const currentValue = computed(() => String(props.modelValue ?? ""));
|
|
36
|
+
const seenLabels = ref(/* @__PURE__ */ new Map());
|
|
37
|
+
watch(options, (list) => {
|
|
38
|
+
for (const o of list) seenLabels.value.set(String(o.value), resolveLocalized(o.label) || String(o.value));
|
|
39
|
+
}, { immediate: true });
|
|
36
40
|
const currentKnown = computed(
|
|
37
|
-
() => options.value.some((o) => String(o.value) === currentValue.value)
|
|
41
|
+
() => options.value.some((o) => String(o.value) === currentValue.value) || seenLabels.value.has(currentValue.value)
|
|
38
42
|
);
|
|
39
|
-
const currentLabel = computed(() =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
const currentLabel = computed(() => seenLabels.value.get(currentValue.value) ?? currentValue.value);
|
|
44
|
+
const listDismissed = ref(false);
|
|
45
|
+
const listOpen = computed(() => focused.value && !q.gated.value && !listDismissed.value);
|
|
46
|
+
const escapeHeld = ref(false);
|
|
47
|
+
function onComboEscape(event) {
|
|
48
|
+
if (event.isComposing) return;
|
|
49
|
+
const claim = listOpen.value || escapeHeld.value && event.repeat;
|
|
50
|
+
if (!claim) return;
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
event.stopPropagation();
|
|
53
|
+
if (!listOpen.value) return;
|
|
54
|
+
escapeHeld.value = true;
|
|
55
|
+
listDismissed.value = true;
|
|
56
|
+
const input = event.target;
|
|
57
|
+
void nextTick(() => input.select());
|
|
58
|
+
}
|
|
59
|
+
function onComboEscapeUp() {
|
|
60
|
+
escapeHeld.value = false;
|
|
61
|
+
}
|
|
62
|
+
function onComboArrowDown(event) {
|
|
63
|
+
if (!listDismissed.value) return;
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
listDismissed.value = false;
|
|
66
|
+
}
|
|
67
|
+
function onComboSearch(v) {
|
|
68
|
+
search.value = String(v);
|
|
69
|
+
listDismissed.value = false;
|
|
70
|
+
}
|
|
71
|
+
function onComboClick() {
|
|
72
|
+
listDismissed.value = false;
|
|
73
|
+
}
|
|
44
74
|
const visibleOptions = computed(() => {
|
|
45
75
|
const term = search.value.trim().toLowerCase();
|
|
46
76
|
if (!focused.value || !term) return options.value;
|
|
@@ -51,6 +81,7 @@ const visibleOptions = computed(() => {
|
|
|
51
81
|
});
|
|
52
82
|
function onComboFocus() {
|
|
53
83
|
search.value = "";
|
|
84
|
+
listDismissed.value = false;
|
|
54
85
|
focused.value = true;
|
|
55
86
|
}
|
|
56
87
|
function onComboBlur() {
|
|
@@ -155,14 +186,16 @@ function toggleMulti(optValue) {
|
|
|
155
186
|
<template v-else>
|
|
156
187
|
<div class="relative">
|
|
157
188
|
<Input
|
|
158
|
-
:model-value="
|
|
189
|
+
:model-value="listOpen ? search : currentLabel"
|
|
159
190
|
:aria-label="resolveLocalized(field.label)"
|
|
160
191
|
:placeholder="resolveLocalized(field.placeholder) || t('integration.nodeConfig.select.placeholder')"
|
|
161
192
|
class="h-8 bg-white pr-7 text-sm"
|
|
162
|
-
@update:model-value="
|
|
163
|
-
search = String(v);
|
|
164
|
-
}"
|
|
193
|
+
@update:model-value="onComboSearch"
|
|
165
194
|
@focus="onComboFocus"
|
|
195
|
+
@click="onComboClick"
|
|
196
|
+
@keydown.esc="onComboEscape"
|
|
197
|
+
@keyup.esc="onComboEscapeUp"
|
|
198
|
+
@keydown.down="onComboArrowDown"
|
|
166
199
|
@blur="onComboBlur"
|
|
167
200
|
/>
|
|
168
201
|
<ChevronDown :size="14" class="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground" />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revenexx/studio-integrations",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Integration Studio (core: workflows, node editor, runs, schedules, credentials, secrets, audit) as a standalone, publishable Nuxt module.",
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"vue-sonner": "^2.0.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@changesets/cli": "^
|
|
56
|
+
"@changesets/cli": "^3.0.3",
|
|
57
57
|
"@nuxt/eslint-config": "^1.17.0",
|
|
58
58
|
"@nuxt/kit": "^4.0.0",
|
|
59
59
|
"@nuxt/module-builder": "^1.0.2",
|