Makros: GET/POST-Anfragen mit JSON-Ergebnis und FOR-Iteration
Erweitert die Makro-Sprache um Netzwerkzugriff: "x = GET(url)"/ "x = POST(url; body)" binden die geparste JSON-Antwort an eine Variable; FOR item IN x DO ... END iteriert, wenn x ein JSON-Array ist, über dessen Elemente; JSONGET(wert; pfad) liest ein Feld heraus (punktgetrennt, Zahl = Array-Index) und funktioniert – anders als GET/POST – überall in einem Ausdruck verschachtelt, nicht nur als ganze Zuweisung. Da ein echter Netzwerkaufruf nicht synchron laufen kann, ohne den Tab einzufrieren, bekommt der Makro-Interpreter einen separaten asynchronen Zweig (execBlockAsync/execStatementAsync); der bestehende synchrone Interpreter, den auch gewöhnliche "Mit Schleife"-Funktionen mitten in der synchronen Neuberechnung nutzen, bleibt unangetastet. Netzwerkaufrufe werden pro Makro einmalig mit Zielname bestätigt (dauerhaft gemerkt); die bestehende "ein Lauf = ein Undo-Schritt"-Garantie, die bislang auf Synchronität beruhte, wird jetzt explizit wiederhergestellt statt sich weiter auf die Zeit-Koaleszenz zu verlassen. Zwei echte Lücken erst beim eigenen Live-Test gefunden und behoben: (1) JSONGET direkt in eine Aktion verschachtelt (statt erst einer Variable zugewiesen) scheiterte zunächst an #NAME?; (2) JSONGET(...) direkt als FOR-Quelle (ohne Zwischenvariable) scheiterte sowohl an der Speicher-Zeit-Prüfung als auch zur Laufzeit, da substitute() einen Funktionsaufruf nie auswertet. Live gegen eine neue same-origin-Fixture (public/test-fixtures/sample.json) verifiziert: echter GET, echter Bestätigungsdialog, FOR/JSONGET über die echte Antwort, kein erneuter Dialog beim zweiten Lauf. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* own right-click menu, for a quicker "build a button, wire it up, done"
|
||||
* loop without leaving the canvas.
|
||||
*/
|
||||
import { computed, reactive } from 'vue';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { useDocument } from '../store/document';
|
||||
import { useToasts } from '../composables/useToasts';
|
||||
import ContextMenu from './ContextMenu.vue';
|
||||
@@ -21,16 +21,26 @@ const obj = computed(() => {
|
||||
return o && o.kind === 'button' ? o : undefined;
|
||||
});
|
||||
|
||||
function run() {
|
||||
// A macro can now involve a real network round-trip (GET/POST) and even a
|
||||
// blocking confirm() prompt -- guard against a second click starting a
|
||||
// second overlapping run while one is still in flight.
|
||||
const running = ref(false);
|
||||
|
||||
async function run() {
|
||||
const o = obj.value;
|
||||
if (!o) return;
|
||||
if (!o || running.value) return;
|
||||
if (!o.macroId || !store.doc.macros.some((m) => m.id === o.macroId)) {
|
||||
toasts.info('Diesem Button ist noch kein Makro zugewiesen — per Rechtsklick oder im Inspektor.');
|
||||
return;
|
||||
}
|
||||
const result = store.runMacro(o.macroId);
|
||||
if (result.ok) toasts.success(result.message);
|
||||
else toasts.error(result.message);
|
||||
running.value = true;
|
||||
try {
|
||||
const result = await store.runMacro(o.macroId);
|
||||
if (result.ok) toasts.success(result.message);
|
||||
else toasts.error(result.message);
|
||||
} finally {
|
||||
running.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const boxStyle = computed(() => {
|
||||
@@ -77,11 +87,12 @@ const menuItems = computed(() => {
|
||||
<div
|
||||
v-if="obj"
|
||||
class="btnbox"
|
||||
:class="{ running }"
|
||||
:style="boxStyle"
|
||||
@click="run"
|
||||
@contextmenu="onContextMenu"
|
||||
>
|
||||
<span class="label">{{ obj.label || 'Button' }}</span>
|
||||
<span class="label">{{ running ? '…' : obj.label || 'Button' }}</span>
|
||||
<ContextMenu v-model:open="menu.open" :x="menu.x" :y="menu.y" :items="menuItems" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -100,6 +111,10 @@ const menuItems = computed(() => {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.btnbox.running {
|
||||
opacity: 0.6;
|
||||
cursor: default;
|
||||
}
|
||||
.btnbox:hover {
|
||||
filter: brightness(1.06);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user