feat(ui): patterns list and create form layout
Made-with: Cursor
This commit is contained in:
@@ -55,8 +55,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
if (mode === 'create') {
|
||||
if (labelEl) {
|
||||
labelEl.textContent = '';
|
||||
labelEl.style.display = 'none';
|
||||
labelEl.textContent = `${key}:`;
|
||||
labelEl.style.display = '';
|
||||
}
|
||||
if (inputEl) {
|
||||
inputEl.value = '';
|
||||
@@ -203,6 +203,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/** on/off are implemented in driver firmware (presets.py), not as OTA ``.py`` files. */
|
||||
const FIRMWARE_BUILTIN_PATTERNS = new Set(['on', 'off']);
|
||||
|
||||
const isFirmwareBuiltinPattern = (patternName) => {
|
||||
const id = String(patternName || '')
|
||||
.trim()
|
||||
.replace(/\.py$/i, '')
|
||||
.toLowerCase();
|
||||
return FIRMWARE_BUILTIN_PATTERNS.has(id);
|
||||
};
|
||||
|
||||
const sendPatternToDevices = async (patternName) => {
|
||||
const response = await fetch(`/patterns/${encodeURIComponent(patternName)}/send`, {
|
||||
method: 'POST',
|
||||
@@ -281,7 +292,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/patterns/ota/file/${encodeURIComponent(patternName)}.py`, {
|
||||
const raw = String(patternName || '').trim();
|
||||
const fileSegment = /\.py$/i.test(raw) ? raw : `${raw}.py`;
|
||||
const response = await fetch(`/patterns/ota/file/${encodeURIComponent(fileSegment)}`, {
|
||||
headers: { Accept: 'text/plain' },
|
||||
});
|
||||
if (!response.ok) {
|
||||
@@ -315,39 +328,41 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const label = document.createElement('span');
|
||||
label.textContent = patternName;
|
||||
|
||||
const details = document.createElement('span');
|
||||
const minDelay = data && data.min_delay !== undefined ? data.min_delay : '-';
|
||||
const maxDelay = data && data.max_delay !== undefined ? data.max_delay : '-';
|
||||
details.textContent = `${minDelay}–${maxDelay} ms`;
|
||||
details.style.color = '#aaa';
|
||||
details.style.fontSize = '0.85em';
|
||||
|
||||
const sendBtn = document.createElement('button');
|
||||
sendBtn.className = 'btn btn-primary btn-small';
|
||||
sendBtn.textContent = 'Send';
|
||||
sendBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
await sendPatternToDevices(patternName);
|
||||
} catch (error) {
|
||||
console.error('Send pattern failed:', error);
|
||||
alert(error.message || 'Failed to send pattern.');
|
||||
}
|
||||
});
|
||||
|
||||
const editBtn = document.createElement('button');
|
||||
editBtn.className = 'btn btn-secondary btn-small';
|
||||
editBtn.textContent = 'Edit';
|
||||
editBtn.addEventListener('click', async () => {
|
||||
if (patternEditorModal) {
|
||||
patternEditorModal.classList.add('active');
|
||||
}
|
||||
await loadPatternIntoEditor(patternName, data || {});
|
||||
});
|
||||
|
||||
row.appendChild(label);
|
||||
row.appendChild(details);
|
||||
row.appendChild(editBtn);
|
||||
row.appendChild(sendBtn);
|
||||
|
||||
if (isFirmwareBuiltinPattern(patternName)) {
|
||||
const note = document.createElement('span');
|
||||
note.className = 'muted-text';
|
||||
note.style.fontSize = '0.85em';
|
||||
note.textContent = 'Built-in (no OTA module)';
|
||||
row.appendChild(note);
|
||||
} else {
|
||||
const sendBtn = document.createElement('button');
|
||||
sendBtn.className = 'btn btn-primary btn-small';
|
||||
sendBtn.textContent = 'Send';
|
||||
sendBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
await sendPatternToDevices(patternName);
|
||||
} catch (error) {
|
||||
console.error('Send pattern failed:', error);
|
||||
alert(error.message || 'Failed to send pattern.');
|
||||
}
|
||||
});
|
||||
|
||||
const editBtn = document.createElement('button');
|
||||
editBtn.className = 'btn btn-secondary btn-small';
|
||||
editBtn.textContent = 'Edit';
|
||||
editBtn.addEventListener('click', async () => {
|
||||
if (patternEditorModal) {
|
||||
patternEditorModal.classList.add('active');
|
||||
}
|
||||
await loadPatternIntoEditor(patternName, data || {});
|
||||
});
|
||||
|
||||
row.appendChild(editBtn);
|
||||
row.appendChild(sendBtn);
|
||||
}
|
||||
|
||||
patternsList.appendChild(row);
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user