all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH docs] build api-viewer from widget-toolkit-dev
Date: Fri, 28 May 2021 14:14:31 +0200	[thread overview]
Message-ID: <20210528121431.20382-1-d.csapak@proxmox.com> (raw)

build-depends naturally on the new proxmox-widget-toolkit-dev package

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 Makefile             |  10 +-
 api-viewer/PVEAPI.js | 489 +------------------------------------------
 debian/control       |   1 +
 extractapi.pl        |   2 +-
 4 files changed, 19 insertions(+), 483 deletions(-)

diff --git a/Makefile b/Makefile
index 98b6b44..552bbd8 100644
--- a/Makefile
+++ b/Makefile
@@ -63,6 +63,11 @@ GEN_SCRIPTS=					\
 	gen-pve-firewall-vm-opts.pl		\
 	gen-output-format-opts.pl
 
+API_VIEWER_FILES=							\
+	api-viewer/apidata.js						\
+	api-viewer/PVEAPI.js						\
+	/usr/share/javascript/proxmox-widget-toolkit-dev/APIVIEWER.js
+
 API_VIEWER_SOURCES=				\
 	api-viewer/index.html			\
 	api-viewer/apidoc.js
@@ -149,8 +154,9 @@ pve-admin-guide.epub: ${PVE_ADMIN_GUIDE_ADOCDEPENDS}
 api-viewer/apidata.js: extractapi.pl
 	./extractapi.pl >$@
 
-api-viewer/apidoc.js: api-viewer/apidata.js api-viewer/PVEAPI.js
-	cat api-viewer/apidata.js api-viewer/PVEAPI.js >$@
+api-viewer/apidoc.js: ${API_VIEWER_FILES}
+	cat ${API_VIEWER_FILES} >$@.tmp
+	mv $@.tmp $@
 
 .PHONY: dinstall
 dinstall: ${GEN_DEB} ${DOC_DEB} ${MEDIAWIKI_DEB}
