public inbox for pmg-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pmg-devel] [PATCH pmg-docs v2] build api-viewer from proxmox-widget-toolkit-dev
@ 2021-06-04 12:42 Dominik Csapak
  2021-06-14  7:44 ` [pmg-devel] applied: " Stoiko Ivanov
  0 siblings, 1 reply; 2+ messages in thread
From: Dominik Csapak @ 2021-06-04 12:42 UTC (permalink / raw)
  To: pmg-devel

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

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v1:
* insert dev-dependency sorted
* use new 'api' of APIViewer (apiSchema/cliUsageRenderer)
* update path to APIViewer.js (previously APIVIEWER.js)

 Makefile             |  10 +-
 api-viewer/PMGAPI.js | 490 +------------------------------------------
 debian/control       |   1 +
 extractapi.pl        |   2 +-
 4 files changed, 19 insertions(+), 484 deletions(-)

diff --git a/Makefile b/Makefile
index 8b125df..eb4db5a 100644
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,11 @@ GEN_SCRIPTS=					\
 	gen-pmg.conf.5-opts.pl			\
 	gen-user.conf.5-opts.pl
 
+API_VIEWER_FILES=							\
+	api-viewer/apidata.js						\
+	api-viewer/PMGAPI.js						\
+	/usr/share/javascript/proxmox-widget-toolkit-dev/APIViewer.js
+
 API_VIEWER_SOURCES=				\
 	api-viewer/index.html			\
 	api-viewer/apidoc.js
@@ -139,8 +144,9 @@ pmg-admin-guide.epub: ${PMG_ADMIN_GUIDE_ADOCDEPENDS}
 api-viewer/apidata.js: extractapi.pl
 	./extractapi.pl >$@
 
-api-viewer/apidoc.js: api-viewer/apidata.js api-viewer/PMGAPI.js
-	cat api-viewer/apidata.js api-viewer/PMGAPI.js >$@
+api-viewer/apidoc.js: ${API_VIEWER_FILES}
+	cat ${API_VIEWER_FILES} >$@.tmp
+	mv $@.tmp $@
 
 .PHONY: dinstall
 dinstall: ${GEN_DEB} ${DOC_DEB}
diff --git a/api-viewer/PMGAPI.js b/api-viewer/PMGAPI.js
index 76fd77e..e5a6187 100644
--- a/api-viewer/PMGAPI.js
+++ b/api-viewer/PMGAPI.js
@@ -1,482 +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 cliUsageRenderer(method, path) {
+    return `<tr><td>&nbsp;</td></tr><tr><td>CLI:</td><td>pmgsh ${clicmdhash[method]} ${path}</td></tr></table>`;
 }
-
-Ext.onReady(function() {
-
-    Ext.define('pmg-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('pmg-updated-treestore', {
-	extend: 'Ext.data.TreeStore',
-	model: Ext.define('pmg-api-doc', {
-	    extend: 'Ext.data.Model',
-	    fields:  [
-		'path', 'info', 'text',
-	    ]
-	}),
-	proxy: {
-	    type: 'memory',
-	    data: pmgapi
-	},
-	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>pmgsh " + 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: 'pmg-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: 'pmg-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) {
-		    // PMG doesn't fully supports API token, and probably won't ever!?
-		    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 8d2ccde..5993180 100644
--- a/debian/control
+++ b/debian/control
@@ -9,6 +9,7 @@ Build-Depends: asciidoc-dblatex,
                imagemagick,
                librsvg2-bin,
                lintian,
+               proxmox-widget-toolkit-dev,
                source-highlight,
 Standards-Version: 3.8.4
 
diff --git a/extractapi.pl b/extractapi.pl
index 283d8a0..9a7262d 100755
--- a/extractapi.pl
+++ b/extractapi.pl
@@ -42,6 +42,6 @@ sub cleanup_tree {
 
 my $tree = cleanup_tree(PVE::RESTHandler::api_dump('PMG::API2'));
 
-print "var pmgapi = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
+print "var apiSchema = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
 
 exit(0);
-- 
2.20.1





^ permalink raw reply	[flat|nested] 2+ messages in thread

* [pmg-devel] applied: [PATCH pmg-docs v2] build api-viewer from proxmox-widget-toolkit-dev
  2021-06-04 12:42 [pmg-devel] [PATCH pmg-docs v2] build api-viewer from proxmox-widget-toolkit-dev Dominik Csapak
@ 2021-06-14  7:44 ` Stoiko Ivanov
  0 siblings, 0 replies; 2+ messages in thread
