diff --git a/admin/calendar.php b/admin/calendar.php index a3256299..e8dc6aa9 100644 --- a/admin/calendar.php +++ b/admin/calendar.php @@ -282,10 +282,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
@@ -334,147 +334,168 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
+
-

\ No newline at end of file diff --git a/inc/headerAdmin.inc.php b/inc/headerAdmin.inc.php index 3f7df57d..37976b7b 100644 --- a/inc/headerAdmin.inc.php +++ b/inc/headerAdmin.inc.php @@ -78,6 +78,7 @@ header('X-UA-Compatible: IE=edge'); + {$end_time_sql}) AND `categories`.`usage` <> 1"; - - if (!$staff) { - $sql .= " AND `categories`.`type` = '0'"; - } - - $rs = hesk_dbQuery($sql); - - $events = array(); - while ($row = hesk_dbFetchAssoc($rs)) { - // Skip the event if the user does not have access to it - if ($staff && !$_SESSION['isadmin'] && !in_array($row['category'], $_SESSION['categories'])) { - continue; - } - - mfh_log_debug('Calendar', "Creating event with id: {$row['id']}", ''); - - $event['type'] = 'CALENDAR'; - $event['id'] = intval($row['id']); - $event['startTime'] = $row['start']; - $event['endTime'] = $row['end']; - $event['allDay'] = $row['all_day'] ? true : false; - $event['title'] = $row['name']; - $event['location'] = $row['location']; - $event['comments'] = $row['comments']; - $event['categoryId'] = $row['category']; - $event['categoryName'] = $row['category_name']; - $event['backgroundColor'] = $row['background_color']; - $event['foregroundColor'] = $row['foreground_color']; - $event['displayBorder'] = $row['display_border']; - - if ($staff) { - $event['reminderValue'] = $row['reminder_value']; - $event['reminderUnits'] = $row['reminder_unit']; - } - - $events[] = $event; - } - - if ($staff) { - $old_time_setting = $hesk_settings['timeformat']; - $hesk_settings['timeformat'] = 'Y-m-d'; - $current_date = hesk_date(); - $hesk_settings['timeformat'] = $old_time_setting; - - $sql = "SELECT `trackid`, `subject`, `due_date`, `category`, `categories`.`name` AS `category_name`, `categories`.`background_color` AS `background_color`, - `categories`.`foreground_color` AS `foreground_color`, `categories`.`display_border_outline` AS `display_border`, - CASE WHEN `due_date` < '{$current_date}' THEN 1 ELSE 0 END AS `overdue`, `owner`.`name` AS `owner_name`, `tickets`.`owner` AS `owner_id`, - `tickets`.`priority` AS `priority` - FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` AS `tickets` - INNER JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` AS `categories` - ON `categories`.`id` = `tickets`.`category` - AND `categories`.`usage` <> 2 - LEFT JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `owner` - ON `tickets`.`owner` = `owner`.`id` - WHERE `due_date` >= CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($start) - . " / 1000), @@session.time_zone, '+00:00') - AND `due_date` <= CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($end) . " / 1000), @@session.time_zone, '+00:00') - AND `status` IN (SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 0) "; - - $rs = hesk_dbQuery($sql); - while ($row = hesk_dbFetchAssoc($rs)) { - // Skip the ticket if the user does not have access to it - if (!hesk_checkPermission('can_view_tickets', 0) - || ($row['owner_id'] && $row['owner_id'] != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) - || (!$row['owner_id'] && !hesk_checkPermission('can_view_unassigned', 0))) { - continue; - } - - $event['type'] = 'TICKET'; - $event['trackingId'] = $row['trackid']; - $event['subject'] = $row['subject']; - $event['title'] = $row['subject']; - $event['startTime'] = $row['due_date']; - $event['url'] = $hesk_settings['hesk_url'] . '/' . $hesk_settings['admin_dir'] . '/admin_ticket.php?track=' . $event['trackingId']; - $event['categoryId'] = $row['category']; - $event['categoryName'] = $row['category_name']; - $event['backgroundColor'] = $row['background_color']; - $event['foregroundColor'] = $row['foreground_color']; - $event['displayBorder'] = $row['display_border']; - $event['owner'] = $row['owner_name']; - - $priorities = array( - 0 => $hesklang['critical'], - 1 => $hesklang['high'], - 2 => $hesklang['medium'], - 3 => $hesklang['low'] - ); - $event['priority'] = $priorities[$row['priority']]; - - $events[] = $event; - } - } - - return $events; -} - -function create_event($event, $hesk_settings) { - // Make sure the user can create events in this category - if (!$_SESSION['isadmin'] && !in_array($event['category'], $_SESSION['categories'])) { - print_error('Access Denied', 'You cannot create an event in this category'); - } - - $event['start'] = date('Y-m-d H:i:s', strtotime($event['start'])); - $event['end'] = date('Y-m-d H:i:s', strtotime($event['end'])); - $event['all_day'] = $event['all_day'] ? 1 : 0; - - $sql = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event` (`start`, `end`, `all_day`, - `name`, `location`, `comments`, `category`) VALUES ( - '" . hesk_dbEscape($event['start']) . "', '" . hesk_dbEscape($event['end']) . "', '" . hesk_dbEscape($event['all_day']) . "', - '" . hesk_dbEscape(addslashes($event['title'])) . "', '" . hesk_dbEscape(addslashes($event['location'])) . "', '" . hesk_dbEscape(addslashes($event['comments'])) . "', - " . intval($event['category']) . ")"; - - hesk_dbQuery($sql); - $event_id = hesk_dbInsertID(); - - if ($event['reminder_amount'] != null) { - $sql = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event_reminder` (`user_id`, `event_id`, - `amount`, `unit`) VALUES (" . intval($event['reminder_user']) . ", " . intval($event_id) . ", " . intval($event['reminder_amount']) . ", - " . intval($event['reminder_units']) . ")"; - - hesk_dbQuery($sql); - } - - return $event_id; -} - -function update_event($event, $hesk_settings) { - // Make sure the user can edit events in this category - if (!$_SESSION['isadmin'] && !in_array($event['category'], $_SESSION['categories'])) { - print_error('Access Denied', 'You cannot edit an event in this category'); - } - - $event['start'] = date('Y-m-d H:i:s', strtotime($event['start'])); - $event['end'] = date('Y-m-d H:i:s', strtotime($event['end'])); - if ($event['create_ticket_date'] != null) { - $event['create_ticket_date'] = date('Y-m-d H:i:s', strtotime($event['create_ticket_date'])); - } - $event['all_day'] = $event['all_day'] ? 1 : 0; - $event['assign_to'] = $event['assign_to'] != null ? intval($event['assign_to']) : 'NULL'; - - $sql = "UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event` SET `start` = '" . hesk_dbEscape($event['start']) - . "', `end` = '" . hesk_dbEscape($event['end']) . "', `all_day` = '" . hesk_dbEscape($event['all_day']) . "', `name` = '" - . hesk_dbEscape(addslashes($event['title'])) . "', `location` = '" . hesk_dbEscape(addslashes($event['location'])) . "', `comments` = '" - . hesk_dbEscape(addslashes($event['comments'])) . "', `category` = " . intval($event['category']) . " WHERE `id` = " . intval($event['id']); - - if ($event['reminder_amount'] != null) { - $delete_sql = "DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event_reminder` WHERE `event_id` = " . intval($event['id']) - . " AND `user_id` = " . intval($event['reminder_user']); - hesk_dbQuery($delete_sql); - $insert_sql = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event_reminder` (`user_id`, `event_id`, - `amount`, `unit`) VALUES (" . intval($event['reminder_user']) . ", " . intval($event['id']) . ", " . intval($event['reminder_amount']) . ", - " . intval($event['reminder_units']) . ")"; - hesk_dbQuery($insert_sql); - } - - hesk_dbQuery($sql); -} - -function delete_event($id, $hesk_settings) { - // Make sure the user can delete events in this category - $categoryRs = hesk_dbQuery('SELECT `category` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'calendar_event` WHERE `id` = ' . intval($id)); - $category = hesk_dbFetchAssoc($categoryRs); - if (!$_SESSION['isadmin'] && !in_array($category['category'], $_SESSION['categories'])) { - print_error('Access Denied', 'You cannot delete events in this category'); - } - - $sql = "DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "calendar_event` WHERE `id` = " . intval($id); - - hesk_dbQuery($sql); -} - -function update_ticket_due_date($ticket, $hesk_settings) { - $ticket_id_rs = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($ticket['trackid']) . "'"); - $ticket_id = hesk_dbFetchAssoc($ticket_id_rs); - - $due_date = 'NULL'; - $language_key = 'audit_due_date_removed'; - $audit_array = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'); - if ($ticket['due_date'] != NULL) { - $audit_array = array( - 0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')', - 1 => date('Y-m-d H:i:s', strtotime($ticket['due_date'])) - ); - $due_date = "'" . date('Y-m-d H:i:s', strtotime($ticket['due_date'])) . "'"; - $language_key = 'audit_due_date_changed'; - } - $sql = "UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `due_date` = {$due_date}, `overdue_email_sent` = '0' - WHERE `trackid` = '" . hesk_dbEscape($ticket['trackid']) . "'"; - - mfh_insert_audit_trail_record($ticket_id['id'], 'TICKET', $language_key, hesk_date(), - $audit_array); - - hesk_dbQuery($sql); -} \ No newline at end of file diff --git a/js/calendar/mods-for-hesk-calendar-admin-readonly.js b/js/calendar/mods-for-hesk-calendar-admin-readonly.js index 619e5d23..51f2b763 100644 --- a/js/calendar/mods-for-hesk-calendar-admin-readonly.js +++ b/js/calendar/mods-for-hesk-calendar-admin-readonly.js @@ -16,9 +16,10 @@ $(document).ready(function() { defaultView: $('#setting_default_view').text().trim(), events: function(start, end, timezone, callback) { $.ajax({ - url: heskPath + 'internal-api/admin/calendar/?start=' + start + '&end=' + end, + url: heskPath + 'api/index.php/v1/calendar/events/staff?start=' + start + '&end=' + end, method: 'GET', dataType: 'json', + headers: { 'X-Internal-Call': true }, success: function(data) { var events = []; $(data).each(function() { @@ -61,7 +62,8 @@ $(document).ready(function() { .find('.popover-owner span').text(event.owner).end() .find('.popover-subject span').text(event.subject).end() .find('.popover-category span').text(event.categoryName).end() - .find('.popover-priority span').text(event.priority); + .find('.popover-priority span').text(event.priority) + .find('.popover-status span').text(event.status).end(); } else { if (event.location === '') { $contents.find('.popover-location').hide(); @@ -124,7 +126,13 @@ $(document).ready(function() { }); function buildEvent(id, dbObject) { - if (dbObject.type == 'TICKET') { + var priorities = []; + priorities['CRITICAL'] = mfhLang.text('critical'); + priorities['HIGH'] = mfhLang.text('high'); + priorities['MEDIUM'] = mfhLang.text('medium'); + priorities['LOW'] = mfhLang.text('low'); + + if (dbObject.type === 'TICKET') { return { title: dbObject.title, subject: dbObject.subject, @@ -140,8 +148,9 @@ function buildEvent(id, dbObject) { categoryName: dbObject.categoryName, className: 'category-' + dbObject.categoryId, owner: dbObject.owner, - priority: dbObject.priority, - fontIconMarkup: getIcon(dbObject) + priority: priorities[dbObject.priority], + fontIconMarkup: getIcon(dbObject), + status: dbObject.status }; } diff --git a/js/calendar/mods-for-hesk-calendar-readonly.js b/js/calendar/mods-for-hesk-calendar-readonly.js index eff85039..a282c155 100644 --- a/js/calendar/mods-for-hesk-calendar-readonly.js +++ b/js/calendar/mods-for-hesk-calendar-readonly.js @@ -16,7 +16,7 @@ $(document).ready(function() { defaultView: $('#setting_default_view').text().trim(), events: function(start, end, timezone, callback) { $.ajax({ - url: heskPath + 'internal-api/calendar/?start=' + start + '&end=' + end, + url: heskPath + 'api/index.php/v1/calendar/events/?start=' + start + '&end=' + end, method: 'GET', dataType: 'json', success: function(data) { diff --git a/js/calendar/mods-for-hesk-calendar.js b/js/calendar/mods-for-hesk-calendar.js index 97c4fc7b..4cf6ebe9 100644 --- a/js/calendar/mods-for-hesk-calendar.js +++ b/js/calendar/mods-for-hesk-calendar.js @@ -16,9 +16,10 @@ $(document).ready(function() { defaultView: $('#setting_default_view').text().trim(), events: function(start, end, timezone, callback) { $.ajax({ - url: heskPath + 'internal-api/admin/calendar/?start=' + start + '&end=' + end, + url: heskPath + 'api/index.php/v1/calendar/events/staff?start=' + start + '&end=' + end, method: 'GET', dataType: 'json', + headers: { 'X-Internal-Call': true }, success: function(data) { var events = []; $(data).each(function() { @@ -51,16 +52,7 @@ $(document).ready(function() { var $contents = $(contents); var format = 'dddd, MMMM Do YYYY'; - var endDate = event.end == null ? event.start : event.end; - - if (event.allDay) { - endDate = event.end.clone(); - endDate.add(-1, 'days'); - } - - if (!event.allDay && event.type !== 'TICKET') { - format += ', HH:mm'; - } + var endDate = event.end === null ? event.start : event.end; if (event.type === 'TICKET') { contents = $('.ticket-popover-template').html(); @@ -74,8 +66,16 @@ $(document).ready(function() { .find('.popover-owner span').text(event.owner).end() .find('.popover-subject span').text(event.subject).end() .find('.popover-category span').text(event.categoryName).end() - .find('.popover-priority span').text(event.priority); + .find('.popover-priority span').text(event.priority).end() + .find('.popover-status span').text(event.status).end(); } else { + if (event.allDay) { + endDate = event.end.clone(); + endDate.add(-1, 'days'); + } else { + format += ', HH:mm'; + } + if (event.location === '') { $contents.find('.popover-location').hide(); } @@ -90,7 +90,7 @@ $(document).ready(function() { var $eventMarkup = $(this); var eventTitle = event.title; - if (event.fontIconMarkup != undefined) { + if (event.fontIconMarkup !== undefined) { eventTitle = event.fontIconMarkup + ' ' + eventTitle; } @@ -161,17 +161,15 @@ $(document).ready(function() { $editForm.find('#delete-button').click(function() { var id = $editForm.find('input[name="id"]').val(); - var data = { - id: id, - action: 'delete' - }; - $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, + url: heskPath + 'api/index.php/v1/calendar/events/staff/' + id, + headers: { + 'X-Internal-Call': true, + 'X-HTTP-Method-Override': 'DELETE' + }, success: function() { - removeFromCalendar(data.id); + removeFromCalendar(id); mfhAlert.success(mfhLang.text('event_deleted')); $('#edit-event-modal').modal('hide'); }, @@ -195,6 +193,9 @@ $(document).ready(function() { dateFormat = 'YYYY-MM-DD HH:mm:ss'; } + var reminderValue = $createForm.find('input[name="reminder-value"]').val(); + var reminderUnits = $createForm.find('select[name="reminder-unit"]').val(); + var data = { title: $createForm.find('input[name="name"]').val(), location: $createForm.find('input[name="location"]').val(), @@ -203,22 +204,23 @@ $(document).ready(function() { allDay: allDay, comments: $createForm.find('textarea[name="comments"]').val(), categoryId: $createForm.find('select[name="category"]').val(), - action: 'create', type: 'CALENDAR', backgroundColor: $createForm.find('select[name="category"] :selected').attr('data-background-color'), foregroundColor: $createForm.find('select[name="category"] :selected').attr('data-foreground-color'), displayBorder: $createForm.find('select[name="category"] :selected').attr('data-display-border'), categoryName: $createForm.find('select[name="category"] :selected').text().trim(), - reminderValue: $createForm.find('input[name="reminder-value"]').val(), - reminderUnits: $createForm.find('select[name="reminder-unit"]').val() + reminderValue: reminderValue === "" ? null : reminderValue, + reminderUnits: reminderValue === "" ? null : reminderUnits }; $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, - success: function(id) { - addToCalendar(id, data, $('#lang_event_created').text()); + url: heskPath + 'api/index.php/v1/calendar/events/staff', + data: JSON.stringify(data), + contentType: 'json', + headers: { 'X-Internal-Call': true }, + success: function(createdEvent) { + addToCalendar(createdEvent.id, data, $('#lang_event_created').text()); $('#create-event-modal').modal('hide'); updateCategoryVisibility(); }, @@ -243,6 +245,9 @@ $(document).ready(function() { dateFormat = 'YYYY-MM-DD HH:mm:ss'; } + var reminderValue = $createForm.find('input[name="reminder-value"]').val(); + var reminderUnits = $createForm.find('select[name="reminder-unit"]').val(); + var data = { id: $form.find('input[name="id"]').val(), title: $form.find('input[name="name"]').val(), @@ -251,21 +256,26 @@ $(document).ready(function() { endTime: moment(end).format(dateFormat), allDay: allDay, comments: $form.find('textarea[name="comments"]').val(), - categoryId: $form.find('select[name="category"]').val(), + categoryId: parseInt($form.find('select[name="category"]').val()), backgroundColor: $form.find('select[name="category"] :selected').attr('data-background-color'), foregroundColor: $form.find('select[name="category"] :selected').attr('data-foreground-color'), displayBorder: $form.find('select[name="category"] :selected').attr('data-display-border'), categoryName: $form.find('select[name="category"] :selected').text().trim(), - action: 'update', - reminderValue: $form.find('input[name="reminder-value"]').val(), - reminderUnits: $form.find('select[name="reminder-unit"]').val() + reminderValue: reminderValue === "" ? null : reminderValue, + reminderUnits: reminderValue === "" ? null : reminderUnits, }; $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, - success: function() { + url: heskPath + 'api/index.php/v1/calendar/events/staff/' + data.id, + data: JSON.stringify(data), + contentType: 'json', + headers: { + 'X-Internal-Call': true, + 'X-HTTP-Method-Override': 'PUT' + }, + success: function(updatedEvent) { + data.auditTrail = updatedEvent.auditTrail; removeFromCalendar(data.id); addToCalendar(data.id, data, $('#lang_event_updated').text()); $('#edit-event-modal').modal('hide'); @@ -290,8 +300,16 @@ function removeFromCalendar(id) { } function buildEvent(id, dbObject) { - if (dbObject.type == 'TICKET') { + var priorities = []; + priorities['CRITICAL'] = mfhLang.text('critical'); + priorities['HIGH'] = mfhLang.text('high'); + priorities['MEDIUM'] = mfhLang.text('medium'); + priorities['LOW'] = mfhLang.text('low'); + + + if (dbObject.type === 'TICKET') { return { + id: id, title: dbObject.title, subject: dbObject.subject, trackingId: dbObject.trackingId, @@ -306,8 +324,9 @@ function buildEvent(id, dbObject) { categoryName: dbObject.categoryName, className: 'category-' + dbObject.categoryId, owner: dbObject.owner, - priority: dbObject.priority, - fontIconMarkup: getIcon(dbObject) + priority: priorities[dbObject.priority], + fontIconMarkup: getIcon(dbObject), + status: dbObject.status }; } @@ -334,7 +353,8 @@ function buildEvent(id, dbObject) { borderColor: parseInt(dbObject.displayBorder) === 1 ? dbObject.foregroundColor : dbObject.backgroundColor, reminderValue: dbObject.reminderValue == null ? '' : dbObject.reminderValue, reminderUnits: dbObject.reminderUnits, - fontIconMarkup: '' + fontIconMarkup: '', + auditTrail: dbObject.auditTrail }; } @@ -379,7 +399,7 @@ function displayCreateModal(date, viewName) { .find('input[name="location"]').val('').end() .find('textarea[name="comments"]').val('').end() .find('select[name="category"]').val($form.find('select[name="category"] option:first-child').val()).end() - .find('select[name="reminder-unit"]').val(0).end() + .find('select[name="reminder-unit"]').val("MINUTE").end() .find('input[name="reminder-value"]').val('').end(); var $modal = $('#create-event-modal'); @@ -454,6 +474,24 @@ function displayEditModal(date) { $form.find('select[name="category"] option[value="' + date.categoryId + '"]').prop('selected', true); + var $auditTrail = $('#edit-history'); + if (date.auditTrail.length === 0) { + $('.nav-tabs[role="tablist"]').hide(); + } else { + $('.nav-tabs[role="tablist"]').show(); + + var $historyTable = $('#history-table'); + $historyTable.html(''); + $.each(date.auditTrail, function() { + var $template = $($('#audit-trail-template').html()); + $template.find('[data-property="date"]').text(this.date).end() + .find('[data-property="description"]').text(vsprintf(mfhLang.text(this.languageKey), this.replacementValues)); + + $historyTable.append($template); + }); + } + $('#edit-modal-tabs').find('a:first').tab('show'); + $('#edit-event-modal').modal('show'); } @@ -477,15 +515,19 @@ function updateCategoryVisibility() { function respondToDragAndDrop(event, delta, revertFunc) { var heskPath = $('p#hesk-path').text(); + if (event.type === 'TICKET') { + var uri = 'api/index.php/v1/staff/tickets/' + event.id + '/due-date'; $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: { - trackingId: event.trackingId, - action: 'update-ticket', - dueDate: event.start.format('YYYY-MM-DD') + url: heskPath + uri, + headers: { + 'X-Internal-Call': true, + 'X-HTTP-Method-Override': 'PATCH' }, + data: JSON.stringify({ + dueDate: event.start.format('YYYY-MM-DD') + }), success: function() { event.fontIconMarkup = getIcon({ startTime: event.start @@ -526,12 +568,19 @@ function respondToDragAndDrop(event, delta, revertFunc) { reminderValue: event.reminderValue, reminderUnits: event.reminderUnits }; + + var url = heskPath + 'api/index.php/v1/calendar/events/staff/' + event.id; $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, - success: function() { - mfhAlert.success(mfhLang.text('event_updated')); + url: url, + data: JSON.stringify(data), + headers: { + 'X-Internal-Call': true, + 'X-HTTP-Method-Override': 'PUT' + }, + success: function(updatedEvent) { + removeFromCalendar(updatedEvent.id); + addToCalendar(updatedEvent.id, updatedEvent, $('#lang_event_updated').text()); }, error: function() { mfhAlert.error(mfhLang.text('error_updating_event')); diff --git a/js/sprintf.min.js b/js/sprintf.min.js new file mode 100644 index 00000000..11ea3642 --- /dev/null +++ b/js/sprintf.min.js @@ -0,0 +1,3 @@ +/*! sprintf-js v1.1.0 | Copyright (c) 2007-present, Alexandru Marasteanu | BSD-3-Clause */ +!function(e){"use strict";function t(){var e=arguments[0],r=t.cache;return r[e]||(r[e]=t.parse(e)),t.format.call(null,r[e],arguments)}function r(e){return"number"==typeof e?"number":"string"==typeof e?"string":Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}function n(e,t){return t>=0&&t<=7&&i[e]?i[e][t]:Array(t+1).join(e)}var s={not_string:/[^s]/,not_bool:/[^t]/,not_type:/[^T]/,not_primitive:/[^v]/,number:/[diefg]/,numeric_arg:/[bcdiefguxX]/,json:/[j]/,not_json:/[^j]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[\+\-]/};t.format=function(e,a){var i,o,l,c,p,f,u,g=1,_=e.length,d="",b=[],h=!0,x="";for(o=0;o<_;o++)if("string"===(d=r(e[o])))b[b.length]=e[o];else if("array"===d){if(c=e[o],c[2])for(i=a[g],l=0;l=0),c[8]){case"b":i=parseInt(i,10).toString(2);break;case"c":i=String.fromCharCode(parseInt(i,10));break;case"d":case"i":i=parseInt(i,10);break;case"j":i=JSON.stringify(i,null,c[6]?parseInt(c[6]):0);break;case"e":i=c[7]?parseFloat(i).toExponential(c[7]):parseFloat(i).toExponential();break;case"f":i=c[7]?parseFloat(i).toFixed(c[7]):parseFloat(i);break;case"g":i=c[7]?parseFloat(i).toPrecision(c[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=String(i),i=c[7]?i.substring(0,c[7]):i;break;case"t":i=String(!!i),i=c[7]?i.substring(0,c[7]):i;break;case"T":i=r(i),i=c[7]?i.substring(0,c[7]):i;break;case"u":i=parseInt(i,10)>>>0;break;case"v":i=i.valueOf(),i=c[7]?i.substring(0,c[7]):i;break;case"x":i=parseInt(i,10).toString(16);break;case"X":i=parseInt(i,10).toString(16).toUpperCase()}s.json.test(c[8])?b[b.length]=i:(!s.number.test(c[8])||h&&!c[3]?x="":(x=h?"+":"-",i=i.toString().replace(s.sign,"")),f=c[4]?"0"===c[4]?"0":c[4].charAt(1):" ",u=c[6]-(x+i).length,p=c[6]&&u>0?n(f,u):"",b[b.length]=c[5]?x+i+p:"0"===f?x+p+i:p+x+i)}return b.join("")},t.cache=Object.create(null),t.parse=function(e){for(var t=e,r=[],n=[],a=0;t;){if(null!==(r=s.text.exec(t)))n[n.length]=r[0];else if(null!==(r=s.modulo.exec(t)))n[n.length]="%";else{if(null===(r=s.placeholder.exec(t)))throw new SyntaxError("[sprintf] unexpected placeholder");if(r[2]){a|=1;var i=[],o=r[2],l=[];if(null===(l=s.key.exec(o)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(i[i.length]=l[1];""!==(o=o.substring(l[0].length));)if(null!==(l=s.key_access.exec(o)))i[i.length]=l[1];else{if(null===(l=s.index_access.exec(o)))throw new SyntaxError("[sprintf] failed to parse named argument key");i[i.length]=l[1]}r[2]=i}else a|=2;if(3===a)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");n[n.length]=r}t=t.substring(r[0].length)}return n};var a=function(e,r,n){return n=(r||[]).slice(0),n.splice(0,0,e),t.apply(null,n)},i={0:["","0","00","000","0000","00000","000000","0000000"]," ":[""," "," "," "," "," "," "," "],_:["","_","__","___","____","_____","______","_______"]};"undefined"!=typeof exports&&(exports.sprintf=t,exports.vsprintf=a),void 0!==e&&(e.sprintf=t,e.vsprintf=a,"function"==typeof define&&define.amd&&define(function(){return{sprintf:t,vsprintf:a}}))}("undefined"==typeof window?this:window); +//# sourceMappingURL=sprintf.min.js.map diff --git a/language/en/text.php b/language/en/text.php index 7d62e3f3..51c2470a 100644 --- a/language/en/text.php +++ b/language/en/text.php @@ -2215,6 +2215,8 @@ $hesklang['audit_linked_ticket'] = '%s linked ticket %s to this ticket'; $hesklang['audit_unlinked_ticket'] = '%s unlinked ticket %s'; // Added or modified in Mods for HESK 3.3.0 +$hesklang['audit_event_created'] = '%s created event'; +$hesklang['audit_event_updated'] = '%s updated event'; $hesklang['error_retrieving_sm'] = 'An error occurred retrieving service messages!'; $hesklang['error_saving_updating_sm'] = 'An error occurred creating / saving the service message!'; $hesklang['error_deleting_sm'] = 'An error occurred when trying to delete the service message.';