diff --git a/front/core/directives/anchor.js b/front/core/directives/anchor.js
new file mode 100644
index 000000000..9a079affd
--- /dev/null
+++ b/front/core/directives/anchor.js
@@ -0,0 +1,70 @@
+import ngModule from '../module';
+
+export function stringifyParams(data) {
+ const params = Object.assign({}, data.params);
+ for (let param in params)
+ params[param] = JSON.stringify(params[param]);
+
+ return params;
+}
+
+export function changeState($state, event, data) {
+ const params = stringifyParams(data);
+ $state.go(data.state, params);
+
+ event.preventDefault();
+ event.stopPropagation();
+}
+
+export function openNewTab($state, $window, event, data) {
+ const params = stringifyParams(data);
+ const href = $state.href(data.state, params);
+ $window.open(href);
+
+ event.preventDefault();
+ event.stopPropagation();
+}
+
+/**
+ * Allows changing state for nested anchor
+ *
+ * @param {Object} $state
+ * @param {Object} $window
+ * @return {Object} The directive
+ */
+export function directive($state, $window) {
+ let ctrlPressed = false;
+
+ $window.addEventListener('keydown', event => {
+ if (event.key == 'Control')
+ ctrlPressed = true;
+ });
+
+ $window.addEventListener('keyup', event => {
+ if (event.key == 'Control')
+ ctrlPressed = false;
+ });
+
+ return {
+ restrict: 'A',
+ link: function($scope, $element, $attrs) {
+ const data = $scope.$eval($attrs.vnAnchor);
+ $element.on('click', event => {
+ if (ctrlPressed)
+ openNewTab($state, $window, event, data);
+ else
+ changeState($state, event, data);
+ });
+
+ $element.on('mousedown', event => {
+ const mouseWheel = 1;
+ if (event.button == mouseWheel)
+ openNewTab($state, $window, event, data);
+ });
+ }
+ };
+}
+
+directive.$inject = ['$state', '$window'];
+
+ngModule.directive('vnAnchor', directive);
diff --git a/front/core/directives/index.js b/front/core/directives/index.js
index af05c9b38..e0f42aef5 100644
--- a/front/core/directives/index.js
+++ b/front/core/directives/index.js
@@ -15,3 +15,4 @@ import './smart-table';
import './droppable';
import './http-click';
import './http-submit';
+import './anchor';
diff --git a/modules/client/front/descriptor/locale/es.yml b/modules/client/front/descriptor/locale/es.yml
index 3f59aede8..03cf17e7b 100644
--- a/modules/client/front/descriptor/locale/es.yml
+++ b/modules/client/front/descriptor/locale/es.yml
@@ -1,4 +1,5 @@
Simple ticket: Ticket simple
View consumer report: Ver informe de consumo
From date: Fecha desde
-To date: Fecha hasta
\ No newline at end of file
+To date: Fecha hasta
+Go to user: Ir al usuario
\ No newline at end of file
diff --git a/modules/client/front/index/index.html b/modules/client/front/index/index.html
index 7493ecace..abbbe60e5 100644
--- a/modules/client/front/index/index.html
+++ b/modules/client/front/index/index.html
@@ -40,8 +40,7 @@
vn-tooltip="Client frozen"
icon="icon-frozen">
-
diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html
index e9066a41b..902d1f5a4 100644
--- a/modules/ticket/front/index/index.html
+++ b/modules/ticket/front/index/index.html
@@ -119,7 +119,7 @@
diff --git a/modules/ticket/front/index/index.js b/modules/ticket/front/index/index.js
index 32c2f0baa..cae9c403c 100644
--- a/modules/ticket/front/index/index.js
+++ b/modules/ticket/front/index/index.js
@@ -114,11 +114,6 @@ export default class Controller extends Section {
return 'warning';
}
- goToLines(ticketFk) {
- let url = this.$state.href('ticket.card.sale', {id: ticketFk}, {absolute: true});
- window.open(url, '_blank');
- }
-
preview(ticket) {
this.selectedTicket = ticket;
this.$.summary.show();
diff --git a/modules/worker/front/index/index.html b/modules/worker/front/index/index.html
index 3d383ae04..c994e7a7b 100644
--- a/modules/worker/front/index/index.html
+++ b/modules/worker/front/index/index.html
@@ -29,7 +29,7 @@