Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
WEBUI/API: add multi-row (foreach) editor, fixes #3075
  • Loading branch information
perexg committed Oct 8, 2015
1 parent b48e32a commit 15bd982
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 26 deletions.
52 changes: 40 additions & 12 deletions src/api/api_idnode.c
Expand Up @@ -375,6 +375,7 @@ api_idnode_save
htsmsg_field_t *f;
const char *uuid;
int count = 0;
const idnodes_rb_t *domain = NULL;

if (!(f = htsmsg_field_find(args, "node")))
return EINVAL;
Expand All @@ -384,23 +385,49 @@ api_idnode_save

pthread_mutex_lock(&global_lock);

/* Single */
/* Single or Foreach */
if (!msg->hm_islist) {
if (!(uuid = htsmsg_get_str(msg, "uuid")))
goto exit;
if (!(in = idnode_find(uuid, NULL, NULL)))
goto exit;
if (idnode_perm(in, perm, msg)) {
err = EPERM;
goto exit;

if (!(uuid = htsmsg_get_str(msg, "uuid"))) {

/* Foreach */
f = htsmsg_field_find(msg, "uuid");
if (!(conf = htsmsg_field_get_list(f)))
goto exit;
HTSMSG_FOREACH(f, conf) {
if (!(uuid = htsmsg_field_get_str(f)))
continue;
if (!(in = idnode_find(uuid, NULL, domain)))
continue;
domain = in->in_domain;
if (idnode_perm(in, perm, msg)) {
err = EPERM;
continue;
}
count++;
idnode_update(in, msg);
idnode_perm_unset(in);
}
if (count)
err = 0;

} else {

if (!(in = idnode_find(uuid, NULL, NULL)))
goto exit;
if (idnode_perm(in, perm, msg)) {
err = EPERM;
goto exit;
}
idnode_update(in, msg);
idnode_perm_unset(in);
err = 0;

}
idnode_update(in, msg);
idnode_perm_unset(in);
err = 0;

/* Multiple */
} else {
const idnodes_rb_t *domain = NULL;

HTSMSG_FOREACH(f, msg) {
if (!(conf = htsmsg_field_get_map(f)))
continue;
Expand All @@ -419,6 +446,7 @@ api_idnode_save
}
if (count)
err = 0;

}

// TODO: return updated UUIDs?
Expand Down
88 changes: 74 additions & 14 deletions src/webui/static/app/idnode.js
Expand Up @@ -764,13 +764,40 @@ tvheadend.idnode_editor_form = function(d, meta, panel, conf)
var rf = [];
var df = [];
var groups = null;
var width = 0;

/* Fields */
for (var i = 0; i < d.length; i++) {
var p = d[i];
if (conf.uuids && p.rdonly)
continue;
var f = tvheadend.idnode_editor_field(p, conf);
if (!f)
continue;
if (conf.uuids) {
var label = f.fieldLabel;
f.fieldLabel = null;
var w = 15 + 10 + conf.labelWidth + 10 +
(f.initialConfig.width ? f.initialConfig.width : 100) + 10;
if (w > width)
width = w;
f = new Ext.form.CompositeField({
items: [
new Ext.ux.form.XCheckbox({
width: 15,
height: 12,
name: '_x_' + f.name
}),
{
xtype: 'displayfield',
width: conf.labelWidth,
height: 12,
value: label
},
f
]
});
}
if (p.group && meta.groups) {
if (!groups)
groups = {};
Expand Down Expand Up @@ -868,6 +895,20 @@ tvheadend.idnode_editor_form = function(d, meta, panel, conf)
panel.add(newFieldSet({ title: _("Read-only Info"), items: rf, collapsed: 'true'}));
}
panel.doLayout();
if (width)
panel.fixedWidth = width + 50;
if (conf.uuids) {
panel.getForm().getFieldValues = function(dirtyOnly) {
o = {};
this.items.each(function(f) {
var cbox = f.items.itemAt(0);
var field = f.items.itemAt(2);
if (cbox.getValue())
o[field.getName()] = field.getValue();
});
return o;
}
}
};

/*
Expand All @@ -885,7 +926,7 @@ tvheadend.idnode_editor = function(item, conf)
iconCls: 'save',
handler: function() {
var node = panel.getForm().getFieldValues();
node.uuid = item.uuid;
node.uuid = conf.uuids ? conf.uuids : item.uuid;
tvheadend.Ajax({
url: 'api/idnode/save',
params: {
Expand Down Expand Up @@ -916,7 +957,7 @@ tvheadend.idnode_editor = function(item, conf)
border: conf.inTabPanel ? false : true,
bodyStyle: 'padding: 5px',
labelAlign: 'left',
labelWidth: conf.labelWidth || 200,
labelWidth: conf.uuids ? 1 : (conf.labelWidth || 200),
autoWidth: conf.noautoWidth ? false : true,
autoHeight: !conf.fixedHeight,
width: conf.nowidth ? null : (conf.width || 600),
Expand All @@ -926,9 +967,12 @@ tvheadend.idnode_editor = function(item, conf)
buttons: buttons
});

tvheadend.idnode_editor_form(item.props || item.params, item.meta, panel,
{ showpwd: conf.showpwd });

var c = {
showpwd: conf.showpwd,
uuids: conf.uuids,
labelWidth: conf.labelWidth || 200
};
tvheadend.idnode_editor_form(item.props || item.params, item.meta, panel, c);
return panel;
};

Expand Down Expand Up @@ -1192,7 +1236,7 @@ tvheadend.idnode_grid = function(panel, conf)
abuttons.down.setDisabled(count === 0);
}
if (abuttons.edit)
abuttons.edit.setDisabled(count !== 1);
abuttons.edit.setDisabled(count === 0);
if (conf.selected)
conf.selected(s, abuttons);
});
Expand Down Expand Up @@ -1347,9 +1391,9 @@ tvheadend.idnode_grid = function(panel, conf)
text: _('Edit'),
disabled: true,
handler: function() {
var r = select.getSelected();
if (r) {
if (conf.edittree) {
if (conf.edittree) {
var r = select.getSelected();
if (r) {
var p = tvheadend.idnode_tree({
url: 'api/idnode/tree',
params: {
Expand All @@ -1367,11 +1411,17 @@ tvheadend.idnode_grid = function(panel, conf)
items: p
});
w.show();
} else {
}
} else {
var r = select.getSelections();
if (r && r.length > 0) {
var uuids = [];
for (var i = 0; i < r.length; i++)
uuids.push(r[i].id);
var params = {};
if (conf.edit && conf.edit.params)
params = conf.edit.params;
params['uuid'] = r.id;
params = conf.edit.params;
params['uuid'] = r[0].id;
params['meta'] = 1;
tvheadend.Ajax({
url: 'api/idnode/load',
Expand All @@ -1380,16 +1430,26 @@ tvheadend.idnode_grid = function(panel, conf)
d = json_decode(d);
var w = null;
var c = {win: w};
if (uuids.length > 1) {
var title = String.format(_('Edit {0} ({1} entries)'),
conf.titleS, uuids.length);
c.uuids = uuids;
} else {
var title = String.format(_('Edit {0}'), conf.titleS);
}
var p = tvheadend.idnode_editor(d[0], c);
var width = p.fixedWidth;
w = new Ext.Window({
title: String.format(_('Edit {0}'), conf.titleS),
title: title,
iconCls: 'edit',
layout: 'fit',
autoWidth: true,
autoWidth: width ? false : true,
autoHeight: true,
plain: true,
items: p
});
if (width)
w.setWidth(width);
c.win = w;
w.show();
}
Expand Down

0 comments on commit 15bd982

Please sign in to comment.