]>
Commit | Line | Data |
---|---|---|
ee93ce96 DM |
1 | Ext.define('PVE.window.Wizard', { |
2 | extend: 'Ext.window.Window', | |
f677074b DM |
3 | |
4 | activeTitle: '', // used for automated testing | |
bd2118c6 | 5 | |
d738b11e | 6 | width: 720, |
3632a029 | 7 | height: 540, |
bd2118c6 TL |
8 | |
9 | modal: true, | |
10 | border: false, | |
11 | ||
12 | draggable: true, | |
13 | closable: true, | |
14 | resizable: false, | |
15 | ||
16 | layout: 'border', | |
17 | ||
ee93ce96 | 18 | getValues: function(dirtyOnly) { |
b18a3d9f | 19 | let me = this; |
ee93ce96 | 20 | |
b18a3d9f | 21 | let values = {}; |
ee93ce96 | 22 | |
b18a3d9f TL |
23 | me.down('form').getForm().getFields().each(field => { |
24 | if (!field.up('inputpanel') && (!dirtyOnly || field.isDirty())) { | |
25 | Proxmox.Utils.assemble_field_data(values, field.getSubmitData()); | |
26 | } | |
27 | }); | |
ee93ce96 | 28 | |
b18a3d9f | 29 | me.query('inputpanel').forEach(panel => { |
e7ade592 | 30 | Proxmox.Utils.assemble_field_data(values, panel.getValues(dirtyOnly)); |
ee93ce96 DM |
31 | }); |
32 | ||
33 | return values; | |
34 | }, | |
35 | ||
36 | initComponent: function() { | |
37 | var me = this; | |
38 | ||
39 | var tabs = me.items || []; | |
40 | delete me.items; | |
2a4971d8 TL |
41 | |
42 | /* | |
ee93ce96 DM |
43 | * Items may have the following functions: |
44 | * validator(): per tab custom validation | |
45 | * onSubmit(): submit handler | |
46 | * onGetValues(): overwrite getValues results | |
47 | */ | |
48 | ||
49 | Ext.Array.each(tabs, function(tab) { | |
50 | tab.disabled = true; | |
51 | }); | |
52 | tabs[0].disabled = false; | |
53 | ||
3fb9e6f9 | 54 | let maxidx = 0, curidx = 0; |
373d7ea4 | 55 | |
3fb9e6f9 TL |
56 | let check_card = function(card) { |
57 | let fields = card.query('field, fieldcontainer'); | |
ee93ce96 DM |
58 | if (card.isXType('fieldcontainer')) { |
59 | fields.unshift(card); | |
60 | } | |
3fb9e6f9 TL |
61 | let valid = true; |
62 | for (const field of fields) { | |
ee93ce96 DM |
63 | // Note: not all fielcontainer have isValid() |
64 | if (Ext.isFunction(field.isValid) && !field.isValid()) { | |
65 | valid = false; | |
66 | } | |
3fb9e6f9 | 67 | } |
ee93ce96 DM |
68 | if (Ext.isFunction(card.validator)) { |
69 | return card.validator(); | |
70 | } | |
ee93ce96 DM |
71 | return valid; |
72 | }; | |
73 | ||
3fb9e6f9 TL |
74 | let disableTab = function(card) { |
75 | let tp = me.down('#wizcontent'); | |
76 | for (let idx = tp.items.indexOf(card); idx < tp.items.getCount(); idx++) { | |
77 | let tab = tp.items.getAt(idx); | |
78 | if (tab) { | |
79 | tab.disable(); | |
ee93ce96 DM |
80 | } |
81 | } | |
82 | }; | |
83 | ||
3fb9e6f9 | 84 | let tabchange = function(tp, newcard, oldcard) { |
ee93ce96 DM |
85 | if (newcard.onSubmit) { |
86 | me.down('#next').setVisible(false); | |
2a4971d8 | 87 | me.down('#submit').setVisible(true); |
ee93ce96 DM |
88 | } else { |
89 | me.down('#next').setVisible(true); | |
2a4971d8 | 90 | me.down('#submit').setVisible(false); |
ee93ce96 | 91 | } |
3fb9e6f9 | 92 | let valid = check_card(newcard); |
2a4971d8 TL |
93 | me.down('#next').setDisabled(!valid); |
94 | me.down('#submit').setDisabled(!valid); | |
3fb9e6f9 | 95 | me.down('#back').setDisabled(tp.items.indexOf(newcard) === 0); |
ee93ce96 | 96 | |
3fb9e6f9 | 97 | let idx = tp.items.indexOf(newcard); |
373d7ea4 DC |
98 | if (idx > maxidx) { |
99 | maxidx = idx; | |
100 | } | |
101 | curidx = idx; | |
102 | ||
3fb9e6f9 | 103 | let ntab = tp.items.getAt(idx + 1); |
ee93ce96 DM |
104 | if (valid && ntab && !newcard.onSubmit) { |
105 | ntab.enable(); | |
106 | } | |
107 | }; | |
108 | ||
109 | if (me.subject && !me.title) { | |
e7ade592 | 110 | me.title = Proxmox.Utils.dialog_title(me.subject, true, false); |
ee93ce96 DM |
111 | } |
112 | ||
3fb9e6f9 TL |
113 | let sp = Ext.state.Manager.getProvider(); |
114 | let advancedOn = sp.get('proxmox-advanced-cb'); | |
3e0ea404 | 115 | |
60575f19 | 116 | Ext.apply(me, { |
ee93ce96 | 117 | items: [ |
ee93ce96 DM |
118 | { |
119 | xtype: 'form', | |
120 | region: 'center', | |
121 | layout: 'fit', | |
122 | border: false, | |
123 | margins: '5 5 0 5', | |
124 | fieldDefaults: { | |
125 | labelWidth: 100, | |
f6710aac | 126 | anchor: '100%', |
ee93ce96 DM |
127 | }, |
128 | items: [{ | |
129 | itemId: 'wizcontent', | |
130 | xtype: 'tabpanel', | |
131 | activeItem: 0, | |
74c0b9a9 | 132 | bodyPadding: 0, |
ee93ce96 DM |
133 | listeners: { |
134 | afterrender: function(tp) { | |
3fb9e6f9 | 135 | tabchange(tp, this.getActiveTab()); |
ee93ce96 DM |
136 | }, |
137 | tabchange: function(tp, newcard, oldcard) { | |
ee93ce96 | 138 | tabchange(tp, newcard, oldcard); |
f6710aac | 139 | }, |
ee93ce96 | 140 | }, |
74c0b9a9 DC |
141 | defaults: { |
142 | padding: 10, | |
143 | }, | |
f6710aac TL |
144 | items: tabs, |
145 | }], | |
146 | }, | |
18f4718f TL |
147 | ], |
148 | fbar: [ | |
149 | { | |
150 | xtype: 'proxmoxHelpButton', | |
f6710aac | 151 | itemId: 'help', |
18f4718f TL |
152 | }, |
153 | '->', | |
3e0ea404 DC |
154 | { |
155 | xtype: 'proxmoxcheckbox', | |
156 | boxLabelAlign: 'before', | |
157 | boxLabel: gettext('Advanced'), | |
3fb9e6f9 | 158 | value: advancedOn, |
3e0ea404 | 159 | listeners: { |
3fb9e6f9 TL |
160 | change: function(_, value) { |
161 | let tp = me.down('#wizcontent'); | |
3e0ea404 | 162 | tp.query('inputpanel').forEach(function(ip) { |
3fb9e6f9 | 163 | ip.setAdvancedVisible(value); |
3e0ea404 | 164 | }); |
3fb9e6f9 | 165 | sp.set('proxmox-advanced-cb', value); |
f6710aac TL |
166 | }, |
167 | }, | |
3e0ea404 | 168 | }, |
18f4718f TL |
169 | { |
170 | text: gettext('Back'), | |
171 | disabled: true, | |
172 | itemId: 'back', | |
173 | minWidth: 60, | |
174 | handler: function() { | |
3fb9e6f9 TL |
175 | let tp = me.down('#wizcontent'); |
176 | let prev = tp.items.indexOf(tp.getActiveTab()) - 1; | |
18f4718f TL |
177 | if (prev < 0) { |
178 | return; | |
179 | } | |
3fb9e6f9 | 180 | let ntab = tp.items.getAt(prev); |
18f4718f TL |
181 | if (ntab) { |
182 | tp.setActiveTab(ntab); | |
183 | } | |
f6710aac | 184 | }, |
18f4718f TL |
185 | }, |
186 | { | |
187 | text: gettext('Next'), | |
188 | disabled: true, | |
189 | itemId: 'next', | |
190 | minWidth: 60, | |
191 | handler: function() { | |
3fb9e6f9 TL |
192 | let tp = me.down('#wizcontent'); |
193 | let activeTab = tp.getActiveTab(); | |
194 | if (!check_card(activeTab)) { | |
18f4718f TL |
195 | return; |
196 | } | |
3fb9e6f9 TL |
197 | let next = tp.items.indexOf(activeTab) + 1; |
198 | let ntab = tp.items.getAt(next); | |
18f4718f TL |
199 | if (ntab) { |
200 | ntab.enable(); | |
201 | tp.setActiveTab(ntab); | |
202 | } | |
f6710aac | 203 | }, |
ee93ce96 | 204 | }, |
18f4718f TL |
205 | { |
206 | text: gettext('Finish'), | |
207 | minWidth: 60, | |
208 | hidden: true, | |
209 | itemId: 'submit', | |
210 | handler: function() { | |
3fb9e6f9 TL |
211 | let tp = me.down('#wizcontent'); |
212 | tp.getActiveTab().onSubmit(); | |
f6710aac TL |
213 | }, |
214 | }, | |
215 | ], | |
ee93ce96 DM |
216 | }); |
217 | me.callParent(); | |
ee93ce96 | 218 | |
3e0ea404 | 219 | Ext.Array.each(me.query('inputpanel'), function(panel) { |
3fb9e6f9 | 220 | panel.setAdvancedVisible(advancedOn); |
3e0ea404 DC |
221 | }); |
222 | ||
ee93ce96 | 223 | Ext.Array.each(me.query('field'), function(field) { |
3fb9e6f9 TL |
224 | let validcheck = function() { |
225 | let tp = me.down('#wizcontent'); | |
373d7ea4 | 226 | |
3fb9e6f9 TL |
227 | // check validity for current to last enabled tab, as local change may affect validity of a later one |
228 | for (let i = curidx; i <= maxidx && i < tp.items.getCount(); i++) { | |
229 | let tab = tp.items.getAt(i); | |
230 | let valid = check_card(tab); | |
373d7ea4 DC |
231 | |
232 | // only set the buttons on the current panel | |
233 | if (i === curidx) { | |
234 | me.down('#next').setDisabled(!valid); | |
235 | me.down('#submit').setDisabled(!valid); | |
236 | } | |
3fb9e6f9 TL |
237 | // if a panel is invalid, then disable all following, else enable the next tab |
238 | let nextTab = tp.items.getAt(i + 1); | |
373d7ea4 | 239 | if (!valid) { |
3fb9e6f9 | 240 | disableTab(nextTab); |
373d7ea4 | 241 | return; |
3fb9e6f9 TL |
242 | } else if (nextTab && !tab.onSubmit) { |
243 | nextTab.enable(); | |
373d7ea4 | 244 | } |
ee93ce96 | 245 | } |
a1304e1e DC |
246 | }; |
247 | field.on('change', validcheck); | |
248 | field.on('validitychange', validcheck); | |
ee93ce96 | 249 | }); |
f6710aac | 250 | }, |
ee93ce96 | 251 | }); |