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