mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 17:00:13 +02:00
Merge branch 'groups-ui' of github.com:AlexanderOtavka/hifi into groups
This commit is contained in:
commit
954c88188c
3 changed files with 316 additions and 82 deletions
|
@ -455,12 +455,16 @@
|
||||||
"name": "group_permissions",
|
"name": "group_permissions",
|
||||||
"type": "table",
|
"type": "table",
|
||||||
"caption": "Permissions for Users in Groups",
|
"caption": "Permissions for Users in Groups",
|
||||||
"can_add_new_rows": true,
|
"categorize_by_key": "permissions_id",
|
||||||
|
"can_add_new_categories": true,
|
||||||
|
"can_add_new_rows": false,
|
||||||
|
"new_category_placeholder": "Add Group",
|
||||||
|
"new_category_message": "Reload to see ranks",
|
||||||
|
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"label": "Group",
|
"label": "Rank",
|
||||||
"span": 2
|
"span": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in, as well as permissions from the previous section. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in, as well as permissions from the previous section. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||||
|
@ -471,7 +475,9 @@
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
"name": "permissions_id",
|
"name": "permissions_id",
|
||||||
"label": "Group Name"
|
"label": "Group Name",
|
||||||
|
"readonly": true,
|
||||||
|
"hidden": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rank_id",
|
"name": "rank_id",
|
||||||
|
@ -487,7 +493,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rank_name",
|
"name": "rank_name",
|
||||||
"label": "Rank Name",
|
"label": "",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -543,13 +549,17 @@
|
||||||
{
|
{
|
||||||
"name": "group_forbiddens",
|
"name": "group_forbiddens",
|
||||||
"type": "table",
|
"type": "table",
|
||||||
"caption": "Permissions denied to Users in Groups",
|
"caption": "Permissions Denied to Users in Groups",
|
||||||
"can_add_new_rows": true,
|
"categorize_by_key": "permissions_id",
|
||||||
|
"can_add_new_categories": true,
|
||||||
|
"can_add_new_rows": false,
|
||||||
|
"new_category_placeholder": "Add Blacklist Group",
|
||||||
|
"new_category_message": "Reload to see ranks",
|
||||||
|
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"label": "Group",
|
"label": "Rank",
|
||||||
"span": 2
|
"span": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
"label": "Permissions <a data-toggle='tooltip' data-html='true' title='<p><strong>Domain-Wide User Permissions</strong></p><ul><li><strong>Connect</strong><br />Sets whether users in specific groups can connect to the domain.</li><li><strong>Lock / Unlock</strong><br />Sets whether users in specific groups can change the “locked” property of an entity (either from on to off or off to on).</li><li><strong>Rez</strong><br />Sets whether users in specific groups can create new entities.</li><li><strong>Rez Temporary</strong><br />Sets whether users in specific groups can create new entities with a finite lifetime.</li><li><strong>Write Assets</strong><br />Sets whether users in specific groups can make changes to the domain’s asset-server assets.</li><li><strong>Ignore Max Capacity</strong><br />Sets whether user in specific groups can connect even if the domain has reached or exceeded its maximum allowed agents.</li></ul><p>Permissions granted to a specific user will be a union of the permissions granted to the groups they are in. Group permissions are only granted if the user doesn’t have their own row in the per-account section, below.</p>'>?</a>",
|
||||||
|
@ -560,7 +570,8 @@
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
"name": "permissions_id",
|
"name": "permissions_id",
|
||||||
"label": "Group Name"
|
"label": "Group Name",
|
||||||
|
"hidden": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rank_id",
|
"name": "rank_id",
|
||||||
|
@ -574,7 +585,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rank_name",
|
"name": "rank_name",
|
||||||
"label": "Rank Name",
|
"label": "",
|
||||||
"readonly": true
|
"readonly": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,10 @@ body {
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.table-lead .lead-line {
|
.table-lead .lead-line {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +24,9 @@ body {
|
||||||
top: 40px;
|
top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table .value-row td, .table .inputs td {
|
.table .value-row td,
|
||||||
|
.table .value-category td,
|
||||||
|
.table .inputs td {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +37,31 @@ body {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.value-category:not(.inputs) {
|
||||||
|
font-weight: bold;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .value-category [message]::after {
|
||||||
|
content: attr(message);
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .value-row.contracted,
|
||||||
|
.table .inputs.contracted {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-category {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-category-icon {
|
||||||
|
padding: 4px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.glyphicon-remove {
|
.glyphicon-remove {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,20 @@ var Settings = {
|
||||||
TRIGGER_CHANGE_CLASS: 'trigger-change',
|
TRIGGER_CHANGE_CLASS: 'trigger-change',
|
||||||
DATA_ROW_CLASS: 'value-row',
|
DATA_ROW_CLASS: 'value-row',
|
||||||
DATA_COL_CLASS: 'value-col',
|
DATA_COL_CLASS: 'value-col',
|
||||||
|
DATA_CATEGORY_CLASS: 'value-category',
|
||||||
ADD_ROW_BUTTON_CLASS: 'add-row',
|
ADD_ROW_BUTTON_CLASS: 'add-row',
|
||||||
ADD_ROW_SPAN_CLASSES: 'glyphicon glyphicon-plus add-row',
|
ADD_ROW_SPAN_CLASSES: 'glyphicon glyphicon-plus add-row',
|
||||||
DEL_ROW_BUTTON_CLASS: 'del-row',
|
DEL_ROW_BUTTON_CLASS: 'del-row',
|
||||||
DEL_ROW_SPAN_CLASSES: 'glyphicon glyphicon-remove del-row',
|
DEL_ROW_SPAN_CLASSES: 'glyphicon glyphicon-remove del-row',
|
||||||
|
ADD_CATEGORY_BUTTON_CLASS: 'add-category',
|
||||||
|
ADD_CATEGORY_SPAN_CLASSES: 'glyphicon glyphicon-plus add-category',
|
||||||
|
TOGGLE_CATEGORY_COLUMN_CLASS: 'toggle-category',
|
||||||
|
TOGGLE_CATEGORY_SPAN_CLASS: 'toggle-category-icon',
|
||||||
|
TOGGLE_CATEGORY_SPAN_CLASSES: 'glyphicon toggle-category-icon',
|
||||||
|
TOGGLE_CATEGORY_EXPANDED_CLASS: 'glyphicon-triangle-bottom',
|
||||||
|
TOGGLE_CATEGORY_CONTRACTED_CLASS: 'glyphicon-triangle-right',
|
||||||
|
DEL_CATEGORY_BUTTON_CLASS: 'del-category',
|
||||||
|
DEL_CATEGORY_SPAN_CLASSES: 'glyphicon glyphicon-remove del-category',
|
||||||
MOVE_UP_BUTTON_CLASS: 'move-up',
|
MOVE_UP_BUTTON_CLASS: 'move-up',
|
||||||
MOVE_UP_SPAN_CLASSES: 'glyphicon glyphicon-chevron-up move-up',
|
MOVE_UP_SPAN_CLASSES: 'glyphicon glyphicon-chevron-up move-up',
|
||||||
MOVE_DOWN_BUTTON_CLASS: 'move-down',
|
MOVE_DOWN_BUTTON_CLASS: 'move-down',
|
||||||
|
@ -37,7 +47,7 @@ var viewHelpers = {
|
||||||
form_group = "<div class='form-group " + (isAdvanced ? Settings.ADVANCED_CLASS : "") + "' data-keypath='" + keypath + "'>";
|
form_group = "<div class='form-group " + (isAdvanced ? Settings.ADVANCED_CLASS : "") + "' data-keypath='" + keypath + "'>";
|
||||||
setting_value = _(values).valueForKeyPath(keypath);
|
setting_value = _(values).valueForKeyPath(keypath);
|
||||||
|
|
||||||
if (typeof setting_value == 'undefined' || setting_value === null) {
|
if (_.isUndefined(setting_value) || _.isNull(setting_value)) {
|
||||||
if (_.has(setting, 'default')) {
|
if (_.has(setting, 'default')) {
|
||||||
setting_value = setting.default;
|
setting_value = setting.default;
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,11 +61,11 @@ var viewHelpers = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function common_attrs(extra_classes) {
|
function common_attrs(extra_classes) {
|
||||||
extra_classes = (typeof extra_classes !== 'undefined' ? extra_classes : "");
|
extra_classes = (!_.isUndefined(extra_classes) ? extra_classes : "");
|
||||||
return " class='" + (setting.type !== 'checkbox' ? 'form-control' : '')
|
return " class='" + (setting.type !== 'checkbox' ? 'form-control' : '')
|
||||||
+ " " + Settings.TRIGGER_CHANGE_CLASS + " " + extra_classes + "' data-short-name='"
|
+ " " + Settings.TRIGGER_CHANGE_CLASS + " " + extra_classes + "' data-short-name='"
|
||||||
+ setting.name + "' name='" + keypath + "' "
|
+ setting.name + "' name='" + keypath + "' "
|
||||||
+ "id='" + (typeof setting.html_id !== 'undefined' ? setting.html_id : keypath) + "'";
|
+ "id='" + (!_.isUndefined(setting.html_id) ? setting.html_id : keypath) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting.type === 'checkbox') {
|
if (setting.type === 'checkbox') {
|
||||||
|
@ -164,19 +174,31 @@ $(document).ready(function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#' + Settings.FORM_ID).on('click', '.' + Settings.ADD_ROW_BUTTON_CLASS, function(){
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.ADD_ROW_BUTTON_CLASS, function(){
|
||||||
addTableRow(this);
|
addTableRow($(this).closest('tr'));
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#' + Settings.FORM_ID).on('click', '.' + Settings.DEL_ROW_BUTTON_CLASS, function(){
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.DEL_ROW_BUTTON_CLASS, function(){
|
||||||
deleteTableRow(this);
|
deleteTableRow($(this).closest('tr'));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.ADD_CATEGORY_BUTTON_CLASS, function(){
|
||||||
|
addTableCategory($(this).closest('tr'));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.DEL_CATEGORY_BUTTON_CLASS, function(){
|
||||||
|
deleteTableCategory($(this).closest('tr'));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.TOGGLE_CATEGORY_COLUMN_CLASS, function(){
|
||||||
|
toggleTableCategory($(this).closest('tr'));
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#' + Settings.FORM_ID).on('click', '.' + Settings.MOVE_UP_BUTTON_CLASS, function(){
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.MOVE_UP_BUTTON_CLASS, function(){
|
||||||
moveTableRow(this, true);
|
moveTableRow($(this).closest('tr'), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#' + Settings.FORM_ID).on('click', '.' + Settings.MOVE_DOWN_BUTTON_CLASS, function(){
|
$('#' + Settings.FORM_ID).on('click', '.' + Settings.MOVE_DOWN_BUTTON_CLASS, function(){
|
||||||
moveTableRow(this, false);
|
moveTableRow($(this).closest('tr'), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#' + Settings.FORM_ID).on('keyup', function(e){
|
$('#' + Settings.FORM_ID).on('keyup', function(e){
|
||||||
|
@ -198,10 +220,11 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sibling.hasClass(Settings.ADD_DEL_BUTTONS_CLASS)) {
|
if (sibling.hasClass(Settings.ADD_DEL_BUTTONS_CLASS)) {
|
||||||
sibling.find('.' + Settings.ADD_ROW_BUTTON_CLASS).click()
|
sibling.find('.' + Settings.ADD_ROW_BUTTON_CLASS).click();
|
||||||
|
sibling.find("." + Settings.ADD_CATEGORY_BUTTON_CLASS).click();
|
||||||
|
|
||||||
// set focus to the first input in the new row
|
// set focus to the first input in the new row
|
||||||
$target.closest('table').find('tr.inputs input:first').focus()
|
$target.closest('table').find('tr.inputs input:first').focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,8 +947,9 @@ $('body').on('click', '.save-button', function(e){
|
||||||
|
|
||||||
function makeTable(setting, keypath, setting_value, isLocked) {
|
function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
var isArray = !_.has(setting, 'key');
|
var isArray = !_.has(setting, 'key');
|
||||||
var isHash = !isArray;
|
var categoryKey = setting.categorize_by_key;
|
||||||
|
var isCategorized = !!categoryKey && isArray;
|
||||||
|
|
||||||
if (!isArray && setting.can_order) {
|
if (!isArray && setting.can_order) {
|
||||||
setting.can_order = false;
|
setting.can_order = false;
|
||||||
}
|
}
|
||||||
|
@ -939,9 +963,10 @@ function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
var nonDeletableRowKey = setting["non-deletable-row-key"];
|
var nonDeletableRowKey = setting["non-deletable-row-key"];
|
||||||
var nonDeletableRowValues = setting["non-deletable-row-values"];
|
var nonDeletableRowValues = setting["non-deletable-row-values"];
|
||||||
|
|
||||||
html += "<table class='table table-bordered " + (isLocked ? "locked-table" : "") + "' data-short-name='" + setting.name
|
html += "<table class='table table-bordered " + (isLocked ? "locked-table" : "") + "' " +
|
||||||
+ "' name='" + keypath + "' id='" + (typeof setting.html_id !== 'undefined' ? setting.html_id : keypath)
|
"data-short-name='" + setting.name + "' name='" + keypath + "' " +
|
||||||
+ "' data-setting-type='" + (isArray ? 'array' : 'hash') + "'>";
|
"id='" + (!_.isUndefined(setting.html_id) ? setting.html_id : keypath) + "' " +
|
||||||
|
"data-setting-type='" + (isArray ? 'array' : 'hash') + "'>";
|
||||||
|
|
||||||
if (setting.caption) {
|
if (setting.caption) {
|
||||||
html += "<caption>" + setting.caption + "</caption>"
|
html += "<caption>" + setting.caption + "</caption>"
|
||||||
|
@ -974,25 +999,43 @@ function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
html += "<td class='key'><strong>" + setting.key.label + "</strong></td>" // Key
|
html += "<td class='key'><strong>" + setting.key.label + "</strong></td>" // Key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var numVisibleColumns = 0;
|
||||||
_.each(setting.columns, function(col) {
|
_.each(setting.columns, function(col) {
|
||||||
|
if (!col.hidden) numVisibleColumns++;
|
||||||
html += "<td " + (col.hidden ? "style='display: none;'" : "") + "class='data " +
|
html += "<td " + (col.hidden ? "style='display: none;'" : "") + "class='data " +
|
||||||
(col.class ? col.class : '') + "'><strong>" + col.label + "</strong></td>" // Data
|
(col.class ? col.class : '') + "'><strong>" + col.label + "</strong></td>" // Data
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!isLocked && !setting.read_only) {
|
if (!isLocked && !setting.read_only) {
|
||||||
if (setting.can_order) {
|
if (setting.can_order) {
|
||||||
|
numVisibleColumns++;
|
||||||
html += "<td class='" + Settings.REORDER_BUTTONS_CLASSES +
|
html += "<td class='" + Settings.REORDER_BUTTONS_CLASSES +
|
||||||
"'><a href='javascript:void(0);' class='glyphicon glyphicon-sort'></a></td>";
|
"'><a href='javascript:void(0);' class='glyphicon glyphicon-sort'></a></td>";
|
||||||
}
|
}
|
||||||
html += "<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES + "'></td></tr>"
|
numVisibleColumns++;
|
||||||
|
html += "<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES + "'></td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate rows in the table from existing values
|
// populate rows in the table from existing values
|
||||||
var row_num = 1;
|
var row_num = 1;
|
||||||
|
|
||||||
if (keypath.length > 0 && _.size(setting_value) > 0) {
|
if (keypath.length > 0 && _.size(setting_value) > 0) {
|
||||||
|
var rowIsObject = setting.columns.length > 1;
|
||||||
|
|
||||||
_.each(setting_value, function(row, rowIndexOrName) {
|
_.each(setting_value, function(row, rowIndexOrName) {
|
||||||
html += "<tr class='" + Settings.DATA_ROW_CLASS + "'" + (isArray ? "" : "name='" + keypath + "." + rowIndexOrName + "'") + ">"
|
var categoryPair = {};
|
||||||
|
var categoryValue = "";
|
||||||
|
if (isCategorized) {
|
||||||
|
categoryValue = rowIsObject ? row[categoryKey] : row;
|
||||||
|
categoryPair[categoryKey] = categoryValue;
|
||||||
|
if (_.findIndex(setting_value, categoryPair) === rowIndexOrName) {
|
||||||
|
html += makeTableCategoryHeader(categoryKey, categoryValue, numVisibleColumns, setting.can_add_new_categories, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "<tr class='" + Settings.DATA_ROW_CLASS + "' " +
|
||||||
|
(isCategorized ? ("data-category='" + categoryValue + "'") : "") + " " +
|
||||||
|
(isArray ? "" : "name='" + keypath + "." + rowIndexOrName + "'") + ">";
|
||||||
|
|
||||||
if (setting.numbered === true) {
|
if (setting.numbered === true) {
|
||||||
html += "<td class='numbered'>" + row_num + "</td>"
|
html += "<td class='numbered'>" + row_num + "</td>"
|
||||||
|
@ -1006,8 +1049,8 @@ function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
|
|
||||||
_.each(setting.columns, function(col) {
|
_.each(setting.columns, function(col) {
|
||||||
|
|
||||||
|
var colValue, colName;
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
rowIsObject = setting.columns.length > 1;
|
|
||||||
colValue = rowIsObject ? row[col.name] : row;
|
colValue = rowIsObject ? row[col.name] : row;
|
||||||
colName = keypath + "[" + rowIndexOrName + "]" + (rowIsObject ? "." + col.name : "");
|
colName = keypath + "[" + rowIndexOrName + "]" + (rowIsObject ? "." + col.name : "");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1019,21 +1062,28 @@ function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
|| (nonDeletableRowKey === col.name && nonDeletableRowValues.indexOf(colValue) !== -1);
|
|| (nonDeletableRowKey === col.name && nonDeletableRowValues.indexOf(colValue) !== -1);
|
||||||
|
|
||||||
if (isArray && col.type === "checkbox" && col.editable) {
|
if (isArray && col.type === "checkbox" && col.editable) {
|
||||||
html += "<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>"
|
html +=
|
||||||
+ "<input type='checkbox' class='form-control table-checkbox' "
|
"<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>" +
|
||||||
+ "name='" + colName + "'" + (colValue ? " checked" : "") + " /></td>";
|
"<input type='checkbox' class='form-control table-checkbox' " +
|
||||||
|
"name='" + colName + "'" + (colValue ? " checked" : "") + "/>" +
|
||||||
|
"</td>";
|
||||||
} else if (isArray && col.type === "time" && col.editable) {
|
} else if (isArray && col.type === "time" && col.editable) {
|
||||||
html += "<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>"
|
html +=
|
||||||
+ "<input type='time' class='form-control table-time' "
|
"<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>" +
|
||||||
+ "name='" + colName + "' value='" + (colValue || col.default || "00:00") + "' /></td>";
|
"<input type='time' class='form-control table-time' name='" + colName + "' " +
|
||||||
|
"value='" + (colValue || col.default || "00:00") + "'/>" +
|
||||||
|
"</td>";
|
||||||
} else {
|
} else {
|
||||||
// Use a hidden input so that the values are posted.
|
// Use a hidden input so that the values are posted.
|
||||||
html += "<td " + (col.hidden ? "style='display: none;'" : "") + "class='" + Settings.DATA_COL_CLASS +
|
html +=
|
||||||
"' name='" + colName + "'>" + colValue + "<input type='hidden' name='" + colName +
|
"<td class='" + Settings.DATA_COL_CLASS + "' " + (col.hidden ? "style='display: none;'" : "") +
|
||||||
"' value='" + colValue + "'/></td>";
|
"name='" + colName + "'>" +
|
||||||
|
colValue +
|
||||||
|
"<input type='hidden' name='" + colName + "' value='" + colValue + "'/>" +
|
||||||
|
"</td>";
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
||||||
|
|
||||||
if (!isLocked && !setting.read_only) {
|
if (!isLocked && !setting.read_only) {
|
||||||
if (setting.can_order) {
|
if (setting.can_order) {
|
||||||
|
@ -1051,24 +1101,53 @@ function makeTable(setting, keypath, setting_value, isLocked) {
|
||||||
|
|
||||||
html += "</tr>"
|
html += "</tr>"
|
||||||
|
|
||||||
|
if (isCategorized && setting.can_add_new_rows && _.findLastIndex(setting_value, categoryPair) === rowIndexOrName) {
|
||||||
|
html += makeTableInputs(setting, categoryPair, categoryValue);
|
||||||
|
}
|
||||||
|
|
||||||
row_num++
|
row_num++
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate inputs in the table for new values
|
// populate inputs in the table for new values
|
||||||
if (!isLocked && !setting.read_only && setting.can_add_new_rows) {
|
if (!isLocked && !setting.read_only) {
|
||||||
html += makeTableInputs(setting)
|
if (setting.can_add_new_categories) {
|
||||||
|
html += makeTableCategoryInput(setting, numVisibleColumns);
|
||||||
|
}
|
||||||
|
if (setting.can_add_new_rows || setting.can_add_new_categories) {
|
||||||
|
html += makeTableInputs(setting, {}, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
html += "</table>"
|
html += "</table>"
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTableInputs(setting) {
|
function makeTableCategoryHeader(categoryKey, categoryValue, numVisibleColumns, canRemove, message) {
|
||||||
var html = "<tr class='inputs'>"
|
var html =
|
||||||
|
"<tr class='" + Settings.DATA_CATEGORY_CLASS + "' data-key='" + categoryKey + "' data-category='" + categoryValue + "'>" +
|
||||||
|
"<td colspan='" + (numVisibleColumns - 1) + "' class='" + Settings.TOGGLE_CATEGORY_COLUMN_CLASS + "'>" +
|
||||||
|
"<span class='" + Settings.TOGGLE_CATEGORY_SPAN_CLASSES + " " + Settings.TOGGLE_CATEGORY_EXPANDED_CLASS + "'></span>" +
|
||||||
|
"<span message='" + message + "'>" + categoryValue + "</span>" +
|
||||||
|
"</td>" +
|
||||||
|
((canRemove) ? (
|
||||||
|
"<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES + "'>" +
|
||||||
|
"<a href='javascript:void(0);' class='" + Settings.DEL_CATEGORY_SPAN_CLASSES + "'></a>" +
|
||||||
|
"</td>"
|
||||||
|
) : (
|
||||||
|
"<td></td>"
|
||||||
|
)) +
|
||||||
|
"</tr>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeTableInputs(setting, initialValues, categoryValue) {
|
||||||
|
var html = "<tr class='inputs'" + (setting.can_add_new_categories && !categoryValue ? " hidden" : "") + " " +
|
||||||
|
(categoryValue ? ("data-category='" + categoryValue + "'") : "") + " " +
|
||||||
|
(setting.categorize_by_key ? ("data-keep-field='" + setting.categorize_by_key + "'") : "") + ">";
|
||||||
|
|
||||||
if (setting.numbered === true) {
|
if (setting.numbered === true) {
|
||||||
html += "<td class='numbered'></td>"
|
html += "<td class='numbered'></td>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting.key) {
|
if (setting.key) {
|
||||||
|
@ -1078,15 +1157,21 @@ function makeTableInputs(setting) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_.each(setting.columns, function(col) {
|
_.each(setting.columns, function(col) {
|
||||||
|
var defaultValue = _.has(initialValues, col.name) ? initialValues[col.name] : col.default;
|
||||||
if (col.type === "checkbox") {
|
if (col.type === "checkbox") {
|
||||||
html += "<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>"
|
html +=
|
||||||
+ "<input type='checkbox' class='form-control table-checkbox' "
|
"<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>" +
|
||||||
+ "name='" + col.name + "'" + (col.default ? " checked" : "") + "/></td>";
|
"<input type='checkbox' class='form-control table-checkbox' " +
|
||||||
|
"name='" + col.name + "'" + (defaultValue ? " checked" : "") + "/>" +
|
||||||
|
"</td>";
|
||||||
} else {
|
} else {
|
||||||
html += "<td " + (col.hidden ? "style='display: none;'" : "") + "class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>\
|
html +=
|
||||||
<input type='text' class='form-control' placeholder='" + (col.placeholder ? col.placeholder : "") + "'\
|
"<td " + (col.hidden ? "style='display: none;'" : "") + " class='" + Settings.DATA_COL_CLASS + "' " +
|
||||||
value='" + (col.default ? col.default : "") + "' data-default='" + (col.default ? col.default : "") + "'" + (col.readonly ? " readonly" : "") + ">\
|
"name='" + col.name + "'>" +
|
||||||
</td>"
|
"<input type='text' class='form-control' placeholder='" + (col.placeholder ? col.placeholder : "") + "' " +
|
||||||
|
"value='" + (defaultValue || "") + "' data-default='" + (defaultValue || "") + "'" +
|
||||||
|
(col.readonly ? " readonly" : "") + ">" +
|
||||||
|
"</td>";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1094,12 +1179,30 @@ function makeTableInputs(setting) {
|
||||||
html += "<td class='" + Settings.REORDER_BUTTONS_CLASSES + "'></td>"
|
html += "<td class='" + Settings.REORDER_BUTTONS_CLASSES + "'></td>"
|
||||||
}
|
}
|
||||||
html += "<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES +
|
html += "<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES +
|
||||||
"'><a href='javascript:void(0);' class='glyphicon glyphicon-plus " + Settings.ADD_ROW_BUTTON_CLASS + "'></a></td>"
|
"'><a href='javascript:void(0);' class='" + Settings.ADD_ROW_SPAN_CLASSES + "'></a></td>"
|
||||||
html += "</tr>"
|
html += "</tr>"
|
||||||
|
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeTableCategoryInput(setting, numVisibleColumns) {
|
||||||
|
var canAddRows = setting.can_add_new_rows;
|
||||||
|
var categoryKey = setting.categorize_by_key;
|
||||||
|
var placeholder = setting.new_category_placeholder || "";
|
||||||
|
var message = setting.new_category_message || "";
|
||||||
|
var html =
|
||||||
|
"<tr class='" + Settings.DATA_CATEGORY_CLASS + " inputs' data-can-add-rows='" + canAddRows + "' " +
|
||||||
|
"data-key='" + categoryKey + "' data-message='" + message + "'>" +
|
||||||
|
"<td colspan='" + (numVisibleColumns - 1) + "'>" +
|
||||||
|
"<input type='text' class='form-control' placeholder='" + placeholder + "'/>" +
|
||||||
|
"</td>" +
|
||||||
|
"<td class='" + Settings.ADD_DEL_BUTTONS_CLASSES + "'>" +
|
||||||
|
"<a href='javascript:void(0);' class='" + Settings.ADD_CATEGORY_SPAN_CLASSES + "'></a>" +
|
||||||
|
"</td>" +
|
||||||
|
"</tr>";
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
function badgeSidebarForDifferences(changedElement) {
|
function badgeSidebarForDifferences(changedElement) {
|
||||||
// figure out which group this input is in
|
// figure out which group this input is in
|
||||||
var panelParentID = changedElement.closest('.panel').attr('id');
|
var panelParentID = changedElement.closest('.panel').attr('id');
|
||||||
|
@ -1138,13 +1241,12 @@ function badgeSidebarForDifferences(changedElement) {
|
||||||
$("a[href='#" + panelParentID + "'] .badge").html(badgeValue);
|
$("a[href='#" + panelParentID + "'] .badge").html(badgeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTableRow(add_glyphicon) {
|
function addTableRow(row) {
|
||||||
var row = $(add_glyphicon).closest('tr')
|
var table = row.parents('table');
|
||||||
|
var isArray = table.data('setting-type') === 'array';
|
||||||
|
var keepField = row.data("keep-field");
|
||||||
|
|
||||||
var table = row.parents('table')
|
var columns = row.parent().children('.' + Settings.DATA_ROW_CLASS);
|
||||||
var isArray = table.data('setting-type') === 'array'
|
|
||||||
|
|
||||||
var columns = row.parent().children('.' + Settings.DATA_ROW_CLASS)
|
|
||||||
|
|
||||||
if (!isArray) {
|
if (!isArray) {
|
||||||
// Check key spaces
|
// Check key spaces
|
||||||
|
@ -1261,10 +1363,12 @@ function addTableRow(add_glyphicon) {
|
||||||
} else {
|
} else {
|
||||||
console.log("Unknown table element")
|
console.log("Unknown table element")
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
input_clone.find('input').each(function(){
|
input_clone.children('td').each(function () {
|
||||||
$(this).val($(this).attr('data-default'));
|
if ($(this).attr("name") !== keepField) {
|
||||||
|
$(this).find("input").val($(this).attr('data-default'));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isArray) {
|
if (isArray) {
|
||||||
|
@ -1276,44 +1380,132 @@ function addTableRow(add_glyphicon) {
|
||||||
|
|
||||||
badgeSidebarForDifferences($(table))
|
badgeSidebarForDifferences($(table))
|
||||||
|
|
||||||
row.parent().append(input_clone)
|
row.after(input_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteTableRow(delete_glyphicon) {
|
function deleteTableRow($row) {
|
||||||
var row = $(delete_glyphicon).closest('tr')
|
var $table = $row.closest('table');
|
||||||
|
var categoryName = $row.data("category");
|
||||||
|
var isArray = $table.data('setting-type') === 'array';
|
||||||
|
|
||||||
var table = $(row).closest('table')
|
$row.empty();
|
||||||
var isArray = table.data('setting-type') === 'array'
|
|
||||||
|
|
||||||
row.empty();
|
|
||||||
|
|
||||||
if (!isArray) {
|
if (!isArray) {
|
||||||
row.html("<input type='hidden' class='form-control' name='"
|
$row.html("<input type='hidden' class='form-control' name='" + $row.attr('name') + "' data-changed='true' value=''>");
|
||||||
+ row.attr('name') + "' data-changed='true' value=''>");
|
|
||||||
} else {
|
} else {
|
||||||
if (table.find('.' + Settings.DATA_ROW_CLASS).length > 1) {
|
if ($table.find('.' + Settings.DATA_ROW_CLASS + "[data-category='" + categoryName + "']").length <= 1) {
|
||||||
updateDataChangedForSiblingRows(row)
|
// This is the last row of the category, so delete the header
|
||||||
|
$table.find('.' + Settings.DATA_CATEGORY_CLASS + "[data-category='" + categoryName + "']").remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($table.find('.' + Settings.DATA_ROW_CLASS).length > 1) {
|
||||||
|
updateDataChangedForSiblingRows($row);
|
||||||
|
|
||||||
// this isn't the last row - we can just remove it
|
// this isn't the last row - we can just remove it
|
||||||
row.remove()
|
$row.remove();
|
||||||
} else {
|
} else {
|
||||||
// this is the last row, we can't remove it completely since we need to post an empty array
|
// this is the last row, we can't remove it completely since we need to post an empty array
|
||||||
|
$row
|
||||||
row.removeClass(Settings.DATA_ROW_CLASS).removeClass(Settings.NEW_ROW_CLASS)
|
.removeClass(Settings.DATA_ROW_CLASS)
|
||||||
row.addClass('empty-array-row')
|
.removeClass(Settings.NEW_ROW_CLASS)
|
||||||
|
.removeAttr("data-category")
|
||||||
row.html("<input type='hidden' class='form-control' name='" + table.attr("name").replace('[]', '')
|
.addClass('empty-array-row')
|
||||||
+ "' data-changed='true' value=''>");
|
.html("<input type='hidden' class='form-control' name='" + $table.attr("name").replace('[]', '') + "' " +
|
||||||
|
"data-changed='true' value=''>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need to fire a change event on one of the remaining inputs so that the sidebar badge is updated
|
// we need to fire a change event on one of the remaining inputs so that the sidebar badge is updated
|
||||||
badgeSidebarForDifferences($(table))
|
badgeSidebarForDifferences($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveTableRow(move_glyphicon, move_up) {
|
function addTableCategory($categoryInputRow) {
|
||||||
var row = $(move_glyphicon).closest('tr')
|
var $input = $categoryInputRow.find("input").first();
|
||||||
|
var categoryValue = $input.prop("value");
|
||||||
|
if (!categoryValue || $categoryInputRow.closest("table").find("tr[data-category='" + categoryValue + "']").length !== 0) {
|
||||||
|
$categoryInputRow.addClass("has-warning");
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
$categoryInputRow.removeClass("has-warning");
|
||||||
|
}, 400);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $rowInput = $categoryInputRow.next(".inputs").clone();
|
||||||
|
if (!$rowInput) {
|
||||||
|
console.error("Error cloning inputs");
|
||||||
|
}
|
||||||
|
|
||||||
|
var canAddRows = $categoryInputRow.data("can-add-rows");
|
||||||
|
var message = $categoryInputRow.data("message");
|
||||||
|
var categoryKey = $categoryInputRow.data("key");
|
||||||
|
var width = 0;
|
||||||
|
$categoryInputRow
|
||||||
|
.children("td")
|
||||||
|
.each(function () {
|
||||||
|
width += $(this).prop("colSpan") || 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
$input
|
||||||
|
.prop("value", "")
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
$rowInput.find("td[name='" + categoryKey + "'] > input").first()
|
||||||
|
.prop("value", categoryValue);
|
||||||
|
$rowInput
|
||||||
|
.attr("data-category", categoryValue)
|
||||||
|
.addClass(Settings.NEW_ROW_CLASS);
|
||||||
|
|
||||||
|
var $newCategoryRow = $(makeTableCategoryHeader(categoryKey, categoryValue, width, true, " - " + message));
|
||||||
|
$newCategoryRow.addClass(Settings.NEW_ROW_CLASS);
|
||||||
|
|
||||||
|
$categoryInputRow
|
||||||
|
.before($newCategoryRow)
|
||||||
|
.before($rowInput);
|
||||||
|
|
||||||
|
if (canAddRows) {
|
||||||
|
$rowInput.removeAttr("hidden");
|
||||||
|
} else {
|
||||||
|
addTableRow($rowInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTableCategory($categoryHeaderRow) {
|
||||||
|
var categoryName = $categoryHeaderRow.data("category");
|
||||||
|
|
||||||
|
$categoryHeaderRow
|
||||||
|
.closest("table")
|
||||||
|
.find("tr[data-category='" + categoryName + "']")
|
||||||
|
.each(function () {
|
||||||
|
if ($(this).hasClass(Settings.DATA_ROW_CLASS)) {
|
||||||
|
deleteTableRow($(this));
|
||||||
|
} else {
|
||||||
|
$(this).remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTableCategory($categoryHeaderRow) {
|
||||||
|
var $icon = $categoryHeaderRow.find("." + Settings.TOGGLE_CATEGORY_SPAN_CLASS).first();
|
||||||
|
var categoryName = $categoryHeaderRow.data("category");
|
||||||
|
var wasExpanded = $icon.hasClass(Settings.TOGGLE_CATEGORY_EXPANDED_CLASS);
|
||||||
|
if (wasExpanded) {
|
||||||
|
$icon
|
||||||
|
.addClass(Settings.TOGGLE_CATEGORY_CONTRACTED_CLASS)
|
||||||
|
.removeClass(Settings.TOGGLE_CATEGORY_EXPANDED_CLASS);
|
||||||
|
} else {
|
||||||
|
$icon
|
||||||
|
.addClass(Settings.TOGGLE_CATEGORY_EXPANDED_CLASS)
|
||||||
|
.removeClass(Settings.TOGGLE_CATEGORY_CONTRACTED_CLASS);
|
||||||
|
}
|
||||||
|
$categoryHeaderRow
|
||||||
|
.closest("table")
|
||||||
|
.find("tr[data-category='" + categoryName + "']")
|
||||||
|
.toggleClass("contracted", wasExpanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveTableRow(row, move_up) {
|
||||||
var table = $(row).closest('table')
|
var table = $(row).closest('table')
|
||||||
var isArray = table.data('setting-type') === 'array'
|
var isArray = table.data('setting-type') === 'array'
|
||||||
if (!isArray) {
|
if (!isArray) {
|
||||||
|
|
Loading…
Reference in a new issue