Skip to content

Commit 1c8f35e

Browse files
committed
Add execute API sequence feature
1 parent bedf740 commit 1c8f35e

File tree

1 file changed

+108
-2
lines changed

1 file changed

+108
-2
lines changed

app.js

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ class AsanaAPIExplorer {
12201220
this.updatePatStatus('', '');
12211221
this.savePATToStorage();
12221222
this.renderEndpoints(); // Re-render to update execute buttons
1223+
this.updateExecuteButtonStatus(); // Update sequence execute button
12231224
});
12241225

12251226
// Toggle PAT visibility
@@ -1521,6 +1522,7 @@ class AsanaAPIExplorer {
15211522
}
15221523
this.updatePatStatus('PAT cleared from storage', 'info');
15231524
this.renderEndpoints();
1525+
this.updateExecuteButtonStatus(); // Update sequence execute button
15241526
} catch (error) {
15251527
console.warn('Failed to clear PAT from localStorage:', error);
15261528
}
@@ -1969,12 +1971,51 @@ ${responseHeaders}</div>
19691971

19701972
container.innerHTML = sequenceHTML;
19711973

1974+
// Update execute button status
1975+
this.updateExecuteButtonStatus();
1976+
19721977
// Restore parameter values to form fields after rendering
19731978
setTimeout(() => {
19741979
this.restoreParametersToForms();
19751980
}, 50);
19761981
}
19771982

1983+
updateExecuteButtonStatus() {
1984+
const executeBtn = document.querySelector('button[onclick="explorer.executeSequence()"]');
1985+
if (!executeBtn) return;
1986+
1987+
const hasVariableMappings = this.apiSequence.some(item =>
1988+
item.variableMappings && Object.keys(item.variableMappings).length > 0
1989+
);
1990+
1991+
const hasToken = !!this.personalAccessToken;
1992+
const hasSequence = this.apiSequence.length > 0;
1993+
1994+
if (hasSequence && hasToken) {
1995+
executeBtn.disabled = false;
1996+
if (hasVariableMappings) {
1997+
executeBtn.innerHTML = '🚀 Execute All (Ready)';
1998+
executeBtn.className = 'sequence-btn sequence-btn-success';
1999+
executeBtn.style.background = '#28a745';
2000+
executeBtn.style.borderColor = '#28a745';
2001+
} else {
2002+
executeBtn.innerHTML = '▶ Execute All';
2003+
executeBtn.className = 'sequence-btn sequence-btn-success';
2004+
executeBtn.style.background = '';
2005+
executeBtn.style.borderColor = '';
2006+
}
2007+
} else {
2008+
executeBtn.disabled = true;
2009+
if (!hasToken) {
2010+
executeBtn.innerHTML = '🔑 Set PAT to Execute';
2011+
executeBtn.className = 'sequence-btn sequence-btn-warning';
2012+
} else {
2013+
executeBtn.innerHTML = '▶ Execute All';
2014+
executeBtn.className = 'sequence-btn sequence-btn-success';
2015+
}
2016+
}
2017+
}
2018+
19782019
getAvailableVariables(currentIndex) {
19792020
const variables = [];
19802021

@@ -3097,19 +3138,67 @@ Status: ${item.error ? 'ERROR' : 'SUCCESS'}
30973138
}
30983139

30993140
async executeSequence() {
3141+
if (this.apiSequence.length === 0) {
3142+
alert('No endpoints in sequence to execute.');
3143+
return;
3144+
}
3145+
3146+
if (!this.personalAccessToken) {
3147+
alert('Personal Access Token is required to execute the sequence.');
3148+
return;
3149+
}
3150+
3151+
console.log('🚀 Starting full sequence execution...');
3152+
3153+
// Show progress indication
3154+
const executeBtn = document.querySelector('button[onclick="explorer.executeSequence()"]');
3155+
const originalText = executeBtn.innerHTML;
3156+
31003157
for (let i = 0; i < this.apiSequence.length; i++) {
31013158
const item = this.apiSequence[i];
3159+
3160+
// Update button to show progress
3161+
executeBtn.innerHTML = `⏳ Executing ${i + 1}/${this.apiSequence.length}`;
3162+
executeBtn.disabled = true;
3163+
3164+
console.log(`📡 Executing step ${i + 1}: ${item.endpoint.method} ${item.endpoint.path}`);
3165+
31023166
try {
31033167
await this.executeSequenceItem(item.id);
3168+
31043169
if (item.error) {
3105-
console.error(`Sequence stopped at step ${i + 1} due to error:`, item.error);
3170+
console.error(`❌ Sequence stopped at step ${i + 1} due to error:`, item.error);
3171+
alert(`Sequence execution stopped at step ${i + 1} due to an error. Check the console for details.`);
31063172
break;
31073173
}
3174+
3175+
console.log(`✅ Step ${i + 1} completed successfully`);
3176+
3177+
// Add a small delay between calls to be respectful to the API
3178+
if (i < this.apiSequence.length - 1) {
3179+
await new Promise(resolve => setTimeout(resolve, 500));
3180+
}
3181+
31083182
} catch (error) {
3109-
console.error(`Sequence stopped at step ${i + 1}:`, error);
3183+
console.error(`❌ Sequence stopped at step ${i + 1}:`, error);
3184+
alert(`Sequence execution failed at step ${i + 1}: ${error.message}`);
31103185
break;
31113186
}
31123187
}
3188+
3189+
// Restore button
3190+
executeBtn.innerHTML = originalText;
3191+
executeBtn.disabled = false;
3192+
3193+
console.log('🏁 Sequence execution completed');
3194+
3195+
// Check if all items completed successfully
3196+
const completedItems = this.apiSequence.filter(item => item.executed && !item.error);
3197+
if (completedItems.length === this.apiSequence.length) {
3198+
console.log(`🎉 All ${completedItems.length} steps completed successfully!`);
3199+
} else {
3200+
console.log(`⚠️ Sequence completed with ${completedItems.length}/${this.apiSequence.length} successful steps`);
3201+
}
31133202
}
31143203

31153204
async executeSequenceItem(itemId) {
@@ -3414,6 +3503,23 @@ Status: ${item.error ? 'ERROR' : 'SUCCESS'}
34143503
this.toggleSequencePanel();
34153504
}
34163505

3506+
// Check if sequence has variable mappings and suggest execution
3507+
const hasVariableMappings = this.apiSequence.some(item =>
3508+
item.variableMappings && Object.keys(item.variableMappings).length > 0
3509+
);
3510+
3511+
if (hasVariableMappings && this.personalAccessToken) {
3512+
setTimeout(() => {
3513+
if (confirm('This sequence has variable mappings configured. Would you like to execute the full sequence now?')) {
3514+
this.executeSequence();
3515+
}
3516+
}, 1000);
3517+
} else if (hasVariableMappings && !this.personalAccessToken) {
3518+
setTimeout(() => {
3519+
alert('This sequence has variable mappings configured. Set your Personal Access Token to execute the full sequence.');
3520+
}, 1000);
3521+
}
3522+
34173523
// Restore parameter values to form fields after a short delay
34183524
setTimeout(() => {
34193525
this.restoreParametersToForms();

0 commit comments

Comments
 (0)