Files
argparser/static/js/app.js
2025-10-10 18:13:54 +02:00

235 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class ArgumentBuilder {
constructor() {
this.arguments = [];
this.container = document.getElementById('arguments-container');
this.headerInput = document.getElementById('custom-header');
this.generateBtn = document.getElementById('generate-btn');
this.helpContent = document.getElementById('help-content');
this.outputSection = document.getElementById('output-section');
this.generatedCode = document.getElementById('generated-code');
this.copyBtn = document.getElementById('copy-btn');
this.init();
}
init() {
// Add initial empty row
this.addArgumentRow();
// Event listeners
this.generateBtn.addEventListener('click', () => this.generateScript());
this.headerInput.addEventListener('input', () => this.updateHelpPreview());
this.copyBtn.addEventListener('click', () => this.copyToClipboard());
// Update help preview initially
this.updateHelpPreview();
}
addArgumentRow(params = '', command = '', helpText = '') {
const row = document.createElement('div');
row.className = 'argument-row';
const paramsInput = document.createElement('input');
paramsInput.type = 'text';
paramsInput.placeholder = '-v --verbose';
paramsInput.value = params;
const commandInput = document.createElement('input');
commandInput.type = 'text';
commandInput.placeholder = 'verbose';
commandInput.value = command;
const helpTextInput = document.createElement('input');
helpTextInput.type = 'text';
helpTextInput.placeholder = 'Enable verbose output';
helpTextInput.value = helpText;
const removeBtn = document.createElement('button');
removeBtn.className = 'remove-btn';
removeBtn.innerHTML = '×';
removeBtn.addEventListener('click', () => {
row.remove();
this.updateHelpPreview();
});
// Add input event listeners for real-time updates
const updatePreview = () => {
this.updateHelpPreview();
// Add new empty row if this is the last row and has content
const rows = this.container.querySelectorAll('.argument-row');
const isLastRow = rows[rows.length - 1] === row;
const hasContent = commandInput.value.trim() !== '';
if (isLastRow && hasContent) {
this.addArgumentRow();
}
};
paramsInput.addEventListener('input', updatePreview);
commandInput.addEventListener('input', updatePreview);
helpTextInput.addEventListener('input', updatePreview);
row.appendChild(paramsInput);
row.appendChild(commandInput);
row.appendChild(helpTextInput);
row.appendChild(removeBtn);
this.container.appendChild(row);
}
getArguments() {
const rows = this.container.querySelectorAll('.argument-row');
const args = [];
rows.forEach(row => {
const inputs = row.querySelectorAll('input');
const params = inputs[0].value.trim();
const command = inputs[1].value.trim();
const helpText = inputs[2].value.trim();
if (command) {
args.push({
params: params || command,
command: command,
helpText: helpText || command
});
}
});
return args;
}
addSubcommand(name = '', description = '') {
const subcommandSection = document.createElement('div');
subcommandSection.className = 'subcommand-section';
const header = this.createSubcommandHeader(name, description);
const argsContainer = this.createArgumentsContainer();
subcommandSection.appendChild(header);
subcommandSection.appendChild(argsContainer);
this.subcommandContainer.appendChild(subcommandSection);
return subcommandSection;
}
updateHelpPreview() {
const header = this.headerInput.value.trim();
const args = this.getArguments();
if (args.length === 0) {
this.helpContent.textContent = 'Add arguments to see the help output...';
return;
}
let helpText = '';
if (header) {
helpText += header + '\n\n';
}
helpText += 'Usage: script.sh [OPTIONS]\n\n';
helpText += 'Options:\n';
args.forEach(arg => {
const params = arg.params || arg.command;
const help = arg.helpText || arg.command;
helpText += ` ${params.padEnd(20)} ${help}\n`;
});
helpText += ` ${'-h --help'.padEnd(20)} Show this help message\n`;
this.helpContent.textContent = helpText;
}
createSubcommandHeader(name, description) {
const header = document.createElement('div');
header.className = 'subcommand-header';
header.innerHTML = `
<input type="text" class="subcommand-name"
placeholder="container" value="${name}">
<input type="text" class="subcommand-desc"
placeholder="Manage containers" value="${description}">
<button class="toggle-btn">▼</button>
<button class="remove-btn">×</button>
`;
return header;
}
getSubcommands() {
const sections = this.subcommandContainer.querySelectorAll('.subcommand-section');
return Array.from(sections).map(section => {
const nameInput = section.querySelector('.subcommand-name');
const descInput = section.querySelector('.subcommand-desc');
const args = this.getArgumentsFromSection(section);
return {
name: nameInput.value.trim(),
description: descInput.value.trim(),
arguments: args
};
}).filter(sc => sc.name);
}
async generateScript() {
const header = this.headerInput.value.trim();
const args = this.getArguments();
if (args.length === 0) {
alert('Please add at least one argument');
return;
}
const payload = {
header: this.headerInput.value.trim(),
arguments: this.getArguments(),
subcommands: this.getSubcommands()
};
try {
const response = await fetch('/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error('Failed to generate script');
}
const scriptCode = await response.text();
this.generatedCode.textContent = scriptCode;
this.outputSection.style.display = 'block';
// Smooth scroll to output
this.outputSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} catch (error) {
alert('Error generating script: ' + error.message);
}
}
async copyToClipboard() {
const code = this.generatedCode.textContent;
try {
await navigator.clipboard.writeText(code);
this.copyBtn.textContent = 'Copied!';
this.copyBtn.classList.add('copied');
setTimeout(() => {
this.copyBtn.textContent = 'Copy';
this.copyBtn.classList.remove('copied');
}, 2000);
} catch (error) {
alert('Failed to copy to clipboard');
}
}
}
// Initialize the application when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
new ArgumentBuilder();
});