diff --git a/src/webui/extjs.c b/src/webui/extjs.c index c9ba7d09..0d75c4a2 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -2169,6 +2169,49 @@ extjs_tvhlog(http_connection_t *hc, const char *remain, void *opaque) return 0; } +static int +extjs_idnode + (http_connection_t *hc, const char *remain, void *opaque) +{ + htsbuf_queue_t *hq = &hc->hc_reply; + const char *uuid = http_arg_get(&hc->hc_req_args, "uuid"); + const char *op = http_arg_get(&hc->hc_req_args, "op"); + htsmsg_t *out = NULL; + idnode_t *node; + + if(uuid == NULL) + return HTTP_STATUS_BAD_REQUEST; + + pthread_mutex_lock(&global_lock); + + if(http_access_verify(hc, ACCESS_ADMIN)) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_UNAUTHORIZED; + } + + node = idnode_find(uuid, NULL); + if (!node) { + pthread_mutex_unlock(&global_lock); + return HTTP_STATUS_BAD_REQUEST; + } + + if (!strcmp(op, "get")) { + out = htsmsg_create_list(); + htsmsg_t *m = idnode_serialize(node); + htsmsg_add_u32(m, "leaf", idnode_is_leaf(node)); + htsmsg_add_msg(out, NULL, m); + } + + pthread_mutex_unlock(&global_lock); + + if (!out) + return HTTP_STATUS_BAD_REQUEST; + + htsmsg_json_serialize(out, hq, 0); + htsmsg_destroy(out); + http_output_content(hc, "text/x-json; charset=UTF-8"); + return 0; +} /** * @@ -2399,6 +2442,7 @@ extjs_start(void) http_path_add("/tvadapters", NULL, extjs_tvadapters, ACCESS_ADMIN); + http_path_add("/api/idnode", NULL, extjs_idnode, ACCESS_ADMIN); // TODO: might want diff access for read/write` extjs_start_dvb(); diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index 3cd10b99..26fa00ef 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -2,13 +2,82 @@ json_decode = function(d) { if (d && d.responseText) { d = Ext.util.JSON.decode(d.responseText) - d = d.entries; + if (d.entries) + d = d.entries; } else { d = [] } return d; } +/* + * ID node editor panel + */ +tvheadend.idnode_editor = function(item) +{ + var fields = [] + + for (var idx in item.params) { + var f = item.params[idx]; + var d = f.rdonly || false; + switch(f.type) { + case 'str': + fields.push({ + fieldLabel: f.caption, + name: f.id, + value: f.value, + disabled: d + }); + break; + + case 'bool': + fields.push({ + xtype: 'checkbox', + fieldLabel: f.caption, + name: f.id, + checked: f.value, + disabled: d + }); + break; + + case 'int': + case 'u32': + case 'u16': + fields.push(new Ext.form.NumberField({ + fieldLabel: f.caption, + name: f.id, + value: f.value, + disabled: d, + width : 300 + })); + break; + + case 'separator': + fields.push({ + xtype: 'label', + fieldLabel: f.caption + }); + break; + } + } + + var panel = new Ext.FormPanel({ + frame : true, + border : true, + bodyStyle : 'padding: 5px', + labelAlign : 'left', + labelWidth : 200, + autoWidth : true, + autoHeight : true, + defaultType : 'textfield', + buttonAlign : 'left', + items : fields, + //buttons : [ undoBtn, saveBtn ] + }); + return panel; +} + + /* * IDnode creation dialog */ @@ -156,6 +225,7 @@ tvheadend.idnode_grid = function(panel, conf) var undoBtn = null; var addBtn = null; var delBtn = null; + var editBtn = null; /* Process */ for (i = 0; i < d.length; i++) { @@ -229,6 +299,7 @@ tvheadend.idnode_grid = function(panel, conf) select.on('selectionchange', function(s){ if (delBtn) delBtn.setDisabled(s.getCount() == 0); + editBtn.setDisabled(s.getCount() != 1); }); /* Top bar */ @@ -273,6 +344,40 @@ tvheadend.idnode_grid = function(panel, conf) }); buttons.push(delBtn); } + buttons.push('-'); + editBtn = new Ext.Toolbar.Button({ + tooltip : 'Edit selected entry', + iconCls : 'edit', + text : 'Edit', + disabled : true, + handler : function() { + r = select.getSelected(); + if (r) { + Ext.Ajax.request({ + url : 'api/idnode', + params : { + op: 'get', + uuid: r.id + }, + success : function(d) + { + d = json_decode(d); + p = tvheadend.idnode_editor(d[0]); + w = new Ext.Window({ + title : 'Add ' + conf.title, + layout : 'fit', + autoWidth : true, + autoHeight : true, + plain : true, + items : p + }); + w.show(); + } + }); + } + } + }); + buttons.push(editBtn); buttons.push('->'); if (conf.help) { buttons.push({