diff --git a/api-viewer/PVEAPI.js b/api-viewer/PVEAPI.js
index 53bc36c..ae45884 100644
--- a/api-viewer/PVEAPI.js
+++ b/api-viewer/PVEAPI.js
@@ -1,481 +1,10 @@
-// avoid errors when running without development tools
-if (!Ext.isDefined(Ext.global.console)) {
-    var console = {
-        dir: function() {},
-        log: function() {}
-    };
+var clicmdhash = {
+    GET: 'get',
+    POST: 'create',
+    PUT: 'set',
+    DELETE: 'delete'
+};
+
+function cliusage(method, path) {
+    return `<tr><td>&nbsp;</td></td><tr><td>CLI:</td><td>pvesh ${clicmdhash[method]} ${path}</td></tr></table>`;
 }
-
-Ext.onReady(function() {
-
-    Ext.define('pve-param-schema', {
-        extend: 'Ext.data.Model',
-        fields:  [
-	    'name', 'type', 'typetext', 'description', 'verbose_description',
-	    'enum', 'minimum', 'maximum', 'minLength', 'maxLength',
-	    'pattern', 'title', 'requires', 'format', 'default',
-	    'disallow', 'extends', 'links',
-	    {
-		name: 'optional',
-		type: 'boolean'
-	    }
-	]
-    });
-
-    var store = Ext.define('pve-updated-treestore', {
-	extend: 'Ext.data.TreeStore',
-	model: Ext.define('pve-api-doc', {
-            extend: 'Ext.data.Model',
-            fields:  [
-		'path', 'info', 'text',
-	    ]
-	}),
-        proxy: {
-            type: 'memory',
-            data: pveapi
-        },
-        sorters: [{
-            property: 'leaf',
-            direction: 'ASC'
-        }, {
-            property: 'text',
-            direction: 'ASC'
-	}],
-	filterer: 'bottomup',
-	doFilter: function(node) {
-	    this.filterNodes(node, this.getFilters().getFilterFn(), true);
-	},
-
-	filterNodes: function(node, filterFn, parentVisible) {
-	    var me = this,
-		bottomUpFiltering = me.filterer === 'bottomup',
-		match = filterFn(node) && parentVisible || (node.isRoot() && !me.getRootVisible()),
-		childNodes = node.childNodes,
-		len = childNodes && childNodes.length, i, matchingChildren;
-
-	    if (len) {
-		for (i = 0; i < len; ++i) {
-		    matchingChildren = me.filterNodes(childNodes[i], filterFn, match || bottomUpFiltering) || matchingChildren;
-		}
-		if (bottomUpFiltering) {
-		    match = matchingChildren || match;
-		}
-	    }
-
-	    node.set("visible", match, me._silentOptions);
-	    return match;
-	},
-
-    }).create();
-
-    var render_description = function(value, metaData, record) {
-	var pdef = record.data;
-
-	value = pdef.verbose_description || value;
-
-	// TODO: try to render asciidoc correctly
-
-	metaData.style = 'white-space:pre-wrap;'
-
-	return Ext.htmlEncode(value);
-    };
-
-    var render_type = function(value, metaData, record) {
-	var pdef = record.data;
-
-	return pdef['enum'] ? 'enum' : (pdef.type || 'string');
-    };
-
-    var render_format = function(value, metaData, record) {
-	var pdef = record.data;
-
-	metaData.style = 'white-space:normal;'
-
-	if (pdef.typetext)
-	    return Ext.htmlEncode(pdef.typetext);
-
-	if (pdef['enum'])
-	    return pdef['enum'].join(' | ');
-
-	if (pdef.format)
-	    return pdef.format;
-
-	if (pdef.pattern)
-	    return Ext.htmlEncode(pdef.pattern);
-
-	return '';
-    };
-
-    var render_docu = function(data) {
-	var md = data.info;
-
-	// console.dir(data);
-
-	var items = [];
-
-	var clicmdhash = {
-	    GET: 'get',
-	    POST: 'create',
-	    PUT: 'set',
-	    DELETE: 'delete'
-	};
-
-	Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function(method) {
-	    var info = md[method];
-	    if (info) {
-
-		var usage = "";
-
-		usage += "<table><tr><td>HTTP:&nbsp;&nbsp;&nbsp;</td><td>" + method + " /api2/json" + data.path + "</td></tr><tr><td>&nbsp</td></tr>";
-		usage += "<tr><td>CLI:</td><td>pvesh " + clicmdhash[method] + " " + data.path + "</td></tr></table>";
-
-		var sections = [
-		    {
-			title: 'Description',
-			html: Ext.htmlEncode(info.description),
-			bodyPadding: 10
-		    },
-		    {
-			title: 'Usage',
-			html: usage,
-			bodyPadding: 10
-		    }
-		];
-
-		if (info.parameters && info.parameters.properties) {
-
-		    var pstore = Ext.create('Ext.data.Store', {
-			model: 'pve-param-schema',
-			proxy: {
-			    type: 'memory'
-			},
-			groupField: 'optional',
-			sorters: [
-			    {
-				property: 'name',
-				direction: 'ASC'
-			    }
-			]
-		    });
-
-		    Ext.Object.each(info.parameters.properties, function(name, pdef) {
-			pdef.name = name;
-			pstore.add(pdef);
-		    });
-
-		    pstore.sort();
-
-		    var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
-			enableGroupingMenu: false,
-			groupHeaderTpl: '<tpl if="groupValue">Optional</tpl><tpl if="!groupValue">Required</tpl>'
-		    });
-
-		    sections.push({
-			xtype: 'gridpanel',
-			title: 'Parameters',
-			features: [groupingFeature],
-			store: pstore,
-			viewConfig: {
-			    trackOver: false,
-			    stripeRows: true
-			},
-			columns: [
-			    {
-				header: 'Name',
-				dataIndex: 'name',
-				flex: 1
-			    },
-			    {
-				header: 'Type',
-				dataIndex: 'type',
-				renderer: render_type,
-				flex: 1
-			    },
-			    {
-				header: 'Default',
-				dataIndex: 'default',
-				flex: 1
-			    },
-			    {
-				header: 'Format',
-				dataIndex: 'type',
-				renderer: render_format,
-				flex: 2
-			    },
-			    {
-				header: 'Description',
-				dataIndex: 'description',
-				renderer: render_description,
-				flex: 6
-			    }
-			]
-		    });
-
-		}
-
-		if (info.returns) {
-
-		    var retinf = info.returns;
-		    var rtype = retinf.type;
-		    if (!rtype && retinf.items)
-			rtype = 'array';
-		    if (!rtype)
-			rtype = 'object';
-
-		    var rpstore = Ext.create('Ext.data.Store', {
-			model: 'pve-param-schema',
-			proxy: {
-			    type: 'memory'
-			},
-			groupField: 'optional',
-			sorters: [
-			    {
-				property: 'name',
-				direction: 'ASC'
-			   }
-			]
-		    });
-
-		    var properties;
-		    if (rtype === 'array' && retinf.items.properties) {
-			properties = retinf.items.properties;
-		    }
-
-		    if (rtype === 'object' && retinf.properties) {
-			properties = retinf.properties;
-		    }
-
-		    Ext.Object.each(properties, function(name, pdef) {
-			pdef.name = name;
-			rpstore.add(pdef);
-		    });
-
-		    rpstore.sort();
-
-		    var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{
-			enableGroupingMenu: false,
-			groupHeaderTpl: '<tpl if="groupValue">Optional</tpl><tpl if="!groupValue">Obligatory</tpl>'
-		    });
-		    var returnhtml;
-		    if (retinf.items) {
-			returnhtml = '<pre>items: ' + Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) + '</pre>';
-		    }
-
-		    if (retinf.properties) {
-			returnhtml = returnhtml || '';
-			returnhtml += '<pre>properties:' + Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4)) + '</pre>';
-		    }
-
-		    var rawSection = Ext.create('Ext.panel.Panel', {
-			bodyPadding: '0px 10px 10px 10px',
-			html: returnhtml,
-			hidden: true
-		    });
-
-		    sections.push({
-			xtype: 'gridpanel',
-			title: 'Returns: ' + rtype,
-			features: [groupingFeature],
-			store: rpstore,
-			viewConfig: {
-			    trackOver: false,
-			    stripeRows: true
-			},
-		    columns: [
-			{
-			    header: 'Name',
-			    dataIndex: 'name',
-			    flex: 1
-			},
-			{
-			    header: 'Type',
-			    dataIndex: 'type',
-			    renderer: render_type,
-			    flex: 1
-			},
-			{
-			    header: 'Default',
-			    dataIndex: 'default',
-			    flex: 1
-			},
-			{
-			    header: 'Format',
-			    dataIndex: 'type',
-			    renderer: render_format,
-			    flex: 2
-			},
-			{
-			    header: 'Description',
-			    dataIndex: 'description',
-			    renderer: render_description,
-			    flex: 6
-			}
-		    ],
-		    bbar: [
-			{
-			    xtype: 'button',
-			    text: 'Show RAW',
-			    handler: function(btn) {
-				rawSection.setVisible(!rawSection.isVisible());
-				btn.setText(rawSection.isVisible() ? 'Hide RAW' : 'Show RAW');
-			    }}
-		    ]
-		});
-
-		sections.push(rawSection);
-
-
-		}
-
-		var permhtml = '';
-		if (!info.permissions) {
-		    permhtml = "Root only.";
-		} else {
-		    if (info.permissions.description) {
-			permhtml += "<div style='white-space:pre-wrap;padding-bottom:10px;'>" +
-			    Ext.htmlEncode(info.permissions.description) + "</div>";
-		    }
-
-		    if (info.permissions.user) {
-			if (!info.permissions.description) {
-			    if (info.permissions.user === 'world') {
-				permhtml += "Accessible without any authentication.";
-			    } else if (info.permissions.user === 'all') {
-				permhtml += "Accessible by all authenticated users.";
-			    } else {
-				permhtml += 'Onyl accessible by user "' +
-				    info.permissions.user + '"';
-			    }
-			}
-		    } else if (info.permissions.check) {
-			permhtml += "<pre>Check: " +
-			    Ext.htmlEncode(Ext.JSON.encode(info.permissions.check))  + "</pre>";
-		    } else {
-			permhtml += "Unknown systax!";
-		    }
-		}
-		if (!info.allowtoken) {
-		    permhtml += "<br />This API endpoint is not available for API tokens."
-		}
-
-		sections.push({
-		    title: 'Required permissions',
-		    bodyPadding: 10,
-		    html: permhtml
-		});
-
-
-		items.push({
-		    title: method,
-		    autoScroll: true,
-		    defaults: {
-			border: false
-		    },
-		    items: sections
-		});
-	    }
-	});
-
-	var ct = Ext.getCmp('docview');
-	ct.setTitle("Path: " + data.path);
-	ct.removeAll(true);
-	ct.add(items);
-	ct.setActiveTab(0);
-    };
-
-    Ext.define('Ext.form.SearchField', {
-	extend: 'Ext.form.field.Text',
-	alias: 'widget.searchfield',
-
-	emptyText: 'Search...',
-
-	flex: 1,
-
-	inputType: 'search',
-	listeners: {
-	    'change': function(){
-
-		var value = this.getValue();
-		if (!Ext.isEmpty(value)) {
-		    store.filter({
-			property: 'path',
-			value: value,
-			anyMatch: true
-		    });
-		} else {
-		    store.clearFilter();
-		}
-	    }
-	}
-    });
-
-    var tree = Ext.create('Ext.tree.Panel', {
-	title: 'Resource Tree',
-	tbar: [
-	    {
-		xtype: 'searchfield',
-	    }
-	],
-	tools: [
-	    {
-		type: 'expand',
-		tooltip: 'Expand all',
-		tooltipType: 'title',
-		callback: (tree) => tree.expandAll(),
-	    },
-	    {
-		type: 'collapse',
-		tooltip: 'Collapse all',
-		tooltipType: 'title',
-		callback: (tree) => tree.collapseAll(),
-	    },
-	],
-        store: store,
-	width: 200,
-        region: 'west',
-        split: true,
-        margins: '5 0 5 5',
-        rootVisible: false,
-	listeners: {
-	    selectionchange: function(v, selections) {
-		if (!selections[0])
-		    return;
-		var rec = selections[0];
-		render_docu(rec.data);
-		location.hash = '#' + rec.data.path;
-	    }
-	}
-    });
-
-    Ext.create('Ext.container.Viewport', {
-	layout: 'border',
-	renderTo: Ext.getBody(),
-	items: [
-	    tree,
-	    {
-		xtype: 'tabpanel',
-		title: 'Documentation',
-		id: 'docview',
-		region: 'center',
-		margins: '5 5 5 0',
-		layout: 'fit',
-		items: []
-	    }
-	]
-    });
-
-    var deepLink = function() {
-	var path = window.location.hash.substring(1).replace(/\/\s*$/, '')
-	var endpoint = store.findNode('path', path);
-
-	if (endpoint) {
-	    tree.getSelectionModel().select(endpoint);
-	    tree.expandPath(endpoint.getPath());
-	    render_docu(endpoint.data);
-	}
-    }
-    window.onhashchange = deepLink;
-
-    deepLink();
-
-});
diff --git a/debian/control b/debian/control
index ba8a2c2..9207c8e 100644
--- a/debian/control
+++ b/debian/control
@@ -13,6 +13,7 @@ Build-Depends: asciidoc-dblatex,
                lintian,
                rsync,
                source-highlight,
+	       proxmox-widget-toolkit-dev,
 Standards-Version: 4.3.0
 
 Package: pve-doc-generator
diff --git a/extractapi.pl b/extractapi.pl
index 06d6af4..4d3f143 100755
--- a/extractapi.pl
+++ b/extractapi.pl
@@ -10,6 +10,6 @@ use JSON;
 
 my $tree = PVE::RESTHandler::api_dump_remove_refs(PVE::RESTHandler::api_dump('PVE::API2'));
 
-print "var pveapi = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
+print "var pmxapi = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
 
 exit(0);
-- 
2.20.1





             reply	other threads:[~2021-05-28 12:14 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-28 12:14 Dominik Csapak [this message]
2021-06-02 14:46 ` [pve-devel] applied: " Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210528121431.20382-1-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal