@@ -26,9 +26,8 @@ import Button from './Components/Button.js';
26
26
* @param operation_id If provided, is saved in the data-operation-id attribute, for later lookup.
27
27
* @param show_progress Enable a progress bar, and display `(foo%)` after the status message
28
28
* @param on_cancel A callback run when the Cancel button is clicked. Without it, no Cancel button will appear.
29
- * @returns {Promise<{set_progress: *, set_status: *, close: *, element: Element}> } Object for managing the progress dialog
29
+ * @returns {Promise<{set_progress: *, set_status: *, close: *, show_error: *, element: Element}> } Object for managing the progress dialog
30
30
* @constructor
31
- * TODO: Error display
32
31
* TODO: Debouncing logic (show only after a delay, then hide only after a delay)
33
32
*/
34
33
async function UIWindowProgress ( {
@@ -37,30 +36,47 @@ async function UIWindowProgress({
37
36
on_cancel = null ,
38
37
} = { } ) {
39
38
const placeholder_cancel_btn = Placeholder ( ) ;
39
+ const placeholder_ok_btn = Placeholder ( ) ;
40
40
41
41
let h = '' ;
42
42
h += `<div ${ operation_id ? `data-operation-id="${ operation_id } "` : '' } >` ;
43
- h += `<div style="display: flex; align-items: center;">` ;
44
- // spinner
45
- h += `<svg style="margin-right: 7px; overflow: visible;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>` ;
46
- // Progress report
47
- h += `<div style="font-size:15px; overflow: hidden; flex-grow: 1; text-overflow: ellipsis; white-space: nowrap;">
48
- <span class="progress-msg">${ i18n ( 'preparing' ) } </span>` ;
43
+ h += `<div class="progress-running">` ;
44
+ h += `<div style="display: flex; align-items: center; gap: 7px;">` ;
45
+ // spinner
46
+ h += `<svg style="overflow: visible;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>` ;
47
+ // Progress report
48
+ h += `<div style="font-size:15px; overflow: hidden; flex-grow: 1; text-overflow: ellipsis; white-space: nowrap;">
49
+ <span class="progress-msg">${ i18n ( 'preparing' ) } </span>` ;
50
+ if ( show_progress ) {
51
+ h += ` (<span class="progress-percent">0%</span>)` ;
52
+ }
53
+ h += `</div>` ;
54
+ h += `</div>` ;
49
55
if ( show_progress ) {
50
- h += ` (<span class="progress-percent">0%</span>)` ;
56
+ h += `<div class="progress-bar-container" style="margin-top:20px;">` ;
57
+ h += `<div class="progress-bar"></div>` ;
58
+ h += `</div>` ;
51
59
}
60
+ if ( on_cancel ) {
61
+ h += `<div style="display: flex; justify-content: flex-end;">` ;
62
+ h += placeholder_cancel_btn . html ;
63
+ h += `</div>` ;
64
+ }
65
+ h += `</div>` ;
66
+ h += `<div class="progress-error" style="display: none">` ;
67
+ h += `<div style="display: flex; align-items: center; gap: 7px;">` ;
68
+ // Alert icon
69
+ h += `<img style="width:24px; height:24px;" src="${ html_encode ( window . icons [ 'warning-sign.svg' ] ) } " />` ;
70
+ // Progress report
71
+ h += `<div style="font-size:15px; overflow: hidden; flex-grow: 1; text-overflow: ellipsis; white-space: nowrap;">
72
+ <span class="progress-error-title"></span>` ;
73
+ h += `</div>` ;
52
74
h += `</div>` ;
53
- h += `</div>` ;
54
- if ( show_progress ) {
55
- h += `<div class="progress-bar-container" style="margin-top:20px;">` ;
56
- h += `<div class="progress-bar"></div>` ;
57
- h += `</div>` ;
58
- }
59
- if ( on_cancel ) {
75
+ h += `<p class="progress-error-message"></p>` ;
60
76
h += `<div style="display: flex; justify-content: flex-end;">` ;
61
- h += placeholder_cancel_btn . html ;
77
+ h += placeholder_ok_btn . html ;
62
78
h += `</div>` ;
63
- }
79
+ h += `</div>` ;
64
80
h += `</div>` ;
65
81
66
82
const el_window = await UIWindow ( {
@@ -106,6 +122,15 @@ async function UIWindowProgress({
106
122
cancel_btn . attach ( placeholder_cancel_btn ) ;
107
123
}
108
124
125
+ const ok_btn = new Button ( {
126
+ label : i18n ( 'ok' ) ,
127
+ style : 'small' ,
128
+ on_click : ( ) => {
129
+ $ ( el_window ) . close ( ) ;
130
+ } ,
131
+ } ) ;
132
+ ok_btn . attach ( placeholder_ok_btn ) ;
133
+
109
134
return {
110
135
element : el_window ,
111
136
set_status : ( text ) => {
@@ -118,7 +143,12 @@ async function UIWindowProgress({
118
143
close : ( ) => {
119
144
$ ( el_window ) . close ( ) ;
120
145
} ,
121
- // TODO: show_error(), which replaces the window content with a title, error message, and OK button
146
+ show_error : ( title , message ) => {
147
+ el_window . querySelector ( '.progress-running' ) . style . display = 'none' ;
148
+ el_window . querySelector ( '.progress-error' ) . style . display = 'block' ;
149
+ el_window . querySelector ( '.progress-error-title' ) . innerText = title ;
150
+ el_window . querySelector ( '.progress-error-message' ) . innerText = message ;
151
+ } ,
122
152
} ;
123
153
}
124
154
0 commit comments