Precise certificate generation
[pve-docs.git] / api-viewer / PVEAPI.js
1 // avoid errors when running without development tools
2 if (!Ext.isDefined(Ext.global.console)) {   
3     var console = { 
4         dir: function() {}, 
5         log: function() {} 
6     };
7 }
8
9 Ext.onReady(function() {
10
11     Ext.define('pve-param-schema', {
12         extend: 'Ext.data.Model',
13         fields:  [ 
14             'name', 'type', 'typetext', 'description', 'verbose_description',
15             'enum', 'minimum', 'maximum', 'minLength', 'maxLength',
16             'pattern', 'title', 'requires', 'format', 'default',
17             'disallow', 'extends', 'links',
18             {
19                 name: 'optional',
20                 type: 'boolean'
21             }
22         ]
23     });
24
25     var store = Ext.create('Ext.data.TreeStore', {
26         model: Ext.define('pve-api-doc', {
27             extend: 'Ext.data.Model',
28             fields:  [ 
29                 'path', 'info', 'text',
30             ]
31         }),
32         proxy: {
33             type: 'memory',
34             data: pveapi
35         },
36         sorters: [{
37             property: 'leaf',
38             direction: 'ASC'
39         }, {
40             property: 'text',
41             direction: 'ASC'
42         }]
43     });
44     
45     var render_description = function(value, metaData, record) {
46         var pdef = record.data;
47
48         value = pdef.verbose_description || value;
49
50         // TODO: try to render asciidoc correctly
51
52         metaData.style = 'white-space:pre-wrap;'
53
54         return Ext.htmlEncode(value);
55     };
56
57     var render_type = function(value, metaData, record) {
58         var pdef = record.data;
59
60         return pdef['enum'] ? 'enum' : (pdef.type || 'string');
61     };
62
63     var render_format = function(value, metaData, record) {
64         var pdef = record.data;
65
66         metaData.style = 'white-space:normal;'
67
68         if (pdef.typetext)
69             return Ext.htmlEncode(pdef.typetext);
70
71         if (pdef['enum'])
72             return pdef['enum'].join(' | ');
73
74         if (pdef.format) 
75             return pdef.format;
76
77         if (pdef.pattern) 
78             return Ext.htmlEncode(pdef.pattern);
79
80         return '';
81     };
82
83     var render_docu = function(data) {
84         var md = data.info;
85
86         // console.dir(data);
87
88         var items = [];
89
90         var clicmdhash = {
91             GET: 'get',
92             POST: 'create',
93             PUT: 'set',
94             DELETE: 'delete'
95         };
96
97         Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function(method) {
98             var info = md[method];
99             if (info) {
100
101                 var usage = "";
102
103                 usage += "<table><tr><td>HTTP:&nbsp;&nbsp;&nbsp;</td><td>" + method + " /api2/json" + data.path + "</td></tr><tr><td>&nbsp</td></tr>";
104                 usage += "<tr><td>CLI:</td><td>pvesh " + clicmdhash[method] + " " + data.path + "</td></tr></table>";
105
106                 var sections = [
107                     {
108                         title: 'Description',
109                         html: Ext.htmlEncode(info.description),
110                         bodyPadding: 10
111                     },
112                     {
113                         title: 'Usage',
114                         html: usage,
115                         bodyPadding: 10
116                     }
117                 ];
118
119                 if (info.parameters && info.parameters.properties) {
120
121                     var pstore = Ext.create('Ext.data.Store', {
122                         model: 'pve-param-schema',
123                         proxy: {
124                             type: 'memory'
125                         },
126                         groupField: 'optional',
127                         sorters: [
128                             {
129                                 property: 'name',
130                                 direction: 'ASC'
131                             }
132                         ]
133                     });
134
135                     Ext.Object.each(info.parameters.properties, function(name, pdef) {
136                         pdef.name = name;
137                         pstore.add(pdef);
138                     });
139
140                     pstore.sort();
141
142                     var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
143                         enableGroupingMenu: false,
144                         groupHeaderTpl: '<tpl if="groupValue">Optional</tpl><tpl if="!groupValue">Required</tpl>'
145                     });
146
147                     sections.push({
148                         xtype: 'gridpanel',
149                         title: 'Parameters',
150                         features: [groupingFeature],
151                         store: pstore,
152                         viewConfig: {
153                             trackOver: false,
154                             stripeRows: true
155                         },
156                         columns: [
157                             {
158                                 header: 'Name',
159                                 dataIndex: 'name',
160                                 flex: 1
161                             },
162                             {
163                                 header: 'Type',
164                                 dataIndex: 'type',
165                                 renderer: render_type,
166                                 flex: 1
167                             },
168                             {
169                                 header: 'Default',
170                                 dataIndex: 'default',
171                                 flex: 1
172                             },
173                             {
174                                 header: 'Format',
175                                 dataIndex: 'type',
176                                 renderer: render_format,
177                                 flex: 2
178                             },
179                             {
180                                 header: 'Description',
181                                 dataIndex: 'description',
182                                 renderer: render_description,
183                                 flex: 6
184                             }
185                         ]
186                     });
187
188                 }
189
190                 if (info.returns) {
191
192                     var retinf = info.returns;
193                     var rtype = retinf.type;
194                     if (!rtype && retinf.items)
195                         rtype = 'array';
196                     if (!rtype)
197                         rtype = 'object';
198
199                     var returnhtml;
200                     if (retinf.items) {
201                         returnhtml = '<pre>items: ' + Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) + '</pre>';
202                     }
203
204                     if (retinf.properties) {
205                         returnhtml = returnhtml || '';
206                         returnhtml += '<pre>properties:' + Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4));
207                     }
208
209                     sections.push({
210                         title: 'Returns: ' + rtype,
211                         bodyPadding: 10,
212                         html: returnhtml
213                     });
214                 }
215
216                 var permhtml = '';
217                 if (!info.permissions) {
218                     permhtml = "Root only.";
219                 } else {
220                     if (info.permissions.description) {
221                         permhtml += "<div style='white-space:pre-wrap;padding-bottom:10px;'>" +
222                             Ext.htmlEncode(info.permissions.description) + "</div>";
223                     }
224
225                     if (info.permissions.user) {
226                         if (!info.permissions.description) {
227                             if (info.permissions.user === 'world') {
228                                 permhtml += "Accessible without any authentication.";
229                             } else if (info.permissions.user === 'all') {
230                                 permhtml += "Accessible by all authenticated users.";
231                             } else {
232                                 permhtml += 'Onyl accessible by user "' + 
233                                     info.permissions.user + '"';
234                             }
235                         }
236                     } else if (info.permissions.check) {
237                         permhtml += "<pre>Check: " + 
238                             Ext.htmlEncode(Ext.JSON.encode(info.permissions.check))  + "</pre>";
239                     } else {
240                         permhtml += "Unknown systax!";
241                     }
242                 }
243
244                 sections.push({
245                     title: 'Required permissions',
246                     bodyPadding: 10,
247                     html: permhtml
248                 });
249     
250   
251                 items.push({
252                     title: method,
253                     autoScroll: true,
254                     defaults: {
255                         border: false
256                     },
257                     items: sections
258                 });
259             }
260         });
261
262         var ct = Ext.getCmp('docview');
263         ct.setTitle("Path: " + data.path);
264         ct.removeAll(true);
265         ct.add(items);
266         ct.setActiveTab(0);
267     };
268
269     var tree = Ext.create('Ext.tree.Panel', {
270         title: 'Resource Tree',
271         store: store,
272         width: 200,
273         region: 'west',
274         split: true,
275         margins: '5 0 5 5',
276         rootVisible: false,
277         listeners: {
278             selectionchange: function(v, selections) {
279                 if (!selections[0])
280                     return;
281                 var rec = selections[0];
282                 render_docu(rec.data);
283             }
284         }
285     });
286
287     Ext.create('Ext.container.Viewport', {
288         layout: 'border',
289         renderTo: Ext.getBody(),
290         items: [
291             tree,
292             {
293                 xtype: 'tabpanel',
294                 title: 'Documentation',
295                 id: 'docview',
296                 region: 'center',
297                 margins: '5 5 5 0',
298                 layout: 'fit',
299                 items: []
300             }
301         ]
302     });
303
304 });