@revenexx/studio-integrations 1.2.0 → 1.4.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/CHANGELOG.md +581 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/Integrations/CanvasShortcutsDialog.d.vue.ts +9 -0
- package/dist/runtime/components/Integrations/CanvasShortcutsDialog.vue +53 -0
- package/dist/runtime/components/Integrations/CanvasShortcutsDialog.vue.d.ts +9 -0
- package/dist/runtime/components/Integrations/EditorTip.vue +2 -15
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +10 -2
- package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +15 -1
- package/dist/runtime/components/Integrations/NodeConfigField.vue +158 -49
- package/dist/runtime/components/Integrations/NodeConfigField.vue.d.ts +15 -1
- package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +5 -1
- package/dist/runtime/components/Integrations/NodeInspector.vue +136 -81
- package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +5 -1
- package/dist/runtime/components/Integrations/NodeVersionMoveDialog.d.vue.ts +21 -0
- package/dist/runtime/components/Integrations/NodeVersionMoveDialog.vue +133 -0
- package/dist/runtime/components/Integrations/NodeVersionMoveDialog.vue.d.ts +21 -0
- package/dist/runtime/components/Integrations/RunDetailPanel.vue +80 -33
- package/dist/runtime/components/Integrations/StateNamespaceCreateDialog.d.vue.ts +16 -0
- package/dist/runtime/components/Integrations/StateNamespaceCreateDialog.vue +111 -0
- package/dist/runtime/components/Integrations/StateNamespaceCreateDialog.vue.d.ts +16 -0
- package/dist/runtime/components/Integrations/TemplateCard.d.vue.ts +0 -4
- package/dist/runtime/components/Integrations/TemplateCard.vue +3 -6
- package/dist/runtime/components/Integrations/TemplateCard.vue.d.ts +0 -4
- package/dist/runtime/components/Integrations/TemplateInstallStep.d.vue.ts +25 -0
- package/dist/runtime/components/Integrations/TemplateInstallStep.vue +198 -0
- package/dist/runtime/components/Integrations/TemplateInstallStep.vue.d.ts +25 -0
- package/dist/runtime/components/Integrations/WorkflowContextMenu.d.vue.ts +2 -2
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +22 -40
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue.d.ts +2 -2
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +94 -65
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +36 -2
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +200 -54
- package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +36 -2
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.d.vue.ts +6 -2
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +4 -106
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue.d.ts +6 -2
- package/dist/runtime/components/Integrations/WorkflowStateNamespacesDialog.d.vue.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowStateNamespacesDialog.vue +216 -0
- package/dist/runtime/components/Integrations/WorkflowStateNamespacesDialog.vue.d.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowsTable.vue +22 -11
- package/dist/runtime/composables/useCanvasShortcuts.d.ts +34 -0
- package/dist/runtime/composables/useCanvasShortcuts.js +11 -8
- package/dist/runtime/composables/useCredentialTypes.js +3 -9
- package/dist/runtime/composables/useIntegrationsCredentials.js +6 -14
- package/dist/runtime/composables/useIntegrationsNodes.js +2 -2
- package/dist/runtime/composables/useIntegrationsRuns.js +8 -13
- package/dist/runtime/composables/useIntegrationsSecrets.js +5 -5
- package/dist/runtime/composables/useIntegrationsTemplates.js +10 -8
- package/dist/runtime/composables/useIntegrationsTriggers.js +1 -4
- package/dist/runtime/composables/useIntegrationsWorkflows.js +11 -7
- package/dist/runtime/data/canvasShortcuts.d.ts +208 -0
- package/dist/runtime/data/canvasShortcuts.js +68 -0
- package/dist/runtime/data/integrationNodeCatalog.d.ts +25 -0
- package/dist/runtime/data/integrationNodeCatalog.js +8 -0
- package/dist/runtime/data/nodeVersionMove.d.ts +72 -0
- package/dist/runtime/data/nodeVersionMove.js +65 -0
- package/dist/runtime/i18n/messages/de.json +83 -20
- package/dist/runtime/i18n/messages/en.json +83 -20
- package/dist/runtime/pages/integrations/templates/[slug].vue +22 -132
- package/dist/runtime/pages/integrations/workflows/[id].vue +158 -53
- package/dist/runtime/pages/integrations/workflows/index.vue +23 -4
- package/dist/runtime/types/integrations.d.ts +44 -1
- package/dist/runtime/utils/apiEnvelope.d.ts +27 -0
- package/dist/runtime/utils/apiEnvelope.js +20 -0
- package/dist/runtime/utils/buildSettle.d.ts +68 -0
- package/dist/runtime/utils/buildSettle.js +29 -0
- package/dist/runtime/utils/configDefaults.d.ts +18 -0
- package/dist/runtime/utils/configDefaults.js +7 -0
- package/dist/runtime/utils/errorPathAdvice.d.ts +60 -0
- package/dist/runtime/utils/errorPathAdvice.js +19 -0
- package/dist/runtime/utils/notify.d.ts +2 -2
- package/dist/runtime/utils/runEnvelope.d.ts +12 -0
- package/dist/runtime/utils/runEnvelope.js +2 -1
- package/dist/runtime/utils/selectOptions.d.ts +48 -0
- package/dist/runtime/utils/selectOptions.js +19 -0
- package/dist/runtime/utils/settingCondition.d.ts +48 -0
- package/dist/runtime/utils/settingCondition.js +84 -0
- package/dist/runtime/utils/shortcutLabel.d.ts +40 -0
- package/dist/runtime/utils/shortcutLabel.js +48 -0
- package/dist/runtime/utils/stateNamespaceName.d.ts +23 -0
- package/dist/runtime/utils/stateNamespaceName.js +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,586 @@
|
|
|
1
1
|
# @revenexx/studio-integrations
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 388babd: Installing a template takes the same step from both routes into it (PO-244).
|
|
8
|
+
|
|
9
|
+
A template could be installed from two places, and the two gave the user different
|
|
10
|
+
workflows. From the "New workflow" dialog one press of a card installed it there and
|
|
11
|
+
then: the copy arrived under the template's own name, bound to none of the tenant's
|
|
12
|
+
credentials, with nothing said about either — and a refusal came back as a message
|
|
13
|
+
that disappeared. From the template's own page the same act named the copy first,
|
|
14
|
+
offered a credential per place that needs one, listed the secrets it references as
|
|
15
|
+
stored or missing, and kept a refusal on screen with what had been entered. Nobody
|
|
16
|
+
had decided that; the richer route simply arrived later.
|
|
17
|
+
|
|
18
|
+
The dialog's card now opens that same step in place of the list of templates, with
|
|
19
|
+
the way back to the list beside the name. Both routes therefore create the same
|
|
20
|
+
workflow, and it is created when the user confirms rather than when they press a
|
|
21
|
+
card. The step is one component reached from both places, so what it offers cannot
|
|
22
|
+
drift apart again, and while it works out what the template needs it says so —
|
|
23
|
+
"needs no credentials" and "not asked yet" used to look the same.
|
|
24
|
+
|
|
25
|
+
Two things a host should know. **Pressing a card no longer creates anything**, so a
|
|
26
|
+
test or a script that pressed one and waited for the editor now has to confirm the
|
|
27
|
+
step. And the template card has lost its `busy` and `disabled` props, which existed
|
|
28
|
+
for the install that used to start on the card itself; nothing acts on a card any
|
|
29
|
+
more.
|
|
30
|
+
|
|
31
|
+
- 79f42db: The run replay replays the run it was handed, and nothing else (PO-350).
|
|
32
|
+
|
|
33
|
+
The replay carried a second mode, switched by a `single` prop: a 320 px sidebar
|
|
34
|
+
listing the workflow's runs to browse, beside the canvas. No route in the studio
|
|
35
|
+
ever mounted it — the run record took the replay over and passed `single` from the
|
|
36
|
+
day it did — so what shipped was a surface with a defect nobody could reach: asked
|
|
37
|
+
for a run it did not find among the most recent ones, it replayed the newest run
|
|
38
|
+
instead, under a label naming the newest run. A host mounting the component the way
|
|
39
|
+
its own prop documented got that, quietly.
|
|
40
|
+
|
|
41
|
+
The mode is gone. The replay now walks the run it is given, whatever else the
|
|
42
|
+
workflow has run, and with no run given it says so rather than choosing one. Runs
|
|
43
|
+
are browsed on the studio's own runs table, which filters, pages and offers the row
|
|
44
|
+
actions the sidebar never had — and the replay no longer asks for a run list it had
|
|
45
|
+
no use for.
|
|
46
|
+
|
|
47
|
+
`single` is still accepted and now ignored, so a host passing it keeps working; it
|
|
48
|
+
is deprecated and will be dropped at the next major. The four `runsList` strings
|
|
49
|
+
and the run-list failure message leave with the mode.
|
|
50
|
+
|
|
51
|
+
Two more strings stay but stop pointing at it: a panel given no run to replay used
|
|
52
|
+
to answer _Pick a run on the right to replay it._, where the right-hand side was
|
|
53
|
+
that sidebar. It now says _No run to replay._ — the state, rather than an
|
|
54
|
+
instruction with nothing to follow it.
|
|
55
|
+
|
|
56
|
+
- 3ddba20: A workflow that leaves the run mode to its caller is asked which one, instead of
|
|
57
|
+
being run asynchronously (PO-428).
|
|
58
|
+
|
|
59
|
+
Pressing Run in the editor opened a dialog only where the workflow read something
|
|
60
|
+
from its trigger payload. A workflow whose execution mode is **Caller decides** and
|
|
61
|
+
whose nodes read no payload therefore never reached the offer at all: it was started
|
|
62
|
+
in the mode that does not wait, and a run whose result the author wanted to wait for
|
|
63
|
+
could not be started by hand. It now opens the same dialog, with both modes on it.
|
|
64
|
+
`mod+enter` follows the button, as it always has.
|
|
65
|
+
|
|
66
|
+
The dialog is named after the run rather than after the payload: **Run workflow**,
|
|
67
|
+
"Starts a manual run of this workflow. What it returns is shown here when it ends."
|
|
68
|
+
The payload is a field on it and names itself. The old description also still
|
|
69
|
+
promised the result on the Runs tab, which stopped being where it appears when the
|
|
70
|
+
dialog began showing what the run returned.
|
|
71
|
+
|
|
72
|
+
Where both modes are offered, the one that waits for the result is now the suggested
|
|
73
|
+
one, on the right, and it stays the suggested one however the last run was started —
|
|
74
|
+
the offer follows the workflow, not the last press. The mode words on the buttons are
|
|
75
|
+
unchanged.
|
|
76
|
+
|
|
77
|
+
Promised behaviour: `specs/run-from-editor.md` AC-1, AC-2 and AC-10.
|
|
78
|
+
|
|
79
|
+
- 1cb60f7: Every key the workflow canvas answers can be read in one place, and one of them
|
|
80
|
+
could not be pressed on a German keyboard (PO-431).
|
|
81
|
+
|
|
82
|
+
**Press `?` on the canvas** for a list of its keys, grouped and written the way your
|
|
83
|
+
own keyboard is labelled. The canvas answers two dozen shortcuts, and until now
|
|
84
|
+
learning them meant hovering thirteen controls and right-clicking three different
|
|
85
|
+
things — two of them, activating the workflow and renaming a node with Space, were
|
|
86
|
+
shown nowhere at all.
|
|
87
|
+
|
|
88
|
+
**Zooming in now works on every layout.** The binding was `=`, which a German
|
|
89
|
+
keyboard types as Shift+0 — and a Shift the layout requires to produce a character
|
|
90
|
+
was being counted as part of the shortcut, so the key answered on a US keyboard and
|
|
91
|
+
on no other. A character key is now reached however a layout types it, while a
|
|
92
|
+
shortcut that means Shift over a letter still needs Shift held. **Zooming in is now
|
|
93
|
+
`+`** — the key a German keyboard has of its own and a US one reaches with Shift; the
|
|
94
|
+
old `=`, which only ever worked on a US layout, is gone rather than kept as a second
|
|
95
|
+
undocumented way in. Zooming out is `-`, as before.
|
|
96
|
+
|
|
97
|
+
**A modifier is spelled the way its platform spells it.** The command and option keys
|
|
98
|
+
already followed the platform; the shift key was the glyph ⇧ everywhere, so a Windows
|
|
99
|
+
or Linux reader got `Ctrl+⇧+G`. On those platforms it now reads `Ctrl+Shift+G`; on a
|
|
100
|
+
mac nothing changes.
|
|
101
|
+
|
|
102
|
+
Behind all three: the keys live in one list that the overview, the canvas's context
|
|
103
|
+
menu and the control pane's tooltips all read, so a key cannot be shown in one place
|
|
104
|
+
and answered in another. The menu had already drifted — it offered renaming as `F2`
|
|
105
|
+
for a key that answers `Space` too.
|
|
106
|
+
|
|
107
|
+
Promised behaviour: `specs/canvas-keyboard-shortcuts.md` AC-4, AC-5 and AC-6.
|
|
108
|
+
|
|
109
|
+
- 4aa26a6: The editor points out an error output nobody connected, and attaches the ending
|
|
110
|
+
our own templates use (PO-443).
|
|
111
|
+
|
|
112
|
+
**A step that fails on a path nobody drew is not handled.** Most nodes have a red
|
|
113
|
+
error output; if the author never drew a line out of it, a failure there is not
|
|
114
|
+
carried anywhere. The platform now ends the run on it — but by then the workflow
|
|
115
|
+
has been running unattended for weeks. This is the half that says so while it is
|
|
116
|
+
still being drawn.
|
|
117
|
+
|
|
118
|
+
**A slate strip above the canvas names each step whose error output leads
|
|
119
|
+
nowhere**, and a line jumps to that step on the canvas. Deliberately not amber:
|
|
120
|
+
amber already means "fix this before it runs" in this editor twice over, and this
|
|
121
|
+
is not that.
|
|
122
|
+
|
|
123
|
+
**It blocks nothing.** Not activation, not saving, not starting a run. That is the
|
|
124
|
+
whole point of it being advice: the same fact expressed as a validation finding
|
|
125
|
+
would have closed the activation gate — and the run gate — on every workflow that
|
|
126
|
+
has an unconnected error output, including ones that have run nightly for months.
|
|
127
|
+
The rule is therefore computed in the editor, where no gate can read it.
|
|
128
|
+
|
|
129
|
+
**One click attaches the ending.** _Stop the run on error_ drops a Stop and Error
|
|
130
|
+
step below the node, wires it to the error output, and pre-fills its message the
|
|
131
|
+
way all eight shipped templates write theirs — the failing step by name, then its
|
|
132
|
+
own reason quoted out of the port that carried it. Nothing is saved until the
|
|
133
|
+
author saves; deleting the step undoes it.
|
|
134
|
+
|
|
135
|
+
A step nobody has connected yet is left alone, so laying out a workflow before
|
|
136
|
+
wiring it does not produce a wall of complaints. A step whose ports are named only
|
|
137
|
+
once its settings resolve is left alone too — nothing is claimed about an output
|
|
138
|
+
the declaration cannot name.
|
|
139
|
+
|
|
140
|
+
Promised behaviour: `specs/workflow-advice.md`, a new spec that owns what the
|
|
141
|
+
editor says about a workflow it has no objection to. `specs/workflow-validation.md`
|
|
142
|
+
keeps the gate, and the two now say so about each other.
|
|
143
|
+
|
|
144
|
+
- 1a1edc3: A node's settings keep the order it declares them in, and only the tail is
|
|
145
|
+
folded (PO-463).
|
|
146
|
+
|
|
147
|
+
The node configuration dialog used to draw every required setting first and fold
|
|
148
|
+
every optional one away. That discarded the order the node author chose and made
|
|
149
|
+
requiredness stand for importance, which it cannot: the API refuses a required
|
|
150
|
+
setting that is empty, so a setting that is central and legitimately empty — Text
|
|
151
|
+
Replace's replacement, whose empty value is how a search value is deleted — had
|
|
152
|
+
to be optional, and therefore disappeared. Text Replace showed one of its six
|
|
153
|
+
settings, and not the one it is named after.
|
|
154
|
+
|
|
155
|
+
The Parameters tab now draws the settings a node declares as one list, in that
|
|
156
|
+
order. Four or fewer are all shown; beyond four the first three are always shown
|
|
157
|
+
and, from the fourth on, a setting is shown when it is required and folded when
|
|
158
|
+
it is not. The fold keeps its single control and its count, and now stands at the
|
|
159
|
+
first setting it hides, so opening it puts the tail back where the node declared
|
|
160
|
+
it. Counted over the 51 published core node types, 157 of 203 settings reach the
|
|
161
|
+
open form where 103 did before, and no node shows fewer than it did.
|
|
162
|
+
|
|
163
|
+
Nothing is required of a node package: the lever is the order a node already
|
|
164
|
+
declares. A node whose central setting still sits past the third — HTTP Request's
|
|
165
|
+
body, Send Email's two bodies — moves it up in its own manifest.
|
|
166
|
+
|
|
167
|
+
- 633f3bf: The workflows list says whether it is grouped by tag, and now promises what
|
|
168
|
+
grouping does (PO-468).
|
|
169
|
+
|
|
170
|
+
Grouping the list by tag was offered by a button that read "Group by tags"
|
|
171
|
+
whether or not the list was already grouped — so pressing it once more ungrouped
|
|
172
|
+
a list whose control still invited grouping, and the only sign of the state was
|
|
173
|
+
the button's colour. It is now a switch: it shows whether grouping is on, to a
|
|
174
|
+
reader and to a screen reader alike.
|
|
175
|
+
|
|
176
|
+
Two behaviours the list already had are promises from here on, with tests behind
|
|
177
|
+
them: the grouping an operator chose is the one the list arrives in on the next
|
|
178
|
+
visit, kept in that browser alone, and a workflow carrying several tags stands
|
|
179
|
+
under each of them, with the untagged ones together under "No tags" at the end.
|
|
180
|
+
No shipped string changes.
|
|
181
|
+
|
|
182
|
+
- 652a08f: Every canvas now zooms between the same two ends, and the editor no longer offers a
|
|
183
|
+
reach that shows nothing (PO-470).
|
|
184
|
+
|
|
185
|
+
The editor went to four times full size while the run replay and the history preview
|
|
186
|
+
stopped at twice. That was never decided: all three stopped at twice until the
|
|
187
|
+
editor's zoom picker was given a 400% preset and its ceiling was raised to match.
|
|
188
|
+
Asked what the extra reach was for, the answer turned out to be nothing — a step's
|
|
189
|
+
card carries a name, a version and a mark, and at four times full size a single card
|
|
190
|
+
fills the canvas without saying more than it did at half that.
|
|
191
|
+
|
|
192
|
+
So the editor comes down to twice full size, where the other two canvases already
|
|
193
|
+
were, and the 300% and 400% entries leave its zoom menu. The menu gains 25%, the
|
|
194
|
+
level the wheel could always reach and the list never offered — it now spans the
|
|
195
|
+
whole range, ends included. Anything typed into the zoom field beyond the range
|
|
196
|
+
still lands at the range's end rather than being refused.
|
|
197
|
+
|
|
198
|
+
Three criteria hold it from here on: the range on all three canvases, the clamping,
|
|
199
|
+
and the six levels the menu offers — 25%, 50%, 75%, 100%, 150% and 200%. That last
|
|
200
|
+
one is named rather than described on purpose: adding, removing or moving a level
|
|
201
|
+
changes what the editor offers an author, and it should take a decision rather than
|
|
202
|
+
a tweak.
|
|
203
|
+
|
|
204
|
+
### Patch Changes
|
|
205
|
+
|
|
206
|
+
- 2b6af97: Three copy-catalogue entries have their source back (PO-244).
|
|
207
|
+
|
|
208
|
+
The catalogue records where each shipped string is used, and recomputing those
|
|
209
|
+
references after the template install step moved lost three of them: the
|
|
210
|
+
publisher badges — Official, Partner, Community — are looked up through a map
|
|
211
|
+
rather than named in a `t()` call, so a scan for `t('…')` did not find them. A
|
|
212
|
+
unit test guards exactly that, and it is why this was caught on `main` rather
|
|
213
|
+
than by a reader finding an entry that points nowhere. No shipped string changes.
|
|
214
|
+
|
|
215
|
+
- aff19fa: One answer to whether a response carries a `data` envelope, checked against the
|
|
216
|
+
service (PO-394).
|
|
217
|
+
|
|
218
|
+
Nine expressions in five composables each decided for themselves whether the
|
|
219
|
+
Integrations API had wrapped a single record, with a spelling that worked either
|
|
220
|
+
way — so nothing recorded which endpoints wrap, and a response in an unexpected
|
|
221
|
+
shape was handed to the caller as the envelope itself and drawn as empty fields.
|
|
222
|
+
They now share `unwrapRecord` and `unwrapList` in `src/runtime/utils/`, which
|
|
223
|
+
carry the service's rule as a table read from its controller bodies: **a
|
|
224
|
+
collection is wrapped in `data`, a single record is bare** — with templates as
|
|
225
|
+
the exception, because there the envelope follows the presenter rather than the
|
|
226
|
+
shape. A record that arrives in neither shape now fails visibly instead of
|
|
227
|
+
rendering blank, and the message a person sees is the page's own copy.
|
|
228
|
+
|
|
229
|
+
No promised behaviour changes. Three routes in the test mock answered a wrapped
|
|
230
|
+
record where the service answers a bare one — one of them contradicting a
|
|
231
|
+
contract this repository had signed a fortnight earlier — and now answer as the
|
|
232
|
+
service does; the envelope question is signed for the templates, workflows and
|
|
233
|
+
runs surfaces in `e2e/support/api-contract.json`.
|
|
234
|
+
|
|
235
|
+
- 2db01ec: A step in a run's timeline opens on what it was handed and what it gave back (PO-421).
|
|
236
|
+
|
|
237
|
+
The **Show payloads** button is gone. It was a fetch switch dressed as a display
|
|
238
|
+
switch: a step opened on an instruction to press it, and pressing it re-read every
|
|
239
|
+
step of the run with its payloads, whether or not the operator went on to open a
|
|
240
|
+
second one. Opening a step now reads them itself, once, and says so while they are
|
|
241
|
+
on their way.
|
|
242
|
+
|
|
243
|
+
What comes back is kept per step scheduling and merged into the reads that keep a
|
|
244
|
+
live run current, so the three-second poll neither blanks an open step nor goes back
|
|
245
|
+
to storage for payloads it already has. A step opened while it was still running is
|
|
246
|
+
read once more when it ends, and only then — the status a payload was read in is
|
|
247
|
+
what decides, so a step that legitimately returned nothing is not re-read on every
|
|
248
|
+
poll, and a read that failed is not retried three seconds later.
|
|
249
|
+
|
|
250
|
+
A failed payload read now leaves the timeline standing and says so inside the open
|
|
251
|
+
step. Before, it shared the read that draws the list of steps, which empties that
|
|
252
|
+
list when it fails.
|
|
253
|
+
|
|
254
|
+
Promised behaviour: `specs/run-detail.md` AC-7, and AC-15 for what an open step keeps
|
|
255
|
+
while its run goes on.
|
|
256
|
+
|
|
257
|
+
- 122659e: An option that stands for no choice can be chosen, and no longer takes the node
|
|
258
|
+
dialog with it (PO-422).
|
|
259
|
+
|
|
260
|
+
A node may offer "no choice" as an entry in a list — the format the file came in as,
|
|
261
|
+
unchanged, all kinds — by declaring an option with an empty value. Three published
|
|
262
|
+
node types do. The control underneath the studio's lists reserves the empty value for
|
|
263
|
+
"nothing selected" and refused the entry outright: the list did not open, and the
|
|
264
|
+
refusal tore down the dialog's dismissal machinery on its way out. From that click
|
|
265
|
+
on, the next list opened anywhere in the form stayed open — Escape and a click
|
|
266
|
+
outside both did nothing — and the only way out was to abandon the dialog with
|
|
267
|
+
everything half set in it.
|
|
268
|
+
|
|
269
|
+
Such an option is now carried through the list under a substitute value and written
|
|
270
|
+
back as the empty string the node reads. It keeps its own label and its place, and it
|
|
271
|
+
is still there once another option has been chosen, so a setting given a value can be
|
|
272
|
+
put back to no choice. A setting the platform is holding as nothing — the empty string
|
|
273
|
+
comes back as null — reads as that option rather than as a placeholder; a setting the
|
|
274
|
+
workflow holds nothing at all for still reads as the placeholder, because no choice
|
|
275
|
+
has been made.
|
|
276
|
+
|
|
277
|
+
- 107db51: Running a run again, above an open run's record, is offered for a run that failed
|
|
278
|
+
(PO-427).
|
|
279
|
+
|
|
280
|
+
It used to be offered for every run that had ended, a successful one included, under
|
|
281
|
+
the word **Retry** — and the press does not repeat that run: it starts a fresh run of
|
|
282
|
+
the workflow as it is saved now, carrying the old run's trigger payload. Over a run
|
|
283
|
+
that had succeeded, that meant doing everything the run already did to the systems at
|
|
284
|
+
the far end, behind a word saying nothing had happened yet. The button now reads **Run
|
|
285
|
+
again**, says in its title what it really runs, and stands over a failed run only. A
|
|
286
|
+
run's own row still offers it whatever the outcome, from behind its actions menu.
|
|
287
|
+
|
|
288
|
+
A press that the platform accepts now leaves the operator looking at the run it
|
|
289
|
+
started, instead of on the run they had just replaced with only a message naming the
|
|
290
|
+
new one. Stepping back returns to the run that failed, so the two can be compared —
|
|
291
|
+
and because the run just started is not over, the button that started it is gone
|
|
292
|
+
rather than standing ready to start a third.
|
|
293
|
+
|
|
294
|
+
Promised behaviour: `specs/run-detail.md` AC-16 and AC-17.
|
|
295
|
+
|
|
296
|
+
- 4a90a4b: A setting inside a list row is drawn as what it declares, and a new row starts from
|
|
297
|
+
what the node declared (PO-436).
|
|
298
|
+
|
|
299
|
+
A node setting that sits inside a repeating row was always drawn as an empty text
|
|
300
|
+
box, whatever its manifest said: the choices it offers, its default, whether it is
|
|
301
|
+
required, the sentence under it. The manifest schema permits all of that on a nested
|
|
302
|
+
setting and the engine reads it — only the form stopped one level short. Each
|
|
303
|
+
sub-setting is now drawn by the same renderer the rest of the form uses, so a
|
|
304
|
+
declared choice arrives as a list of its named options, a boolean as a switch, an
|
|
305
|
+
expression-capable setting as the mapping control, each with its own description and
|
|
306
|
+
required marker. Every control in a row still says which setting and which row it
|
|
307
|
+
belongs to, so a screen reader can still tell two rows apart.
|
|
308
|
+
|
|
309
|
+
The sharper half was the seeding. A new row was created with an empty string under
|
|
310
|
+
every one of its keys, which is a value rather than an absence — so a node's own
|
|
311
|
+
default could not apply, and the one published node with a choice inside its rows
|
|
312
|
+
(Set Fields) stopped every run with `Unknown operation ""` until the author guessed
|
|
313
|
+
one of three words nothing on screen named. A new row now carries each sub-setting's
|
|
314
|
+
declared default and leaves a setting that has none out of the row entirely.
|
|
315
|
+
|
|
316
|
+
One kind of setting is still withheld inside a row: the kind whose options — or
|
|
317
|
+
whose whole set of settings — the platform is asked for while the dialog is open.
|
|
318
|
+
That request carries the values the setting belongs to, and a row is not those
|
|
319
|
+
values. No published node declares one there.
|
|
320
|
+
|
|
321
|
+
**And a row's settings now answer their own conditions.** A node may say that one setting
|
|
322
|
+
in a row means something only under one of another's choices — Set Fields says it about
|
|
323
|
+
the value it writes and about the path it moves a field to. That condition was read by the
|
|
324
|
+
platform when it judged a saved workflow and by nothing on screen, so both boxes stood
|
|
325
|
+
under every action, each explaining in its own small print when it counted.
|
|
326
|
+
|
|
327
|
+
The condition is read against **the row**, which is where the node wrote it and where the
|
|
328
|
+
platform resolves it: two rows of one list show different settings, each according to its
|
|
329
|
+
own choice. And what was typed into a setting a row withdraws goes with it, in that row
|
|
330
|
+
alone — a value nowhere on screen is a value nobody can correct, and it would otherwise be
|
|
331
|
+
saved and read as though the author had meant it.
|
|
332
|
+
|
|
333
|
+
AC-27 and AC-28 gained the clause, and the gap the spec recorded about a row is closed. A
|
|
334
|
+
group is now the one shape left where a declared condition has nothing to hide.
|
|
335
|
+
|
|
336
|
+
- c0d4083: The view a workflow opens on is fitted to the canvas as it actually is (PO-446).
|
|
337
|
+
|
|
338
|
+
`fitView` reads the canvas out of the DOM, and it was being asked before Vue's
|
|
339
|
+
pending changes had been applied — the band above the canvas that points out an
|
|
340
|
+
unconnected error output among them. So the drawing was placed for a canvas a
|
|
341
|
+
frame out of date, and the same workflow opened at two different zooms depending
|
|
342
|
+
on which side of that frame it landed: measured at `scale(0.717)` with the layout
|
|
343
|
+
settled and `scale(0.626)` without.
|
|
344
|
+
|
|
345
|
+
At the smaller zoom the drawing sits far enough to the left that a step — or a
|
|
346
|
+
connection dot on one — can end up behind the node palette, and a card behind a
|
|
347
|
+
panel takes no pointer at all: it can be seen, and clicking it does nothing. The
|
|
348
|
+
opening view is now placed after the layout has settled, so a workflow opens the
|
|
349
|
+
same way every time.
|
|
350
|
+
|
|
351
|
+
What this does not do is stop a panel covering a card where the drawing genuinely
|
|
352
|
+
reaches under one. That is the older question PO-443 left open — the fit knows
|
|
353
|
+
nothing about what floats over the canvas — and it stays open, with what two
|
|
354
|
+
attempted fixes cost measured in PO-446.
|
|
355
|
+
|
|
356
|
+
- 9f155b3: A run's record offers the addresses in its result whole or not at all: every one of
|
|
357
|
+
them where there are at most fifty, none where there are more. It used to offer the
|
|
358
|
+
first eight and drop the rest without saying so. Promised by `specs/run-detail.md`
|
|
359
|
+
AC-19.
|
|
360
|
+
- 6a9a97f: The workflow editor's header survives a long workflow name (PO-461).
|
|
361
|
+
|
|
362
|
+
Beside a name too long for the room, the badge saying how the workflow
|
|
363
|
+
dispatches was cut off mid-word, and the two status texts next to Save — the
|
|
364
|
+
chip reporting a queued build and the unsaved-changes marker — broke onto a
|
|
365
|
+
second line inside boxes one line high, so their text ran over its own border.
|
|
366
|
+
The breadcrumb was laid out inline, so it sized to its content rather than to
|
|
367
|
+
the heading it sits in and nothing in it ever shrank; the two status texts were
|
|
368
|
+
the only items in the actions row not drawn as buttons, and so the only two that
|
|
369
|
+
could wrap. The name is now the only thing in the header that gives way, and it
|
|
370
|
+
gives way as an ellipsis — with the whole of it on the name itself, so pointing
|
|
371
|
+
at a shortened name shows what was cut.
|
|
372
|
+
|
|
373
|
+
The control that folds the studio navigation away is icon-only while the
|
|
374
|
+
navigation is standing, and carries its words again once it is folded — the way
|
|
375
|
+
back is the direction that needs them. Its accessible name is unchanged in both
|
|
376
|
+
directions, so anything addressing it by name is unaffected.
|
|
377
|
+
|
|
378
|
+
- 7bb3a25: Space renames a node on the canvas, which the Keyboard shortcuts list has been
|
|
379
|
+
promising since it existed (PO-472).
|
|
380
|
+
|
|
381
|
+
**Press `Space` on a selected node** and its configuration opens with the name
|
|
382
|
+
selected, exactly as `F2` does. The list under `?` has offered both keys all along,
|
|
383
|
+
and the second of them answered nothing: the library that draws the canvas binds
|
|
384
|
+
Space as a pan key of its own, on the document, and claimed the keystroke before the
|
|
385
|
+
canvas's own bindings were consulted. That pan key is now switched off, and holding
|
|
386
|
+
Space gains rather than loses: with the key claimed, Space over a drag neither panned
|
|
387
|
+
the canvas nor drew the selection rectangle, so the gesture did nothing at all. The
|
|
388
|
+
one thing that changes is Space held over the scroll wheel, which zooms now instead
|
|
389
|
+
of panning, the way the wheel alone already did.
|
|
390
|
+
|
|
391
|
+
**Every key in that list is now pressed by a test.** The test this shipped past
|
|
392
|
+
read the `Space` cap out of the list and never pressed it — and it was not alone:
|
|
393
|
+
of the twenty-six gestures the list offers, ten were proven by a test that pressed
|
|
394
|
+
them and sixteen were not, `Space` among the sixteen. All sixteen have one now, so
|
|
395
|
+
the surface built so that the list and the keyboard could not disagree is checked in
|
|
396
|
+
the direction that matters.
|
|
397
|
+
|
|
398
|
+
Promised behaviour: `specs/canvas-keyboard-shortcuts.md` AC-7.
|
|
399
|
+
|
|
400
|
+
- 3d07d03: Six behaviours the studio already had are now promises with tests behind them
|
|
401
|
+
(PO-475).
|
|
402
|
+
|
|
403
|
+
Nothing ships differently. What changes is what may change silently afterwards:
|
|
404
|
+
each of these was deliberate in the code, visible on screen, and held by no test,
|
|
405
|
+
so any of them could have gone the day somebody touched the surface.
|
|
406
|
+
|
|
407
|
+
- **A credential cannot be saved without a name**, and picking a system fills one
|
|
408
|
+
in so nobody starts from an empty field. Clearing it puts saving out of reach
|
|
409
|
+
again.
|
|
410
|
+
- **A node's mark is the same wherever the node is named in full** — on the canvas,
|
|
411
|
+
in the header of its own configuration, and in a template's drawing of the flow
|
|
412
|
+
it installs.
|
|
413
|
+
- **A node the catalogue marks with nothing is still marked**, with the same
|
|
414
|
+
generic mark every such node gets. Nothing in today's catalogue is in that state,
|
|
415
|
+
so this had never been seen.
|
|
416
|
+
- **A node whose type this installation does not know still opens.** It says it has
|
|
417
|
+
no configuration, and the settings the engine applies around every node are still
|
|
418
|
+
there — which is what makes a workflow with a withdrawn package repairable.
|
|
419
|
+
- **A double-click zooms the run replay and the history preview.** Neither carries
|
|
420
|
+
a zoom control, so it is the only way in; the editor answers the same gesture by
|
|
421
|
+
opening a node, which is why it turns the zoom off and these two do not.
|
|
422
|
+
- **A group folded shut is drawn open on those two surfaces.** A fold is how an
|
|
423
|
+
author makes their own canvas fit; a replay answers which nodes ran.
|
|
424
|
+
|
|
425
|
+
Promised behaviour: `specs/credential-create.md` AC-10, `specs/node-marks.md` AC-5
|
|
426
|
+
and AC-6, `specs/node-configuration.md` AC-32, `specs/readonly-canvases.md` AC-4,
|
|
427
|
+
`specs/group-frames.md` AC-11.
|
|
428
|
+
|
|
429
|
+
## 1.3.0
|
|
430
|
+
|
|
431
|
+
### Minor Changes
|
|
432
|
+
|
|
433
|
+
- 593c0d5: A step can be changed onto another version of its node
|
|
434
|
+
|
|
435
|
+
The editor could say precisely that a step sat on a node version the platform
|
|
436
|
+
cannot run, and name the version that would work — and there it stopped. Getting
|
|
437
|
+
there meant deleting the step and inserting a fresh one, which throws away its
|
|
438
|
+
settings, its name, its note and its connections.
|
|
439
|
+
|
|
440
|
+
The version is now a control wherever there is somewhere to go, and two states
|
|
441
|
+
reach it. Where the pinned version cannot run, the red notice keeps every word it
|
|
442
|
+
had and gains the button it was missing. Where the step runs fine and a newer
|
|
443
|
+
version exists, one grey line in its dialog says so — **and nothing else does**.
|
|
444
|
+
No mark on the canvas card: nothing is wrong there, and a fourth mark for a
|
|
445
|
+
non-problem is what teaches an operator to stop reading marks. A node with a
|
|
446
|
+
single usable version says nothing at all.
|
|
447
|
+
|
|
448
|
+
Older versions are offered too, not only newer ones. A version that turns out to
|
|
449
|
+
behave badly otherwise has no way back.
|
|
450
|
+
|
|
451
|
+
**What the change costs is said before it happens.** The two versions are read
|
|
452
|
+
against the settings the step actually holds, and split three ways: what travels,
|
|
453
|
+
what the chosen version does not have and will be taken out, and what arrives
|
|
454
|
+
needing an eye — a setting it requires and the step has no answer for, or one
|
|
455
|
+
whose type or choices moved. A setting nobody filled in appears nowhere; there is
|
|
456
|
+
nothing to lose. A change that costs nothing says so in a sentence rather than
|
|
457
|
+
showing three empty lists, and where the version being left is no longer in the
|
|
458
|
+
catalogue the answer says the two could not be compared at all.
|
|
459
|
+
|
|
460
|
+
Values the chosen version does not declare are removed rather than left behind.
|
|
461
|
+
The service keeps such a key on save without complaint, so it would otherwise sit
|
|
462
|
+
in the workflow as invisible dead data.
|
|
463
|
+
|
|
464
|
+
Nothing about the step's identity moves: same id, same connections, same name,
|
|
465
|
+
same note, same place on the canvas. It lands as an unsaved change like editing
|
|
466
|
+
any setting, so discarding the editor's changes undoes it.
|
|
467
|
+
|
|
468
|
+
Promised as `specs/node-configuration.md` AC-24 to AC-26. `specs/node-palette.md`
|
|
469
|
+
AC-7 gains the clause that the version it names is somewhere the step can
|
|
470
|
+
actually go, and loses the gap entry that described the dead end.
|
|
471
|
+
|
|
472
|
+
- bb8a80a: Declare what a workflow may remember between runs (PO-374).
|
|
473
|
+
|
|
474
|
+
A new **State** entry in the editor's floating control pane (Shift+T) opens a
|
|
475
|
+
dialog for the blob's `state` block: each namespace with its role — mapping,
|
|
476
|
+
cursor, dedupe or digest — and whether it belongs to this workflow alone or to
|
|
477
|
+
every workflow in the tenant. The engine mints a run's grant from exactly this
|
|
478
|
+
list, so until now a workflow could not reach the state store from the studio at
|
|
479
|
+
all.
|
|
480
|
+
|
|
481
|
+
The role is chosen when the namespace is added and stated as text afterwards:
|
|
482
|
+
entries written with one meaning cannot be read back with another. What sharing
|
|
483
|
+
costs — tenant-wide reads _and_ writes, and a namespace that outlives this
|
|
484
|
+
workflow — is on screen next to the control that chooses it.
|
|
485
|
+
|
|
486
|
+
Also fixes a silent loss in both directions of the workflow mapper, which
|
|
487
|
+
enumerates blob keys one by one: `state` was neither read from the API nor sent
|
|
488
|
+
back on save, so a declaration made anywhere else would have disappeared on the
|
|
489
|
+
next save from the studio.
|
|
490
|
+
|
|
491
|
+
A node setting of the new type `state-ref` picks one of the workflow's declared
|
|
492
|
+
namespaces **of that setting's kind**, and declares a new one from inside the
|
|
493
|
+
picker — the same shape a `credentials-ref` has, so the author never leaves the
|
|
494
|
+
node to type a name that nothing would have compared.
|
|
495
|
+
|
|
496
|
+
A namespace declared inside the picker waits in the node's draft until the
|
|
497
|
+
inspector keeps it — Save, or prev/next — so Esc discards the declaration
|
|
498
|
+
together with the setting that named it, and the workflow does not report
|
|
499
|
+
unsaved changes for something nobody chose to keep.
|
|
500
|
+
|
|
501
|
+
A node's test run now names the workflow being edited, which lets it read that
|
|
502
|
+
workflow's namespaces. Writes stay refused at author time.
|
|
503
|
+
|
|
504
|
+
Promised behaviour: `specs/state-namespaces.md`.
|
|
505
|
+
|
|
506
|
+
- ddff18a: A setting that cannot apply is no longer put in front of the author
|
|
507
|
+
|
|
508
|
+
A node can now say in its manifest when one of its settings applies — another
|
|
509
|
+
setting's key, an operator, and the value to compare against — and the
|
|
510
|
+
configuration form draws it only while that holds. Until now the only thing
|
|
511
|
+
warning an author off a meaningless field was a sentence in small print under
|
|
512
|
+
it, which they read last, having already filled it in. Date Time's **Source**
|
|
513
|
+
is the plainest case: under "Now" it still asked which field to read the date
|
|
514
|
+
out of.
|
|
515
|
+
|
|
516
|
+
What changed on screen:
|
|
517
|
+
|
|
518
|
+
- A setting whose condition does not hold is not drawn, and is not counted
|
|
519
|
+
among the optional ones either — a fold that offers four settings and shows
|
|
520
|
+
three teaches the reader to distrust the number.
|
|
521
|
+
- What was typed into a setting that stops applying is dropped, the same
|
|
522
|
+
cascade the studio already runs for a setting whose options another one
|
|
523
|
+
resolves. A value nowhere on screen is a value nobody can correct.
|
|
524
|
+
- Settings a node resolves while the author edits are treated the same way.
|
|
525
|
+
|
|
526
|
+
The words a condition is written in are the fourteen the condition and filter
|
|
527
|
+
nodes already offer — `equals`, `isEmpty`, `contains`, `>` and the rest — so an
|
|
528
|
+
author who has met them in one place does not learn a second set for the other.
|
|
529
|
+
`specs/node-configuration.md` AC-27 and AC-28 carry the promise.
|
|
530
|
+
|
|
531
|
+
Nothing changes for a node that says nothing: every setting is drawn exactly as
|
|
532
|
+
before. A condition written on a setting _inside a group_ is not honoured here —
|
|
533
|
+
a group is drawn as one value editor rather than as its own settings — and that
|
|
534
|
+
is written into the spec's Gaps rather than left to be discovered.
|
|
535
|
+
|
|
536
|
+
### Patch Changes
|
|
537
|
+
|
|
538
|
+
- 4dd5b12: The answer that keeps unsaved work is legible, and is the one the question emphasises
|
|
539
|
+
|
|
540
|
+
Leaving a workflow with unsaved changes asks whether to discard them, and the
|
|
541
|
+
question offers two answers. Only one of them looked like an answer: "Keep editing"
|
|
542
|
+
was drawn in a colour its own background shares, so it read as an empty button beside
|
|
543
|
+
"Discard and leave" and its label appeared only once the pointer rested on it. Which
|
|
544
|
+
is the wrong half of the dialog to hide — that button is the one the keyboard lands
|
|
545
|
+
on, so the answer the question exists to make easy was the answer nobody could see.
|
|
546
|
+
|
|
547
|
+
It is now drawn as the filled answer, the way every other dialog in the module draws
|
|
548
|
+
the answer on the right, so the question also says which answer it falls back to. The
|
|
549
|
+
cause was two button variants on one element: the dialog's cancel element applies the
|
|
550
|
+
outline variant itself, and the button inside it was left on the default one, so the
|
|
551
|
+
merge took the background from the first and the text colour from the second. Nothing
|
|
552
|
+
else about the question moves — the wording, the keyboard default and what each answer
|
|
553
|
+
does are unchanged.
|
|
554
|
+
|
|
555
|
+
Promised as `specs/workflow-save.md` AC-13 and AC-14: the label is checked as a
|
|
556
|
+
contrast ratio against the button it sits on, unhovered, and the emphasis as a
|
|
557
|
+
difference between the two answers' surfaces rather than against a class name or a
|
|
558
|
+
colour value.
|
|
559
|
+
|
|
560
|
+
- ab2eb96: A build state stops saying "still building" wherever it is shown
|
|
561
|
+
|
|
562
|
+
Saving a workflow queues the platform to build an executable bundle from it, and
|
|
563
|
+
until that build lands the workflow cannot run. Two surfaces say so: the chip beside
|
|
564
|
+
Save in the editor, and the build column in the workflows list. Only the editor's
|
|
565
|
+
ever became true on its own — the list said whatever its last read said, so a
|
|
566
|
+
workflow that finished building while the list stood open kept reading "Building…"
|
|
567
|
+
until something reloaded the page. Save in the editor, come back to the list, and the
|
|
568
|
+
row never moved.
|
|
569
|
+
|
|
570
|
+
The list now watches a build out the way the editor does: one read of the tenant per
|
|
571
|
+
turn, so thirty workflows building at once cost what one costs, and it stops as soon
|
|
572
|
+
as nothing is waiting. A platform build report still makes it quicker where there is
|
|
573
|
+
one; nothing depends on one arriving any more, on either surface.
|
|
574
|
+
|
|
575
|
+
The two waits now share one interval and one ceiling instead of the editor owning
|
|
576
|
+
both, so neither surface can drift into asking twice as often as the other.
|
|
577
|
+
|
|
578
|
+
Promised as `specs/workflow-build.md`, a new spec for the subject: what becomes of a
|
|
579
|
+
saved workflow before it can run. AC-1 is the editor's promise, moved out of
|
|
580
|
+
`specs/workflow-save.md`, where a reader asking what a build state means would not
|
|
581
|
+
have looked; AC-2 is the list's. `specs/realtime-updates.md` AC-7 keeps the
|
|
582
|
+
announcement half and now says which of the two makes a build state true.
|
|
583
|
+
|
|
3
584
|
## 1.2.0
|
|
4
585
|
|
|
5
586
|
### Minor Changes
|
package/dist/module.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:open": (args_0: boolean) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
7
|
+
"onUpdate:open"?: ((args_0: boolean) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@revenexx/studio";
|
|
4
|
+
import { CANVAS_SHORTCUTS, SHORTCUT_GROUPS, SHORTCUT_GROUP_LABELS, shortcutCaps } from "../../data/canvasShortcuts";
|
|
5
|
+
import { formatShortcut } from "../../utils/shortcutLabel";
|
|
6
|
+
defineProps({
|
|
7
|
+
open: { type: Boolean, required: true }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["update:open"]);
|
|
10
|
+
const t = useIntegrationsT();
|
|
11
|
+
const groups = computed(() => SHORTCUT_GROUPS.map((group) => ({
|
|
12
|
+
group,
|
|
13
|
+
label: t(SHORTCUT_GROUP_LABELS[group]),
|
|
14
|
+
items: CANVAS_SHORTCUTS.filter((s) => s.group === group).map((s) => ({
|
|
15
|
+
id: s.id,
|
|
16
|
+
label: t(s.labelKey),
|
|
17
|
+
// One cap per gesture, in the platform's own alphabet.
|
|
18
|
+
caps: shortcutCaps(s.id).map((k) => formatShortcut(k))
|
|
19
|
+
}))
|
|
20
|
+
})).filter((g) => g.items.length > 0));
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<Dialog :open="open" @update:open="(v) => emit('update:open', v)">
|
|
25
|
+
<DialogContent class="max-w-[94vw] sm:max-w-2xl">
|
|
26
|
+
<DialogHeader>
|
|
27
|
+
<DialogTitle>{{ t("integration.canvas.shortcuts.dialog.title") }}</DialogTitle>
|
|
28
|
+
<DialogDescription class="text-sm">
|
|
29
|
+
{{ t("integration.canvas.shortcuts.dialog.description") }}
|
|
30
|
+
</DialogDescription>
|
|
31
|
+
</DialogHeader>
|
|
32
|
+
|
|
33
|
+
<div class="grid max-h-[70vh] gap-x-8 gap-y-5 overflow-y-auto sm:grid-cols-2">
|
|
34
|
+
<section v-for="g in groups" :key="g.group" class="min-w-0">
|
|
35
|
+
<h3 class="mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
|
|
36
|
+
{{ g.label }}
|
|
37
|
+
</h3>
|
|
38
|
+
<ul class="space-y-1">
|
|
39
|
+
<li v-for="item in g.items" :key="item.id" class="flex items-baseline justify-between gap-3 text-sm">
|
|
40
|
+
<span class="min-w-0 truncate">{{ item.label }}</span>
|
|
41
|
+
<span class="flex shrink-0 items-baseline gap-1">
|
|
42
|
+
<template v-for="(cap, i) in item.caps" :key="cap">
|
|
43
|
+
<span v-if="i > 0" class="text-xs text-muted-foreground">{{ t("integration.canvas.shortcuts.or") }}</span>
|
|
44
|
+
<kbd class="rounded border border-black/[0.08] bg-slate-50 px-1.5 py-0.5 text-xs tabular-nums text-foreground">{{ cap }}</kbd>
|
|
45
|
+
</template>
|
|
46
|
+
</span>
|
|
47
|
+
</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</section>
|
|
50
|
+
</div>
|
|
51
|
+
</DialogContent>
|
|
52
|
+
</Dialog>
|
|
53
|
+
</template>
|