Repair gateway workspace event wiring

This commit is contained in:
Jeppe Bundgaard
2026-04-22 18:31:50 +02:00
parent c3381aea39
commit 8391557f2d
2 changed files with 112 additions and 10 deletions
@@ -87,6 +87,8 @@ const fleetFilter = ref("ALL");
const fleetUsage = ref(createEmptyFleetUsage());
const rotateBundle = ref(null);
const editableBindings = ref([]);
const selectedOperationId = ref(null);
const updateTargetVersion = ref("");
const loading = ref({
init: false,
detail: false,
@@ -302,6 +304,11 @@ const view = (gateway) => {
};
const selectedGatewayView = computed(() => view(selectedGateway.value));
const selectedOperation = computed(() => {
const operations = Array.isArray(selectedGatewayView.value?.operations) ? selectedGatewayView.value.operations : [];
return operations.find((operation) => String(operation.id) === String(selectedOperationId.value)) || null;
});
const selectedOperationEvents = computed(() => selectedOperation.value?.events || []);
const summaryCards = computed(() => {
const rows = gateways.value.map(view).filter(Boolean);
@@ -385,6 +392,29 @@ const syncDrafts = (gateway) => {
}));
};
const syncSelectedOperation = (gateway) => {
const operations = Array.isArray(gateway?.operations) ? gateway.operations : [];
if (!operations.length) {
selectedOperationId.value = null;
return;
}
const currentSelection = operations.find((operation) => String(operation.id) === String(selectedOperationId.value)) || null;
if (currentSelection) {
selectedOperationId.value = String(currentSelection.id);
return;
}
const preferredOperation =
operations.find((operation) => ["PENDING", "IN_PROGRESS", "CANCEL_REQUESTED"].includes(String(operation.status || ""))) ||
operations[0];
selectedOperationId.value = preferredOperation ? String(preferredOperation.id) : null;
};
const selectOperation = (operation) => {
selectedOperationId.value = operation?.id ? String(operation.id) : null;
};
const clearError = () => {
errorState.value = null;
};
@@ -507,6 +537,7 @@ const clearSelection = () => {
selectedGateway.value = null;
activeGatewayId.value = null;
unavailableGatewayId.value = null;
selectedOperationId.value = null;
};
const setSelectedGatewaySnapshot = (gateway) => {
@@ -519,6 +550,7 @@ const setSelectedGatewaySnapshot = (gateway) => {
activeGatewayId.value = String(mergedGateway.id);
unavailableGatewayId.value = null;
syncDrafts(mergedGateway);
syncSelectedOperation(mergedGateway);
return mergedGateway;
};
@@ -862,10 +894,14 @@ const queueOperation = async ({ type, request }) => {
loading.value.operation = true;
try {
const response = await createEdgeGatewayOperation(selectedGateway.value.id, type, request || {});
const operation = unwrap(response, null)?.operation || response?.data?.data?.operation || null;
const gateway = unwrap(response, null)?.gateway || response?.data?.data?.gateway || null;
if (gateway) {
setSelectedGatewaySnapshot(gateway);
}
if (operation?.id) {
selectedOperationId.value = String(operation.id);
}
flashMessage.value = `Gateway operation ${type} queued.`;
clearError();
} catch (error) {
@@ -880,10 +916,14 @@ const cancelOperation = async (operation) => {
loading.value.operationCancel = true;
try {
const response = await cancelEdgeGatewayOperation(selectedGateway.value.id, operation.id);
const updatedOperation = response?.data?.data?.operation || null;
const gateway = unwrap(response, null)?.gateway || response?.data?.data?.gateway || null;
if (gateway) {
setSelectedGatewaySnapshot(gateway);
}
if (updatedOperation?.id) {
selectedOperationId.value = String(updatedOperation.id);
}
flashMessage.value =
String(response?.data?.data?.operation?.status || "") === "CANCEL_REQUESTED"
? `Cancellation requested for ${operation.type}.`
@@ -915,6 +955,48 @@ const queueDiscovery = async () => {
}
};
const queueUpdate = async () => {
const targetVersion = String(updateTargetVersion.value || "").trim();
if (!targetVersion) {
flashMessage.value = "Target version is required.";
return;
}
await queueOperation({
type: "UPDATE",
request: {
target_version: targetVersion,
release_channel: "stable",
},
});
};
const queueUninstall = async () => {
await queueOperation({ type: "UNINSTALL", request: {} });
};
const retryOperation = async (operation) => {
if (!operation?.type) {
return;
}
const request =
operation.type === "UPDATE"
? {
target_version:
String(operation?.request?.target_version || updateTargetVersion.value || selectedGateway.value?.target_version || "").trim(),
release_channel: String(operation?.request?.release_channel || "stable"),
}
: operation?.request || {};
if (operation.type === "UPDATE" && !request.target_version) {
flashMessage.value = "Target version is required.";
return;
}
await queueOperation({ type: operation.type, request });
};
const addBindingRow = () =>
editableBindings.value.push({ relay_id: "", device_id: "", local_ip: "", channel: 0, fallback_mode: "PREFER_LOCAL" });
@@ -1284,11 +1366,9 @@ onUnmounted(() => {
<EdgeGatewayInventoryPage
v-else-if="currentView === 'inventory'"
:gateway="selectedGatewayView"
:editable-bindings="editableBindings"
:loading-discovery="loading.discovery || loading.operation"
:loading-bindings="loading.bindings"
:can-edit="true"
@queue-discovery="queueDiscovery"
:bindings="editableBindings"
:busy="loading.discovery || loading.operation || loading.bindings"
@trigger-discovery="queueDiscovery"
@add-binding="addBindingRow"
@remove-binding="removeBindingRow"
@update-binding="updateBinding"
@@ -1297,12 +1377,19 @@ onUnmounted(() => {
<EdgeGatewayOperationsPage
v-else-if="currentView === 'operations'"
:gateway="selectedGatewayView"
:operations="selectedGatewayView.operations || []"
:selected-operation-id="selectedOperationId"
:operation-events="selectedOperationEvents"
:busy="loading.operation || loading.operationCancel"
:allow-destructive="allowDestructive"
:loading-create="loading.operation"
:loading-cancel="loading.operationCancel"
@run-operation="queueOperation"
:update-target-version="updateTargetVersion"
@queue-discovery="queueDiscovery"
@queue-update="queueUpdate"
@queue-uninstall="queueUninstall"
@cancel-operation="cancelOperation"
@retry-operation="retryOperation"
@select-operation="selectOperation"
@update-target-version="updateTargetVersion = $event"
/>
<EdgeGatewayManagePage
@@ -232,7 +232,22 @@ const getStripeHostedInvoiceStatusKey = () => {
};
const getStripeHostedInvoiceStatusLabel = () => {
return t(`admin.pos.stripe.email.states.${getStripeHostedInvoiceStatusKey()}`);
switch (getStripeHostedInvoiceStatusKey()) {
case 'open':
return t('admin.pos.stripe.email.states.open');
case 'paid':
return t('admin.pos.stripe.email.states.paid');
case 'void':
return t('admin.pos.stripe.email.states.void');
case 'uncollectible':
return t('admin.pos.stripe.email.states.uncollectible');
case 'deleted':
return t('admin.pos.stripe.email.states.deleted');
case 'draft':
return t('admin.pos.stripe.email.states.draft');
default:
return t('admin.pos.stripe.email.states.unknown');
}
};
const getStripeHostedInvoiceStatusToneClass = () => {