From: Stoiko Ivanov @ 2021-06-14  7:44 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pmg-devel

On Fri,  4 Jun 2021 14:42:26 +0200
Dominik Csapak <d.csapak@proxmox.com> wrote:

> build-depends on the new proxmox-widget-toolkit-dev package
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> changes from v1:
> * insert dev-dependency sorted
> * use new 'api' of APIViewer (apiSchema/cliUsageRenderer)
> * update path to APIViewer.js (previously APIVIEWER.js)
> 
>  Makefile             |  10 +-
>  api-viewer/PMGAPI.js | 490 +------------------------------------------
>  debian/control       |   1 +
>  extractapi.pl        |   2 +-
>  4 files changed, 19 insertions(+), 484 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index 8b125df..eb4db5a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -53,6 +53,11 @@ GEN_SCRIPTS=					\
>  	gen-pmg.conf.5-opts.pl			\
>  	gen-user.conf.5-opts.pl
>  
> +API_VIEWER_FILES=							\
> +	api-viewer/apidata.js						\
> +	api-viewer/PMGAPI.js						\
> +	/usr/share/javascript/proxmox-widget-toolkit-dev/APIViewer.js
> +
>  API_VIEWER_SOURCES=				\
>  	api-viewer/index.html			\
>  	api-viewer/apidoc.js
> @@ -139,8 +144,9 @@ pmg-admin-guide.epub: ${PMG_ADMIN_GUIDE_ADOCDEPENDS}
>  api-viewer/apidata.js: extractapi.pl
>  	./extractapi.pl >$@
>  
> -api-viewer/apidoc.js: api-viewer/apidata.js api-viewer/PMGAPI.js
> -	cat api-viewer/apidata.js api-viewer/PMGAPI.js >$@
> +api-viewer/apidoc.js: ${API_VIEWER_FILES}
> +	cat ${API_VIEWER_FILES} >$@.tmp
> +	mv $@.tmp $@
>  
>  .PHONY: dinstall
>  dinstall: ${GEN_DEB} ${DOC_DEB}
> diff --git a/api-viewer/PMGAPI.js b/api-viewer/PMGAPI.js
> index 76fd77e..e5a6187 100644
> --- a/api-viewer/PMGAPI.js
> +++ b/api-viewer/PMGAPI.js
> @@ -1,482 +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 cliUsageRenderer(method, path) {
> +    return `<tr><td>&nbsp;</td></tr><tr><td>CLI:</td><td>pmgsh ${clicmdhash[method]} ${path}</td></tr></table>`;
>  }
> -
> -Ext.onReady(function() {
> -
> -    Ext.define('pmg-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('pmg-updated-treestore', {
> -	extend: 'Ext.data.TreeStore',
> -	model: Ext.define('pmg-api-doc', {
> -	    extend: 'Ext.data.Model',
> -	    fields:  [
> -		'path', 'info', 'text',
> -	    ]
> -	}),
> -	proxy: {
> -	    type: 'memory',
> -	    data: pmgapi
> -	},
> -	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>pmgsh " + 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: 'pmg-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: 'pmg-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) {
> -		    // PMG doesn't fully supports API token, and probably won't ever!?
> -		    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 8d2ccde..5993180 100644
> --- a/debian/control
> +++ b/debian/control
> @@ -9,6 +9,7 @@ Build-Depends: asciidoc-dblatex,
>                 imagemagick,
>                 librsvg2-bin,
>                 lintian,
> +               proxmox-widget-toolkit-dev,
>                 source-highlight,
>  Standards-Version: 3.8.4
>  
> diff --git a/extractapi.pl b/extractapi.pl
> index 283d8a0..9a7262d 100755
> --- a/extractapi.pl
> +++ b/extractapi.pl
> @@ -42,6 +42,6 @@ sub cleanup_tree {
>  
>  my $tree = cleanup_tree(PVE::RESTHandler::api_dump('PMG::API2'));
>  
> -print "var pmgapi = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
> +print "var apiSchema = " . to_json($tree, {pretty => 1, canonical => 1}) . ";\n\n";
>  
>  exit(0);

applied - huge thanks!




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-06-14  7:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-04 12:42 [pmg-devel] [PATCH pmg-docs v2] build api-viewer from proxmox-widget-toolkit-dev Dominik Csapak
2021-06-14  7:44 ` [pmg-devel] applied: " Stoiko Ivanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal