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