[pmg-devel] applied: [PATCH docs 3/3] api-viewer: port over search, expand/collapse all & deeplink from PVE
Thomas Lamprecht
t.lamprecht at proxmox.com
Thu Feb 13 18:09:32 CET 2020
Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
api-viewer/PMGAPI.js | 242 +++++++++++++++++++++++++++++++++++++------
1 file changed, 210 insertions(+), 32 deletions(-)
diff --git a/api-viewer/PMGAPI.js b/api-viewer/PMGAPI.js
index f39170c..59efd29 100644
--- a/api-viewer/PMGAPI.js
+++ b/api-viewer/PMGAPI.js
@@ -22,26 +22,52 @@ Ext.onReady(function() {
]
});
- var store = Ext.create('Ext.data.TreeStore', {
+ var store = Ext.define('pmg-updated-treestore', {
+ extend: 'Ext.data.TreeStore',
model: Ext.define('pmg-api-doc', {
- extend: 'Ext.data.Model',
- fields: [
+ extend: 'Ext.data.Model',
+ fields: [
'path', 'info', 'text',
]
}),
- proxy: {
- type: 'memory',
- data: pmgapi
- },
- sorters: [{
- property: 'leaf',
- direction: 'ASC'
- }, {
- property: 'text',
- direction: 'ASC'
- }]
- });
-
+ 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;
@@ -196,21 +222,109 @@ Ext.onReady(function() {
if (!rtype)
rtype = 'object';
- 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>';
- }
-
- sections.push({
- title: 'Returns: ' + rtype,
- bodyPadding: 10,
- html: returnhtml
- });
+ 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 = '';
@@ -240,6 +354,10 @@ Ext.onReady(function() {
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',
@@ -266,8 +384,53 @@ Ext.onReady(function() {
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',
+ 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',
@@ -280,6 +443,7 @@ Ext.onReady(function() {
return;
var rec = selections[0];
render_docu(rec.data);
+ location.hash = '#' + rec.data.path;
}
}
});
@@ -301,4 +465,18 @@ Ext.onReady(function() {
]
});
+ 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();
+
});
--
2.20.1
More information about the pmg-devel
mailing list