]>
Commit | Line | Data |
---|---|---|
f44ce595 DC |
1 | Ext.define('PVE.dc.RealmSyncJobView', { |
2 | extend: 'Ext.grid.Panel', | |
3 | alias: 'widget.pveRealmSyncJobView', | |
4 | ||
5 | stateful: true, | |
6 | stateId: 'grid-realmsyncjobs', | |
7 | ||
8 | controller: { | |
9 | xclass: 'Ext.app.ViewController', | |
10 | ||
11 | addRealmSyncJob: function(button) { | |
12 | let me = this; | |
13 | Ext.create(`PVE.dc.RealmSyncJobEdit`, { | |
14 | autoShow: true, | |
15 | listeners: { | |
16 | destroy: () => me.reload(), | |
17 | }, | |
18 | }); | |
19 | }, | |
20 | ||
21 | editRealmSyncJob: function() { | |
22 | let me = this; | |
23 | let view = me.getView(); | |
24 | let selection = view.getSelection(); | |
25 | if (!selection || selection.length < 1) { | |
26 | return; | |
27 | } | |
28 | ||
29 | Ext.create(`PVE.dc.RealmSyncJobEdit`, { | |
30 | jobid: selection[0].data.id, | |
31 | autoShow: true, | |
32 | listeners: { | |
33 | destroy: () => me.reload(), | |
34 | }, | |
35 | }); | |
36 | }, | |
37 | ||
38 | reload: function() { | |
39 | this.getView().getStore().load(); | |
40 | }, | |
41 | }, | |
42 | ||
43 | store: { | |
44 | autoLoad: true, | |
45 | id: 'realm-syncs', | |
46 | proxy: { | |
47 | type: 'proxmox', | |
48 | url: '/api2/json/cluster/jobs/realm-sync', | |
49 | }, | |
50 | }, | |
51 | ||
059abb7a DC |
52 | viewConfig: { |
53 | getRowClass: (record, _index) => record.get('enabled') ? '' : 'proxmox-disabled-row', | |
54 | }, | |
55 | ||
f44ce595 DC |
56 | columns: [ |
57 | { | |
58 | header: gettext('Enabled'), | |
59 | width: 80, | |
60 | dataIndex: 'enabled', | |
f44ce595 | 61 | sortable: true, |
059abb7a | 62 | align: 'center', |
f44ce595 | 63 | stopSelection: false, |
059abb7a | 64 | renderer: Proxmox.Utils.renderEnabledIcon, |
f44ce595 DC |
65 | }, |
66 | { | |
67 | text: gettext('Name'), | |
68 | flex: 1, | |
69 | dataIndex: 'id', | |
70 | hidden: true, | |
71 | }, | |
72 | { | |
73 | text: gettext('Realm'), | |
74 | width: 200, | |
75 | dataIndex: 'realm', | |
76 | }, | |
77 | { | |
78 | header: gettext('Schedule'), | |
79 | width: 150, | |
80 | dataIndex: 'schedule', | |
81 | }, | |
82 | { | |
83 | text: gettext('Next Run'), | |
84 | dataIndex: 'next-run', | |
85 | width: 150, | |
86 | renderer: PVE.Utils.render_next_event, | |
87 | }, | |
88 | { | |
89 | header: gettext('Comment'), | |
90 | dataIndex: 'comment', | |
91 | renderer: Ext.htmlEncode, | |
92 | sorter: (a, b) => (a.data.comment || '').localeCompare(b.data.comment || ''), | |
93 | flex: 1, | |
94 | }, | |
95 | ], | |
96 | ||
97 | tbar: [ | |
98 | { | |
99 | text: gettext('Add'), | |
100 | handler: 'addRealmSyncJob', | |
101 | }, | |
102 | { | |
103 | text: gettext('Edit'), | |
104 | xtype: 'proxmoxButton', | |
105 | handler: 'editRealmSyncJob', | |
106 | disabled: true, | |
107 | }, | |
108 | { | |
109 | xtype: 'proxmoxStdRemoveButton', | |
110 | baseurl: `/api2/extjs/cluster/jobs/realm-sync`, | |
111 | callback: 'reload', | |
112 | }, | |
113 | ], | |
114 | ||
115 | listeners: { | |
116 | itemdblclick: 'editRealmSyncJob', | |
117 | }, | |
118 | ||
119 | initComponent: function() { | |
120 | var me = this; | |
121 | ||
122 | me.callParent(); | |
123 | ||
124 | Proxmox.Utils.monStoreErrors(me, me.getStore()); | |
125 | }, | |
126 | }); | |
127 | ||
128 | Ext.define('PVE.dc.RealmSyncJobEdit', { | |
129 | extend: 'Proxmox.window.Edit', | |
130 | mixins: ['Proxmox.Mixin.CBind'], | |
131 | ||
132 | subject: gettext('Realm Sync Job'), | |
133 | onlineHelp: 'pveum_ldap_sync', | |
134 | ||
135 | // don't focus the schedule field on edit | |
136 | defaultFocus: 'field[name=id]', | |
137 | ||
138 | cbindData: function() { | |
139 | let me = this; | |
140 | me.isCreate = !me.jobid; | |
141 | me.jobid = me.jobid || ""; | |
142 | let url = '/api2/extjs/cluster/jobs/realm-sync'; | |
143 | me.url = me.jobid ? `${url}/${me.jobid}` : url; | |
144 | me.method = me.isCreate ? 'POST' : 'PUT'; | |
145 | if (!me.isCreate) { | |
146 | me.subject = `${me.subject}: ${me.jobid}`; | |
147 | } | |
148 | return {}; | |
149 | }, | |
150 | ||
151 | submitUrl: function(url, values) { | |
152 | return this.isCreate ? `${url}/${values.id}` : url; | |
153 | }, | |
154 | ||
155 | controller: { | |
156 | xclass: 'Ext.app.ViewController', | |
157 | ||
158 | updateDefaults: function(_field, newValue) { | |
159 | let me = this; | |
99e276c3 DC |
160 | |
161 | ['scope', 'enable-new', 'schedule'].forEach((reference) => { | |
162 | me.lookup(reference)?.setDisabled(false); | |
163 | }); | |
164 | ||
f44ce595 DC |
165 | // only update on create |
166 | if (!me.getView().isCreate) { | |
167 | return; | |
168 | } | |
169 | Proxmox.Utils.API2Request({ | |
170 | url: `/access/domains/${newValue}`, | |
171 | success: function(response) { | |
172 | // first reset the fields to their default | |
173 | ['acl', 'entry', 'properties'].forEach(opt => { | |
174 | me.lookup(`remove-vanished-${opt}`)?.setValue(false); | |
175 | }); | |
176 | me.lookup('enable-new')?.setValue('1'); | |
177 | me.lookup('scope')?.setValue(undefined); | |
178 | ||
179 | let options = response?.result?.data?.['sync-defaults-options']; | |
180 | if (options) { | |
181 | let parsed = PVE.Parser.parsePropertyString(options); | |
182 | if (parsed['remove-vanished']) { | |
183 | let opts = parsed['remove-vanished'].split(';'); | |
184 | for (const opt of opts) { | |
185 | me.lookup(`remove-vanished-${opt}`)?.setValue(true); | |
186 | } | |
187 | delete parsed['remove-vanished']; | |
188 | } | |
189 | for (const [name, value] of Object.entries(parsed)) { | |
190 | me.lookup(name)?.setValue(value); | |
191 | } | |
192 | } | |
193 | }, | |
194 | }); | |
195 | }, | |
196 | }, | |
197 | ||
198 | items: [ | |
199 | { | |
200 | xtype: 'inputpanel', | |
201 | ||
202 | cbind: { | |
203 | isCreate: '{isCreate}', | |
204 | }, | |
205 | ||
206 | onGetValues: function(values) { | |
207 | let me = this; | |
208 | ||
209 | let vanished_opts = []; | |
210 | ['acl', 'entry', 'properties'].forEach((prop) => { | |
211 | if (values[`remove-vanished-${prop}`]) { | |
212 | vanished_opts.push(prop); | |
213 | } | |
214 | delete values[`remove-vanished-${prop}`]; | |
215 | }); | |
216 | ||
217 | if (!values.id && me.isCreate) { | |
218 | values.id = 'realmsync-' + Ext.data.identifier.Uuid.Global.generate().slice(0, 13); | |
219 | } | |
220 | ||
221 | if (vanished_opts.length > 0) { | |
222 | values['remove-vanished'] = vanished_opts.join(';'); | |
223 | } else { | |
224 | values['remove-vanished'] = 'none'; | |
225 | } | |
226 | ||
227 | PVE.Utils.delete_if_default(values, 'node', ''); | |
228 | ||
229 | if (me.isCreate) { | |
230 | delete values.delete; // on create we cannot delete values | |
231 | } | |
232 | ||
233 | return values; | |
234 | }, | |
235 | ||
236 | column1: [ | |
237 | { | |
238 | xtype: 'pmxDisplayEditField', | |
239 | editConfig: { | |
240 | xtype: 'pmxRealmComboBox', | |
241 | storeFilter: rec => rec.data.type === 'ldap' || rec.data.type === 'ad', | |
242 | }, | |
99e276c3 DC |
243 | listConfig: { |
244 | emptyText: `<div class="x-grid-empty">${gettext('No LDAP/AD Realm found')}</div>`, | |
245 | }, | |
f44ce595 DC |
246 | cbind: { |
247 | editable: '{isCreate}', | |
248 | }, | |
249 | listeners: { | |
250 | change: 'updateDefaults', | |
251 | }, | |
252 | fieldLabel: gettext('Realm'), | |
253 | name: 'realm', | |
254 | reference: 'realm', | |
255 | }, | |
256 | { | |
257 | xtype: 'pveCalendarEvent', | |
258 | fieldLabel: gettext('Schedule'), | |
99e276c3 | 259 | disabled: true, |
f44ce595 DC |
260 | allowBlank: false, |
261 | name: 'schedule', | |
262 | reference: 'schedule', | |
263 | }, | |
264 | { | |
265 | xtype: 'proxmoxcheckbox', | |
266 | fieldLabel: gettext('Enable'), | |
267 | name: 'enabled', | |
268 | reference: 'enabled', | |
269 | uncheckedValue: 0, | |
270 | defaultValue: 1, | |
271 | checked: true, | |
272 | }, | |
273 | ], | |
274 | ||
275 | column2: [ | |
276 | { | |
277 | xtype: 'proxmoxKVComboBox', | |
278 | name: 'scope', | |
279 | reference: 'scope', | |
99e276c3 | 280 | disabled: true, |
f44ce595 DC |
281 | fieldLabel: gettext('Scope'), |
282 | value: '', | |
283 | emptyText: gettext('No default available'), | |
284 | deleteEmpty: false, | |
285 | allowBlank: false, | |
286 | comboItems: [ | |
287 | ['users', gettext('Users')], | |
288 | ['groups', gettext('Groups')], | |
289 | ['both', gettext('Users and Groups')], | |
290 | ], | |
291 | }, | |
292 | { | |
293 | xtype: 'proxmoxKVComboBox', | |
294 | value: '1', | |
295 | deleteEmpty: false, | |
99e276c3 | 296 | disabled: true, |
f44ce595 DC |
297 | allowBlank: false, |
298 | comboItems: [ | |
299 | ['1', Proxmox.Utils.yesText], | |
300 | ['0', Proxmox.Utils.noText], | |
301 | ], | |
302 | name: 'enable-new', | |
303 | reference: 'enable-new', | |
304 | fieldLabel: gettext('Enable new'), | |
305 | }, | |
306 | ], | |
307 | ||
308 | columnB: [ | |
309 | { | |
310 | xtype: 'fieldset', | |
311 | title: gettext('Remove Vanished Options'), | |
312 | items: [ | |
313 | { | |
314 | xtype: 'proxmoxcheckbox', | |
315 | fieldLabel: gettext('ACL'), | |
316 | name: 'remove-vanished-acl', | |
317 | reference: 'remove-vanished-acl', | |
318 | boxLabel: gettext('Remove ACLs of vanished users and groups.'), | |
319 | }, | |
320 | { | |
321 | xtype: 'proxmoxcheckbox', | |
322 | fieldLabel: gettext('Entry'), | |
323 | name: 'remove-vanished-entry', | |
324 | reference: 'remove-vanished-entry', | |
325 | boxLabel: gettext('Remove vanished user and group entries.'), | |
326 | }, | |
327 | { | |
328 | xtype: 'proxmoxcheckbox', | |
329 | fieldLabel: gettext('Properties'), | |
330 | name: 'remove-vanished-properties', | |
331 | reference: 'remove-vanished-properties', | |
332 | boxLabel: gettext('Remove vanished properties from synced users.'), | |
333 | }, | |
334 | ], | |
335 | }, | |
336 | { | |
337 | xtype: 'proxmoxtextfield', | |
338 | name: 'comment', | |
339 | fieldLabel: gettext('Job Comment'), | |
340 | cbind: { | |
341 | deleteEmpty: '{!isCreate}', | |
342 | }, | |
343 | autoEl: { | |
344 | tag: 'div', | |
345 | 'data-qtip': gettext('Description of the job'), | |
346 | }, | |
347 | }, | |
348 | { | |
349 | xtype: 'displayfield', | |
350 | reference: 'defaulthint', | |
351 | value: gettext('Default sync options can be set by editing the realm.'), | |
352 | userCls: 'pmx-hint', | |
353 | hidden: true, | |
354 | }, | |
355 | ], | |
356 | }, | |
357 | ], | |
358 | ||
359 | initComponent: function() { | |
360 | let me = this; | |
361 | me.callParent(); | |
362 | if (me.jobid) { | |
363 | me.load({ | |
364 | success: function(response, options) { | |
365 | let values = response.result.data; | |
366 | ||
367 | if (values['remove-vanished']) { | |
368 | let opts = values['remove-vanished'].split(';'); | |
369 | for (const opt of opts) { | |
370 | values[`remove-vanished-${opt}`] = 1; | |
371 | } | |
372 | } | |
373 | me.down('inputpanel').setValues(values); | |
374 | }, | |
375 | }); | |
376 | } | |
377 | }, | |
378 | }); |