You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

574 lines
22 KiB

// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
(function ($) {
$.fn = $.extend($.fn, {
/**
* options:
* trackerId: int
* success: function (data) {}
*/
tracker_add_field: function (options) {
var dialog = this;
$('select', dialog).change(function () {
var descriptions = $(this).closest('.form-group').find('.form-text')
.hide();
if ($(this).val()) {
descriptions
.filter('.' + $(this).val())
.show();
}
}).change();
$('form', dialog).each(function () {
var form = this;
$(form.name).keyup(function () {
var val = $("#fieldPrefix").val() + " " + $(this).val();
val = removeDiacritics(val);
val = val.replace(/[^\w]+/g, '_');
val = val.replace(/_+([a-zA-Z])/g, function (parts) {
return parts[1].toUpperCase();
});
val = val.replace(/^[A-Z]/, function (parts) {
return parts[0].toLowerCase();
});
val = val.replace(/_+$/, '');
$(form.permName).val(val);
});
$(form.submit_and_edit).click(function () {
$(form.next).val('edit');
});
});
},
/**
* options:
* trackerId: int
* success: function (data) {}
*/
tracker_edit_field: function (options) {
this.serviceDialog({
title: tr('Edit Field'),
data: {
controller: 'tracker',
action: 'edit_field',
trackerId: options.trackerId,
fieldId: options.fieldId
},
load: function () {
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$('.groupselector', this).tiki('autocomplete', 'groupname', {
tiki_replace_term: function (term) {
return extractLast(term);
},
focus: function() {
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
},
success: options.success
});
return this;
},
tracker_load_fields: function (trackerId) {
var element = this;
this.each(function () {
var $container = $(this).empty();
element.tikiModal(tr('Loading...'));
$.getJSON($.service('tracker', 'list_fields'), {
trackerId: trackerId
}, function (data) {
element.tikiModal();
$.each(data.fields, function (k, field) {
var $row = $('<tr/>').addClass("tracker-field-" + field.type);
$row.append($('<td class="checkbox-cell"/>').append($('<input type="checkbox" name="fields[]"/>').val(field.fieldId)));
$row.append($('<td class="id"/>')
.text(field.fieldId)
.append($('<input type="hidden" name="field~' + field.fieldId + '~position"/>').val(field.position))
);
$row.append(
$('<td/>')
.append(
$('<div class="small">')
.text(field.permName)
.append(typeof navigator.clipboard === "object" && typeof navigator.clipboard.writeText === "function" ?
$('<a href="#" class="text-info pl-1 tips small" title="' + tr("Copy permanent name")
+ '"><span class="icon fas fa-copy"/></a>')
.click(function () {
navigator.clipboard.writeText(field.permName);
$(this).animate({opacity: .5}, 200, function () {
$(this).animate({opacity: 1}, 500);
});
return false;
}) : ""
)
)
.prepend($('<a/>')
.text(field.name == null?" ":field.name)
.attr('href', $.service('tracker', 'edit_field', {trackerId: trackerId, fieldId: field.fieldId, modal: 1}))
.clickModal({
success: function () {
$.fn.resetFieldsCache();
$container.tracker_load_fields(trackerId);
$.closeModal();
}
})
));
if (data.types[field.type]) {
$row.append($('<td/>').text(data.types[field.type].name));
if (field.options_map.mirrorField) {
$row.find('td:last').append($('<div class="small">').text(tr('Mirror field')+': '+field.options_map.mirrorField));
}
var addCheckbox = function (name, title, disabled = false) {
$row.append($('<td class="checkbox-cell"/>').append(
$('<input type="checkbox" name="field~' + field.fieldId + '~' + name + '" value="1" title="' + title + '"/>')
.prop('checked', field[name] === 'y').prop('disabled', disabled === true)
));
};
if ($("#rulesColumn").length) {
if (field.rules) {
let rulesString = "";
// reformat the ruels for a basic preview, slightly prettier than raw JSON
$.each(JSON.parse(field.rules), function (part, rule) {
rulesString += tr(part);
if (rule && rule.hasOwnProperty("predicates")) {
rulesString += " (" + tr(rule.logicalType_id) + "):\n";
rule.predicates.forEach(function (predicate) {
rulesString += " " + predicate.target_id + " " +
predicate.operator_id + " " +
(predicate.argument !== null ? "\"" + predicate.argument + "\"" : "") +
"\n";
})
} else {
rulesString += ":\n";
}
});
$row.append($('<td class="text-info" />').append(
$().getIcon("ok")
.attr("title", tr("Rules") + "|<pre>" + rulesString + "</pre>")
.addClass("tips")
).tiki_popover());
} else {
$row.append($('<td />'));
}
}
addCheckbox('isTblVisible', tr('List'));
addCheckbox('isMain', tr('Main'));
addCheckbox('isSearchable', tr('Searchable'), $.inArray(field.type, ['h']) !== -1);
addCheckbox('isPublic', tr('Public'));
addCheckbox('isMandatory', tr('Mandatory'));
$row.append($('<td class="action"/>').append($('<a href="#" class="text-danger"><span class="icon fas fa-times"/></a>')
.attr('href', $.service('tracker', 'remove_fields', {trackerId: trackerId, 'fields~0': field.fieldId}))
.requireConfirm({
message: tr('Removing the field will result in data loss. Are you sure?'),
success: function (data) {
$(this).closest('tr').remove();
$.fn.resetFieldsCache();
}
})
));
} else if (data.typesDisabled) {
if (data.typesDisabled[field.type]) {
$row.find('td:last')
.append(' - <a class="ui-state-error" href="tiki-admin.php?lm_criteria=' + data.typesDisabled[field.type].prefs.join('+') + '&exact">' + tr('(Disabled, Click to Enable)') + '</a>');
}
}
$container.append($row);
if (data.duplicates && data.duplicates[field.fieldId]) {
$.each(data.duplicates[field.fieldId], function (k, v) {
$row = $('<tr class="bg-warning"/>');
$row.append($('<td colspan="2"/>'));
$row.append($('<td colspan="8"/>')
.append(v.message)
);
$container.append($row);
});
}
});
});
});
return this;
},
tracker_get_inputs_from_form: function() {
var fields = {};
$.each($(this).serializeArray(), function() {
if (this.name.substr(-2) == '[]') {
if (typeof fields[this.name] === 'undefined') {
fields[this.name] = [];
}
fields[this.name].push(this.value);
} else {
fields[this.name] = this.value;
}
});
if ($(this).data('ajax')) {
fields['ajax'] = true;
}
return fields;
},
tracker_insert_item: function(options, fn) {
$.extend( options, $(this).tracker_get_inputs_from_form() );
$.tracker_insert_item(options, fn);
return this;
},
tracker_remove_item: function(options, fn) {
$.tracker_remove_item(options, fn);
return this;
},
tracker_update_item: function(options, fn) {
$.extend( options, $(this).tracker_get_inputs_from_form() );
$.tracker_update_item(options, fn);
return this;
},
tracker_get_item_inputs: function(options, fn) {
$.tracker_get_item_inputs(options, fn);
return this;
}
});
$ = $.extend($, {
tracker_insert_item: function(options, fn) {
options = $.extend({
controller: 'tracker',
action: 'insert_item',
trackerId: 0,
trackerName: '',
itemId: 0,
byName: false,
fields: {}
}, options);
$.ajax({
url: 'tiki-ajax_services.php',
dataType: 'json',
data: options,
type: 'post',
success: (fn ? fn : null),
});
},
tracker_remove_item: function(options, fn) {
options = $.extend({
controller: 'tracker',
action: 'remove_item',
trackerId: 0,
trackerName: '',
itemId: 0,
byName: false
}, options);
$.ajax({
url: 'tiki-ajax_services.php',
dataType: 'json',
data: options,
type: 'post',
success: (fn ? fn : null),
});
},
tracker_update_item: function(options, fn) {
options = $.extend({
controller: 'tracker',
action: 'update_item',
trackerId: 0,
trackerName: '',
itemId: 0,
byName: false,
fields: {}
}, options);
$.ajax({
url: 'tiki-ajax_services.php',
dataType: 'json',
data: options,
type: 'post',
success: (fn ? fn : null),
});
},
tracker_get_item_inputs: function(options, fn) {
options = $.extend({
controller: 'tracker',
action: 'get_item_inputs',
trackerId: 0,
trackerName: '',
itemId: 0,
byName: false,
defaults: {}
}, options);
$.ajax({
url: 'tiki-ajax_services.php',
dataType: 'json',
data: options,
type: 'post',
success: (fn ? fn : null)
});
}
});
// Tracker Tabular
$(document).on('click', '.use-odbc', function() {
if (this.checked) {
$('.odbc-container').show();
} else {
$('.odbc-container').hide();
}
});
$(document).on('click', '.use-api', function() {
if (this.checked) {
$('.api-container').show();
} else {
$('.api-container').hide();
}
});
$(document).on('mouseenter', '.edit-tabular tbody:not(.ui-sortable) .icon-sort', function () {
$(this).closest('tbody').filter(':not(.ui-sortable)').sortable({
handle: '.icon-sort',
stop: function () {
$(this).closest('table').trigger('tabular-update');
}
});
});
$(document).on('change', '.edit-tabular .selection', function () {
var value = $(this).val(), $add = $(this).closest('table').find('.add-field, .add-filter');
if (! $add.data('original-href')) {
$add.data('original-href', $add.attr('href'));
}
$add
.attr('href', $add.data('original-href') + '&permName=' + value);
});
$(document).on('click', '.edit-tabular .add-field', $.clickModal({
success: function (data) {
var $row;
if (typeof data.columnIndex !== "undefined") {
$row = $(this).closest('table').find("tbody tr:not(.d-none):eq(" + data.columnIndex + ")");
} else {
$row = $(this).closest('table').find('tbody tr.d-none').clone().removeClass('d-none').appendTo($(this).closest('table').find('tbody'));
}
$('.field-label', $row[0]).val(data.label);
$('.field', $row[0]).text(data.field);
$('.mode', $row[0]).text(data.mode);
$('.unique-key', $row[0]).prop('checked', data.isUniqueKey);
$('.read-only', $row[0]).prop('checked', data.isReadOnly);
$('.export-only', $row[0]).prop('checked', data.isExportOnly);
$(this).closest('table').trigger('tabular-update');
$.closeModal();
}
}));
$(document).on('click', '.edit-tabular .add-filter', $.clickModal({
success: function (data) {
var $row = $(this).closest('table').find('tbody tr.d-none').clone().removeClass('d-none').appendTo($(this).closest('table').find('tbody'));
$('.filter-label', $row[0]).val(data.label);
$('.field', $row[0]).text(data.field);
$('.mode', $row[0]).text(data.mode);
$(this).closest('table').trigger('tabular-update');
$.closeModal();
}
}));
$(document).on('click', '.edit-tabular .align-option', function (e) {
e.preventDefault();
var hash = this.href.substring(this.href.lastIndexOf('#') + 1);
$(this).closest('tr')
.find('.align').text($(this).text()).end()
.find('.display-align').val(hash).end()
;
$(this).closest('table').trigger('tabular-update');
});
$(document).on('click', '.edit-tabular .position-option', function (e) {
e.preventDefault();
var hash = this.href.substring(this.href.lastIndexOf('#') + 1);
$(this).closest('tr')
.find('.position-label').text($(this).text()).end()
.find('.position').val(hash).end()
;
$(this).closest('table').trigger('tabular-update');
});
$(document).on('click', '.edit-tabular .remove', function (e) {
var $table = $(this).closest('table');
e.preventDefault();
$(this).closest('tr').remove();
$table.trigger('tabular-update');
});
$(document).on('change', '.edit-tabular table :input', function (e) {
$(this).closest('table').trigger('tabular-update');
});
$(document).on('tabular-update', '.edit-tabular table.fields', function () {
var data = [], count = 0;
$('tbody tr:not(.d-none)', this).each(function () {
var $link = $(this).find("a.add-field");
if ($link.length) {
$link.attr("href", $link.attr("href").replace(/columnIndex=\d+/, "columnIndex=" + count));
count++;
}
data.push({
label: $('.field-label', this).val(),
field: $('.field', this).text(),
mode: $('.mode', this).text(),
remoteField: $('.remote-field', this).val(),
type: $('.type', this).val(),
displayAlign: $('.display-align', this).val(),
isUniqueKey: $('.unique-key', this).is(':checked'),
isReadOnly: $('.read-only', this).is(':checked'),
isExportOnly: $('.export-only', this).is(':checked'),
isPrimary: $('.primary', this).is(':checked')
});
});
$('textarea', this).val(JSON.stringify(data));
$(".edit-tabular").data("dirty", true);
});
$(document).on('tabular-update', '.edit-tabular table.filters', function () {
var data = [];
$('tbody tr:not(.d-none)', this).each(function () {
data.push({
label: $('.field-label', this).val(),
field: $('.field', this).text(),
mode: $('.mode', this).text(),
position: $('.position', this).val()
});
});
$('textarea', this).val(JSON.stringify(data));
$(".edit-tabular").data("dirty", true);
});
if ($(".edit-tabular").length) {
$(window).on("beforeunload", function () {
return $(".edit-tabular").data("dirty");
});
}
$(document).on('click', '.previewItemBtn', function (e) {
var trackerForm = $(this).parents('div.modal-content').find('form');
var trackerFormId = '#' + trackerForm[0].id;
var fields = {};
$.each($('input, select, textarea, radio, img', trackerFormId), function(k) {
var field = $(this);
var fieldType = field.attr('type');
var fieldName = field.attr('name');
var fieldValue = field.val();
if (fieldType == 'checkbox') {
var multicheck = $('input[name="' + fieldName + '"]:checked', trackerFormId);
fieldValue = [];
multicheck.each(function () {
fieldValue.push($(this).val());
});
}
if (fieldType == 'radio') {
fieldValue = $('input[name="' + fieldName + '"]:checked', trackerFormId).val();
}
if (fieldName) {
fieldName = fieldName.replace('[]', '');
}
fields[fieldName] = fieldValue;
});
var options = [];
options = $.extend({
controller: 'tracker',
action: 'preview_item',
fields : fields
}, options);
$.ajax({
url: 'tiki-ajax_services.php',
data: options,
type: 'post',
})
.done(function( html ) {
$('.previewTrackerItem').empty();
$('.previewTrackerItem').append(html);
$('.previewTrackerItem').append('<hr/>');
$('.previewTrackerItem').scroll();
document.getElementsByClassName('previewTrackerItem')[0].scrollIntoView();
});
});
// Global tracker field functions
$(document).on('mouseenter', '.currency_output', function(){
$('.'+$(this).attr('id')).removeClass('d-none');
});
$(document).on('mouseleave', '.currency_output', function(){
$('.'+$(this).attr('id')).addClass('d-none');
});
$(document).on('hidden.bs.modal', function (event) {
if (m = window.location.href.match(/item(\d+)|itemId=(\d+)/)) {
var itemId = m[1] || m[2];
$.getJSON($.service("semaphore", "unset"), {
object_id: itemId,
object_type: 'trackeritem'
});
}
});
}(jQuery));