style(webui): refine UI polish and enhance component interactions

This commit is contained in:
Wha1eChai
2026-01-09 07:54:50 +08:00
parent 40a766ded6
commit e909ea6fe3
13 changed files with 808 additions and 253 deletions

View File

@@ -5,6 +5,36 @@
window.Components = window.Components || {};
window.Components.accountManager = () => ({
searchQuery: '',
deleteTarget: '',
get filteredAccounts() {
const accounts = Alpine.store('data').accounts || [];
if (!this.searchQuery || this.searchQuery.trim() === '') {
return accounts;
}
const query = this.searchQuery.toLowerCase().trim();
return accounts.filter(acc => {
return acc.email.toLowerCase().includes(query) ||
(acc.projectId && acc.projectId.toLowerCase().includes(query)) ||
(acc.source && acc.source.toLowerCase().includes(query));
});
},
formatEmail(email) {
if (!email || email.length <= 40) return email;
const [user, domain] = email.split('@');
if (!domain) return email;
// Preserve domain integrity, truncate username if needed
if (user.length > 20) {
return `${user.substring(0, 10)}...${user.slice(-5)}@${domain}`;
}
return email;
},
async refreshAccount(email) {
const store = Alpine.store('global');
store.showToast(store.t('refreshingAccount', { email }), 'info');
@@ -88,10 +118,16 @@ window.Components.accountManager = () => ({
}
},
async deleteAccount(email) {
confirmDeleteAccount(email) {
this.deleteTarget = email;
document.getElementById('delete_account_modal').showModal();
},
async executeDelete() {
const email = this.deleteTarget;
const store = Alpine.store('global');
if (!confirm(store.t('confirmDelete'))) return;
const password = store.webuiPassword;
try {
const { response, newPassword } = await window.utils.request(`/api/accounts/${encodeURIComponent(email)}`, { method: 'DELETE' }, password);
if (newPassword) store.webuiPassword = newPassword;
@@ -100,6 +136,8 @@ window.Components.accountManager = () => ({
if (data.status === 'ok') {
store.showToast(store.t('deletedAccount', { email }), 'success');
Alpine.store('data').fetchData();
document.getElementById('delete_account_modal').close();
this.deleteTarget = '';
} else {
store.showToast(data.error || store.t('deleteFailed'), 'error');
}

View File

@@ -464,7 +464,9 @@ window.Components.dashboard = () => ({
createDataset(label, data, color, ctx) {
const gradient = ctx.getContext('2d').createLinearGradient(0, 0, 0, 200);
gradient.addColorStop(0, this.hexToRgba(color, 0.3));
// Reduced opacity from 0.3 to 0.12 for less visual noise
gradient.addColorStop(0, this.hexToRgba(color, 0.12));
gradient.addColorStop(0.6, this.hexToRgba(color, 0.05));
gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
return {
@@ -472,12 +474,14 @@ window.Components.dashboard = () => ({
data,
borderColor: color,
backgroundColor: gradient,
borderWidth: 2,
tension: 0.4,
borderWidth: 2.5, // Slightly thicker line for better visibility
tension: 0.35, // Smoother curves
fill: true,
pointRadius: 3,
pointHoverRadius: 5,
pointBackgroundColor: color
pointRadius: 2.5,
pointHoverRadius: 6,
pointBackgroundColor: color,
pointBorderColor: 'rgba(9, 9, 11, 0.8)',
pointBorderWidth: 1.5
};
},

View File

@@ -18,15 +18,28 @@ window.Components.logsViewer = () => ({
},
get filteredLogs() {
const query = this.searchQuery.toLowerCase();
const query = this.searchQuery.trim();
if (!query) {
return this.logs.filter(log => this.filters[log.level]);
}
// Try regex first, fallback to plain text search
let matcher;
try {
const regex = new RegExp(query, 'i');
matcher = (msg) => regex.test(msg);
} catch (e) {
// Invalid regex, fallback to case-insensitive string search
const lowerQuery = query.toLowerCase();
matcher = (msg) => msg.toLowerCase().includes(lowerQuery);
}
return this.logs.filter(log => {
// Level Filter
if (!this.filters[log.level]) return false;
// Search Filter
if (query && !log.message.toLowerCase().includes(query)) return false;
return true;
return matcher(log.message);
});
},