Simplify LuCI interface from 5 tabs to 2: - Dashboard: status, controls, apps list, upload (all-in-one) - Settings: configuration options Remove complex custom CSS, use standard LuCI styles. Deleted: overview.js, apps.js, instances.js, logs.js Added: dashboard.js (single-page dashboard) Updated: settings.js (simplified form), menu.json Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
149 lines
5.1 KiB
JavaScript
149 lines
5.1 KiB
JavaScript
'use strict';
|
|
'require view';
|
|
'require ui';
|
|
'require streamlit.api as api';
|
|
|
|
return view.extend({
|
|
config: {},
|
|
|
|
load: function() {
|
|
return api.getConfig().then(function(c) {
|
|
return c || {};
|
|
});
|
|
},
|
|
|
|
render: function(config) {
|
|
var self = this;
|
|
this.config = config;
|
|
var main = config.main || {};
|
|
var server = config.server || {};
|
|
|
|
return E('div', { 'class': 'cbi-map' }, [
|
|
E('h2', {}, _('Streamlit Settings')),
|
|
|
|
// Main Settings
|
|
E('div', { 'class': 'cbi-section' }, [
|
|
E('h3', {}, _('Service')),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Enabled')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('select', { 'id': 'cfg-enabled', 'class': 'cbi-input-select' }, [
|
|
E('option', { 'value': '1', 'selected': main.enabled == '1' || main.enabled === true }, _('Yes')),
|
|
E('option', { 'value': '0', 'selected': main.enabled == '0' || main.enabled === false }, _('No'))
|
|
])
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('HTTP Port')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('input', { 'type': 'number', 'id': 'cfg-port', 'class': 'cbi-input-text',
|
|
'value': main.http_port || '8501', 'min': '1024', 'max': '65535' })
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Listen Address')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('input', { 'type': 'text', 'id': 'cfg-host', 'class': 'cbi-input-text',
|
|
'value': main.http_host || '0.0.0.0' })
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Data Path')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('input', { 'type': 'text', 'id': 'cfg-path', 'class': 'cbi-input-text',
|
|
'value': main.data_path || '/srv/streamlit' })
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Memory Limit')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('select', { 'id': 'cfg-memory', 'class': 'cbi-input-select' }, [
|
|
E('option', { 'value': '512M', 'selected': main.memory_limit === '512M' }, '512 MB'),
|
|
E('option', { 'value': '1G', 'selected': main.memory_limit === '1G' }, '1 GB'),
|
|
E('option', { 'value': '2G', 'selected': main.memory_limit === '2G' || !main.memory_limit }, '2 GB'),
|
|
E('option', { 'value': '4G', 'selected': main.memory_limit === '4G' }, '4 GB')
|
|
])
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Active App')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('input', { 'type': 'text', 'id': 'cfg-app', 'class': 'cbi-input-text',
|
|
'value': main.active_app || 'hello' })
|
|
)
|
|
])
|
|
]),
|
|
|
|
// Server Settings
|
|
E('div', { 'class': 'cbi-section' }, [
|
|
E('h3', {}, _('Server Options')),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Headless')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('select', { 'id': 'cfg-headless', 'class': 'cbi-input-select' }, [
|
|
E('option', { 'value': 'true', 'selected': server.headless !== 'false' }, _('Yes')),
|
|
E('option', { 'value': 'false', 'selected': server.headless === 'false' }, _('No'))
|
|
])
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Theme')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('select', { 'id': 'cfg-theme', 'class': 'cbi-input-select' }, [
|
|
E('option', { 'value': 'dark', 'selected': server.theme_base !== 'light' }, _('Dark')),
|
|
E('option', { 'value': 'light', 'selected': server.theme_base === 'light' }, _('Light'))
|
|
])
|
|
)
|
|
]),
|
|
|
|
E('div', { 'class': 'cbi-value' }, [
|
|
E('label', { 'class': 'cbi-value-title' }, _('Primary Color')),
|
|
E('div', { 'class': 'cbi-value-field' },
|
|
E('input', { 'type': 'text', 'id': 'cfg-color', 'class': 'cbi-input-text',
|
|
'value': server.theme_primary_color || '#0ff', 'placeholder': '#0ff' })
|
|
)
|
|
])
|
|
]),
|
|
|
|
// Save button
|
|
E('div', { 'class': 'cbi-page-actions' }, [
|
|
E('button', {
|
|
'class': 'cbi-button cbi-button-positive',
|
|
'click': function() { self.save(); }
|
|
}, _('Save & Apply'))
|
|
])
|
|
]);
|
|
},
|
|
|
|
save: function() {
|
|
var cfg = {
|
|
enabled: document.getElementById('cfg-enabled').value,
|
|
http_port: document.getElementById('cfg-port').value,
|
|
http_host: document.getElementById('cfg-host').value,
|
|
data_path: document.getElementById('cfg-path').value,
|
|
memory_limit: document.getElementById('cfg-memory').value,
|
|
active_app: document.getElementById('cfg-app').value,
|
|
headless: document.getElementById('cfg-headless').value,
|
|
browser_gather_usage_stats: 'false',
|
|
theme_base: document.getElementById('cfg-theme').value,
|
|
theme_primary_color: document.getElementById('cfg-color').value
|
|
};
|
|
|
|
api.saveConfig(cfg).then(function(r) {
|
|
if (r && r.success) {
|
|
ui.addNotification(null, E('p', {}, _('Settings saved')), 'info');
|
|
} else {
|
|
ui.addNotification(null, E('p', {}, r.message || _('Save failed')), 'error');
|
|
}
|
|
});
|
|
}
|
|
});
|