]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - src/window/ACMEPluginEdit.js
tree-wide typo fixes
[proxmox-widget-toolkit.git] / src / window / ACMEPluginEdit.js
1 Ext.define('Proxmox.window.ACMEPluginEdit', {
2 extend: 'Proxmox.window.Edit',
3 xtype: 'pmxACMEPluginEdit',
4 mixins: ['Proxmox.Mixin.CBind'],
5
6 //onlineHelp: 'sysadmin_certs_acme_plugins',
7
8 isAdd: true,
9 isCreate: false,
10
11 width: 550,
12
13 acmeUrl: undefined,
14
15 subject: 'ACME DNS Plugin',
16
17 cbindData: function(config) {
18 let me = this;
19 return {
20 challengeSchemaUrl: `/api2/json/${me.acmeUrl}/challenge-schema`,
21 };
22 },
23
24 items: [
25 {
26 xtype: 'inputpanel',
27 // we dynamically create fields from the given schema
28 // things we have to do here:
29 // * save which fields we created to remove them again
30 // * split the data from the generic 'data' field into the boxes
31 // * on deletion collect those values again
32 // * save the original values of the data field
33 createdFields: {},
34 createdInitially: false,
35 originalValues: {},
36 createSchemaFields: function(schema) {
37 let me = this;
38 // we know where to add because we define it right below
39 let container = me.down('container');
40 let datafield = me.down('field[name=data]');
41 let hintfield = me.down('field[name=hint]');
42 if (!me.createdInitially) {
43 [me.originalValues] = Proxmox.Utils.parseACMEPluginData(datafield.getValue());
44 }
45
46 // collect values from custom fields and add it to 'data'',
47 // then remove the custom fields
48 let data = [];
49 for (const [name, field] of Object.entries(me.createdFields)) {
50 let value = field.getValue();
51 if (value !== undefined && value !== null && value !== '') {
52 data.push(`${name}=${value}`);
53 }
54 container.remove(field);
55 }
56 let datavalue = datafield.getValue();
57 if (datavalue !== undefined && datavalue !== null && datavalue !== '') {
58 data.push(datavalue);
59 }
60 datafield.setValue(data.join('\n'));
61
62 me.createdFields = {};
63
64 if (typeof schema.fields !== 'object') {
65 schema.fields = {};
66 }
67 // create custom fields according to schema
68 let gotSchemaField = false;
69 for (const [name, definition] of Object
70 .entries(schema.fields)
71 .sort((a, b) => a[0].localeCompare(b[0]))
72 ) {
73 let xtype;
74 switch (definition.type) {
75 case 'string':
76 xtype = 'proxmoxtextfield';
77 break;
78 case 'integer':
79 xtype = 'proxmoxintegerfield';
80 break;
81 case 'number':
82 xtype = 'numberfield';
83 break;
84 default:
85 console.warn(`unknown type '${definition.type}'`);
86 xtype = 'proxmoxtextfield';
87 break;
88 }
89
90 let label = name;
91 if (typeof definition.name === "string") {
92 label = definition.name;
93 }
94
95 let field = Ext.create({
96 xtype,
97 name: `custom_${name}`,
98 fieldLabel: label,
99 width: '100%',
100 labelWidth: 150,
101 labelSeparator: '=',
102 emptyText: definition.default || '',
103 autoEl: definition.description ? {
104 tag: 'div',
105 'data-qtip': definition.description,
106 } : undefined,
107 });
108
109 me.createdFields[name] = field;
110 container.add(field);
111 gotSchemaField = true;
112 }
113 datafield.setHidden(gotSchemaField); // prefer schema-fields
114
115 if (schema.description) {
116 hintfield.setValue(schema.description);
117 hintfield.setHidden(false);
118 } else {
119 hintfield.setValue('');
120 hintfield.setHidden(true);
121 }
122
123 // parse data from field and set it to the custom ones
124 let extradata = [];
125 [data, extradata] = Proxmox.Utils.parseACMEPluginData(datafield.getValue());
126 for (const [key, value] of Object.entries(data)) {
127 if (me.createdFields[key]) {
128 me.createdFields[key].setValue(value);
129 me.createdFields[key].originalValue = me.originalValues[key];
130 } else {
131 extradata.push(`${key}=${value}`);
132 }
133 }
134 datafield.setValue(extradata.join('\n'));
135 if (!me.createdInitially) {
136 datafield.resetOriginalValue();
137 me.createdInitially = true; // save that we initially set that
138 }
139 },
140
141 onGetValues: function(values) {
142 let me = this;
143 let win = me.up('pmxACMEPluginEdit');
144 if (win.isCreate) {
145 values.id = values.plugin;
146 values.type = 'dns'; // the only one for now
147 }
148 delete values.plugin;
149
150 Proxmox.Utils.delete_if_default(values, 'validation-delay', '30', win.isCreate);
151
152 let data = '';
153 for (const [name, field] of Object.entries(me.createdFields)) {
154 let value = field.getValue();
155 if (value !== null && value !== undefined && value !== '') {
156 data += `${name}=${value}\n`;
157 }
158 delete values[`custom_${name}`];
159 }
160 values.data = Ext.util.Base64.encode(data + values.data);
161 return values;
162 },
163
164 items: [
165 {
166 xtype: 'pmxDisplayEditField',
167 cbind: {
168 editable: (get) => get('isCreate'),
169 submitValue: (get) => get('isCreate'),
170 },
171 editConfig: {
172 flex: 1,
173 xtype: 'proxmoxtextfield',
174 allowBlank: false,
175 },
176 name: 'plugin',
177 labelWidth: 150,
178 fieldLabel: gettext('Plugin ID'),
179 },
180 {
181 xtype: 'proxmoxintegerfield',
182 name: 'validation-delay',
183 labelWidth: 150,
184 fieldLabel: gettext('Validation Delay'),
185 emptyText: 30,
186 cbind: {
187 deleteEmpty: '{!isCreate}',
188 },
189 minValue: 0,
190 maxValue: 48*60*60,
191 },
192 {
193 xtype: 'pmxACMEApiSelector',
194 name: 'api',
195 labelWidth: 150,
196 cbind: {
197 url: '{challengeSchemaUrl}',
198 },
199 listeners: {
200 change: function(selector) {
201 let schema = selector.getSchema();
202 selector.up('inputpanel').createSchemaFields(schema);
203 },
204 },
205 },
206 {
207 xtype: 'textarea',
208 fieldLabel: gettext('API Data'),
209 labelWidth: 150,
210 name: 'data',
211 },
212 {
213 xtype: 'displayfield',
214 fieldLabel: gettext('Hint'),
215 labelWidth: 150,
216 name: 'hint',
217 hidden: true,
218 },
219 ],
220 },
221 ],
222
223 initComponent: function() {
224 var me = this;
225
226 if (!me.acmeUrl) {
227 throw "no acmeUrl given";
228 }
229
230 me.callParent();
231
232 if (!me.isCreate) {
233 me.load({
234 success: function(response, opts) {
235 me.setValues(response.result.data);
236 },
237 });
238 } else {
239 me.method = 'POST';
240 }
241 },
242 });