use toastFrontend for error msgs in plugins
Alessandro committed
Mar 11, 2026 at 13:01 UTC
a9722e70fd62591800e5ca8bdf0fc4cc373bf3e3
6 files changed
+12
-96
plugins/_plugin_installer/webui/install-detail.html
-19
@@ -148,10 +148,6 @@
148
</template>
149
</div>
150
151
- <div x-show="$store.pluginInstallStore.error" class="pi-message pi-message-error">
152
- <span x-text="$store.pluginInstallStore.error"></span>
153
- </div>
154
-
151
<div class="pi-readme-section" x-show="$store.pluginInstallStore.readmeContent || $store.pluginInstallStore.readmeLoading">
152
<div class="pi-readme-header">Readme</div>
153
<div x-show="$store.pluginInstallStore.readmeLoading" class="pi-loading-text">
@@ -466,21 +462,6 @@
462
padding: 0.75rem 0;
463
}
464
469
- .pi-message {
470
- display: flex;
471
- align-items: center;
472
- gap: 0.75rem;
473
- padding: 1rem;
474
- border-radius: 8px;
475
- margin-bottom: 1rem;
476
- }
477
-
478
- .pi-message-error {
479
- background: rgba(239,68,68,0.1);
480
- border: 1px solid rgba(239,68,68,0.3);
481
- color: var(--color-error);
482
- }
483
-
465
.pi-screenshots-section {
466
margin: var(--spacing-lg) 0;
467
padding-top: var(--spacing-lg);
plugins/_plugin_installer/webui/install-git.html
-12
@@ -45,10 +45,6 @@
45
</button>
46
</div>
47
48
- <div x-show="$store.pluginInstallStore.error" class="pi-error">
49
- <span x-text="$store.pluginInstallStore.error"></span>
50
- </div>
51
-
48
<div x-show="$store.pluginInstallStore.result" class="pi-result">
49
<div class="pi-result-icon">
50
<span class="material-symbols-outlined">check_circle</span>
@@ -109,14 +105,6 @@
105
gap: 0.5rem;
106
}
107
112
- .pi-error {
113
- color: var(--color-error);
114
- padding: 0.75rem;
115
- background: var(--color-error-bg, rgba(239,68,68,0.1));
116
- border-radius: 4px;
117
- margin-top: 0.75rem;
118
- }
119
-
108
.pi-result {
109
display: flex;
110
align-items: center;
plugins/_plugin_installer/webui/install-index.html
-14
@@ -62,14 +62,6 @@
62
</div>
63
</div>
64
65
- <div x-show="$store.pluginInstallStore.error && !$store.pluginInstallStore.loading" class="pi-state-card pi-state-error">
66
- <span class="material-symbols-outlined">error</span>
67
- <div>
68
- <div class="pi-state-title">Marketplace unavailable</div>
69
- <div class="pi-state-text" x-text="$store.pluginInstallStore.error"></div>
70
- </div>
71
- </div>
72
-
65
<div x-show="$store.pluginInstallStore.index && !$store.pluginInstallStore.loading && $store.pluginInstallStore.filteredPlugins.length > 0"
66
class="pi-grid">
67
<template x-for="plugin in $store.pluginInstallStore.paginatedPlugins" :key="plugin.key">
@@ -343,12 +335,6 @@
335
color: var(--color-highlight);
336
}
337
346
- .pi-state-error {
347
- border-color: rgba(239, 68, 68, 0.28);
348
- background: rgba(239, 68, 68, 0.1);
349
- color: var(--color-error);
350
- }
351
-
338
.pi-state-empty .material-symbols-outlined {
339
color: var(--color-text-muted);
340
}
plugins/_plugin_installer/webui/install-zip.html
-12
@@ -35,10 +35,6 @@
35
<span x-text="$store.pluginInstallStore.loadingMessage || 'Processing...'"></span>
36
</div>
37
38
- <div x-show="$store.pluginInstallStore.error" class="pi-error">
39
- <span x-text="$store.pluginInstallStore.error"></span>
40
- </div>
41
-
38
<div x-show="$store.pluginInstallStore.result" class="pi-result">
39
<div class="pi-result-icon">
40
<span class="material-symbols-outlined">check_circle</span>
@@ -94,14 +90,6 @@
90
color: var(--color-text-secondary);
91
}
92
97
- .pi-error {
98
- color: var(--color-error);
99
- padding: 0.75rem;
100
- background: var(--color-error-bg, rgba(239,68,68,0.1));
101
- border-radius: 4px;
102
- margin-top: 0.75rem;
103
- }
104
-
93
.pi-result {
94
display: flex;
95
align-items: center;
plugins/_plugin_installer/webui/main.html
-15
@@ -421,13 +421,6 @@
421
color: var(--color-highlight);
422
}
423
424
- .pi-state-error {
425
- border-color: rgba(239, 68, 68, 0.28);
426
- background: rgba(239, 68, 68, 0.1);
427
- color: var(--color-error);
428
- margin-top: 0;
429
- }
430
-
424
.pi-state-empty .material-symbols-outlined {
425
color: var(--color-text-muted);
426
}
@@ -541,14 +534,6 @@
534
color: var(--color-text-secondary);
535
}
536
544
- .pi-error {
545
- color: var(--color-error);
546
- padding: 0.75rem;
547
- background: var(--color-error-bg, rgba(239, 68, 68, 0.1));
548
- border-radius: 4px;
549
- margin-top: 0.75rem;
550
- }
551
-
537
.pi-empty {
538
text-align: center;
539
padding: 2rem;
plugins/_plugin_installer/webui/pluginInstallStore.js
+12
-24
@@ -2,7 +2,7 @@ import { createStore } from "/js/AlpineStore.js";
2
import * as api from "/js/api.js";
3
import { openModal } from "/js/modals.js";
4
import { marked } from "/vendor/marked/marked.esm.js";
5
-import { toastFrontendSuccess } from "/components/notifications/notification-store.js";
5
+import { toastFrontendSuccess, toastFrontendError } from "/components/notifications/notification-store.js";
6
import { showConfirmDialog } from "/js/confirmDialog.js";
7
import { store as imageViewerStore } from "/components/modals/image-viewer/image-viewer-store.js";
8
import { store as pluginListStore } from "/components/plugins/list/pluginListStore.js";
@@ -48,7 +48,6 @@ const model = {
48
// Shared state
49
loading: false,
50
loadingMessage: "",
51
- error: "",
51
result: null,
52
53
// README state
@@ -65,7 +64,6 @@ const model = {
64
65
setTab(tab) {
66
this.activeTab = tab;
68
- this.error = "";
67
this.result = null;
68
},
69
@@ -113,13 +111,12 @@ const model = {
111
if (!file) return;
112
this.zipFile = file;
113
this.zipFileName = file.name;
116
- this.error = "";
114
this.result = null;
115
},
116
117
async installZip() {
118
if (!this.zipFile) {
122
- this.error = "Please select a ZIP file first";
119
+ void toastFrontendError("Please select a ZIP file first", "Plugin Installer");
120
return;
121
}
122
@@ -129,7 +126,6 @@ const model = {
126
try {
127
this.loading = true;
128
this.loadingMessage = "Installing plugin from ZIP...";
132
- this.error = "";
129
this.result = null;
130
131
const formData = new FormData();
@@ -143,7 +139,7 @@ const model = {
139
140
const data = await response.json();
141
if (!data.success) {
146
- this.error = data.error || "Installation failed";
142
+ void toastFrontendError(data.error || "Installation failed", "Plugin Installer");
143
return;
144
}
145
@@ -155,7 +151,7 @@ const model = {
151
);
152
} catch (e) {
153
const message = e instanceof Error ? e.message : String(e);
158
- this.error = `Installation error: ${message}`;
154
+ void toastFrontendError(`Installation error: ${message}`, "Plugin Installer");
155
} finally {
156
this.loading = false;
157
this.loadingMessage = "";
@@ -167,7 +163,7 @@ const model = {
163
async installGit() {
164
const url = (this.gitUrl || "").trim();
165
if (!url) {
170
- this.error = "Please enter a Git URL";
166
+ void toastFrontendError("Please enter a Git URL", "Plugin Installer");
167
return;
168
}
169
@@ -177,7 +173,6 @@ const model = {
173
try {
174
this.loading = true;
175
this.loadingMessage = "Cloning repository...";
180
- this.error = "";
176
this.result = null;
177
178
const data = await api.callJsonApi(PLUGIN_API, {
@@ -187,7 +182,7 @@ const model = {
182
});
183
184
if (!data.success) {
190
- this.error = data.error || "Clone failed";
185
+ void toastFrontendError(data.error || "Clone failed", "Plugin Installer");
186
return;
187
}
188
@@ -199,7 +194,7 @@ const model = {
194
);
195
} catch (e) {
196
const message = e instanceof Error ? e.message : String(e);
202
- this.error = `Clone error: ${message}`;
197
+ void toastFrontendError(`Clone error: ${message}`, "Plugin Installer");
198
} finally {
199
this.loading = false;
200
this.loadingMessage = "";
@@ -212,15 +207,13 @@ const model = {
207
try {
208
this.loading = true;
209
this.loadingMessage = "Loading plugin index...";
215
- this.error = "";
216
- // this.index = null;
210
211
const data = await api.callJsonApi(PLUGIN_API, {
212
action: "fetch_index",
213
});
214
215
if (!data.success) {
223
- this.error = data.error || "Failed to load index";
216
+ void toastFrontendError(data.error || "Failed to load index", "Plugin Installer");
217
return;
218
}
219
@@ -229,7 +222,7 @@ const model = {
222
this.page = 1;
223
} catch (e) {
224
const message = e instanceof Error ? e.message : String(e);
232
- this.error = `Failed to load plugin index: ${message}`;
225
+ void toastFrontendError(`Failed to load plugin index: ${message}`, "Plugin Installer");
226
} finally {
227
this.loading = false;
228
this.loadingMessage = "";
@@ -343,7 +336,6 @@ const model = {
336
337
openDetail(plugin) {
338
this.selectedPlugin = { ...plugin, name: plugin?.key || "" };
346
- this.error = "";
339
this.result = null;
340
this.installedPluginInfo = null;
341
this.readmeContent = null;
@@ -387,7 +379,7 @@ const model = {
379
380
async installFromIndex(plugin) {
381
if (!plugin?.github) {
390
- this.error = "No GitHub URL available for this plugin";
382
+ void toastFrontendError("No GitHub URL available for this plugin", "Plugin Installer");
383
return;
384
}
385
@@ -406,7 +398,6 @@ const model = {
398
try {
399
this.loading = true;
400
this.loadingMessage = `Installing ${plugin.title || plugin.key}...`;
409
- this.error = "";
401
402
const data = await api.callJsonApi(PLUGIN_API, {
403
action: "install_git",
@@ -415,7 +406,7 @@ const model = {
406
});
407
408
if (!data.success) {
418
- this.error = data.error || "Installation failed";
409
+ void toastFrontendError(data.error || "Installation failed", "Plugin Installer");
410
return;
411
}
412
@@ -438,7 +429,7 @@ const model = {
429
);
430
} catch (e) {
431
const message = e instanceof Error ? e.message : String(e);
441
- this.error = `Installation error: ${message}`;
432
+ void toastFrontendError(`Installation error: ${message}`, "Plugin Installer");
433
} finally {
434
this.loading = false;
435
this.loadingMessage = "";
@@ -533,14 +524,12 @@ const model = {
524
resetZip() {
525
this.zipFile = null;
526
this.zipFileName = "";
536
- this.error = "";
527
this.result = null;
528
},
529
530
resetGit() {
531
this.gitUrl = "";
532
this.gitToken = "";
543
- this.error = "";
533
this.result = null;
534
},
535
@@ -549,7 +538,6 @@ const model = {
538
this.page = 1;
539
this.sortBy = "stars";
540
this.browseFilter = "all";
552
- this.error = "";
541
this.result = null;
542
this.selectedPlugin = null;
543
},