diff --git a/front/core/components/confirm/confirm.html b/front/core/components/confirm/confirm.html
index 5ef8fde75..be839078a 100644
--- a/front/core/components/confirm/confirm.html
+++ b/front/core/components/confirm/confirm.html
@@ -1,10 +1,10 @@
-
-
-
- {{$ctrl.statusText}}
+
+
+
+
-
\ No newline at end of file
+
+
+
+ {{$ctrl.statusText}}
+
+
+
\ No newline at end of file
diff --git a/front/core/components/drop-down/index.js b/front/core/components/drop-down/index.js
index ed7de7179..dfdfbe18d 100644
--- a/front/core/components/drop-down/index.js
+++ b/front/core/components/drop-down/index.js
@@ -1,7 +1,6 @@
import './style.scss';
import ngModule from '../../module';
import Popover from '../popover';
-import template from './index.html';
import ArrayModel from '../array-model/array-model';
import CrudModel from '../crud-model/crud-model';
import {mergeWhere} from 'vn-loopback/util/filter';
@@ -21,7 +20,6 @@ export default class DropDown extends Popover {
this.showLoadMore = true;
this.showFilter = true;
this.searchDelay = 300;
- this.fillDefaultSlot(template);
}
get search() {
@@ -458,6 +456,7 @@ function getPosition(parent, event) {
}
ngModule.vnComponent('vnDropDown', {
+ slotTemplate: require('./index.html'),
controller: DropDown,
transclude: {
tplItem: '?tplItem'
diff --git a/front/core/components/form-input/index.js b/front/core/components/form-input/index.js
index 0395922c7..c50102e8a 100644
--- a/front/core/components/form-input/index.js
+++ b/front/core/components/form-input/index.js
@@ -9,12 +9,6 @@ import Component from '../../lib/component';
* @property {Boolean} disabled Put component in disabled mode
*/
export default class FormInput extends Component {
- constructor($element, $scope) {
- super($element, $scope);
- this.classList = this.element.classList;
- this.classList.add(...this.constructor.$classNames);
- }
-
$onInit() {
// XXX: Compatibility with old inputs
let attrs = this.$element[0].attributes;
diff --git a/front/core/components/popover/index.js b/front/core/components/popover/index.js
index 7c54ce494..f7ab30b62 100644
--- a/front/core/components/popover/index.js
+++ b/front/core/components/popover/index.js
@@ -13,8 +13,8 @@ import './style.scss';
* @event close Thrown when popover is hidden
*/
export default class Popover extends Popup {
- constructor($element, $, $transclude) {
- super($element, $, $transclude);
+ constructor(...args) {
+ super(...args);
this.displayMode = isMobile ? 'centered' : 'relative';
this.template = template;
}
@@ -23,9 +23,12 @@ export default class Popover extends Popup {
* Shows the popover emitting the open signal. If a parent is specified
* it is shown in a visible relative position to it.
*
- * @param {HTMLElement} parent Overrides the parent property
+ * @param {HTMLElement|Event} parent Overrides the parent property
*/
show(parent) {
+ if (parent instanceof Event)
+ parent = event.target;
+
if (parent) this.parent = parent;
super.show();
this.content = this.popup.querySelector('.content');
diff --git a/front/core/components/popup/index.js b/front/core/components/popup/index.js
index 0dea66254..6e8c4df75 100644
--- a/front/core/components/popup/index.js
+++ b/front/core/components/popup/index.js
@@ -7,9 +7,8 @@ import './style.scss';
* Base class for windows displayed over application content.
*/
export default class Popup extends Component {
- constructor($element, $scope, $transclude) {
- super($element, $scope);
- this.$transclude = $transclude;
+ constructor(...args) {
+ super(...args);
this._shown = false;
this.displayMode = 'centered';
this.template = template;
@@ -45,11 +44,13 @@ export default class Popup extends Component {
this.onClose();
}
- let linkFn = this.$compile(this.template);
this.$contentScope = this.$.$new();
+
+ let linkFn = this.$compile(this.template);
this.popup = linkFn(this.$contentScope, null,
{parentBoundTranscludeFn: this.$transclude}
)[0];
+
this.windowEl = this.popup.querySelector('.window');
this.windowEl.focus();
@@ -127,5 +128,6 @@ ngModule.vnComponent('vnPopup', {
transclude: true,
bindings: {
shown: '=?'
- }
+ },
+ installClasses: false
});
diff --git a/front/core/directives/click-stop.js b/front/core/directives/click-stop.js
new file mode 100644
index 000000000..c13bbecae
--- /dev/null
+++ b/front/core/directives/click-stop.js
@@ -0,0 +1,23 @@
+import ngModule from '../module';
+
+/*
+ * Registers a handler for the click event and stops propagation when event
+ * is thrown, mainly when nesting clickable elements wich ignore the
+ * Event.defaultPrevented property, like ui-sref.
+ */
+export function directive($parse) {
+ return {
+ restrict: 'A',
+ link: function(scope, element, attrs) {
+ const fn = $parse(attrs.vnClickStop);
+ element.on('click', function(event) {
+ fn(scope, {$event: event});
+ event.stopPropagation();
+ event.preventDefault();
+ });
+ }
+ };
+}
+directive.$inject = ['$parse'];
+
+ngModule.directive('vnClickStop', directive);
diff --git a/front/core/directives/index.js b/front/core/directives/index.js
index 185046a3c..4377afe8c 100644
--- a/front/core/directives/index.js
+++ b/front/core/directives/index.js
@@ -2,6 +2,7 @@ import './id';
import './focus';
import './dialog';
import './popover';
+import './click-stop';
import './rule';
import './acl';
import './on-error-src';
diff --git a/front/core/lib/component.js b/front/core/lib/component.js
index 4552dfbe7..39d593cf0 100644
--- a/front/core/lib/component.js
+++ b/front/core/lib/component.js
@@ -11,14 +11,29 @@ export default class Component extends EventEmitter {
*
* @param {HTMLElement} $element The main component element
* @param {$rootScope.Scope} $scope The element scope
+ * @param {Function} $transclude The transclusion function
*/
- constructor($element, $scope) {
+ constructor($element, $scope, $transclude) {
super();
+ this.$ = $scope;
+
if (!$element) return;
this.element = $element[0];
this.element.$ctrl = this;
this.$element = $element;
- this.$ = $scope;
+ this.$transclude = $transclude;
+ this.classList = this.element.classList;
+
+ const constructor = this.constructor;
+ const $options = constructor.$options;
+
+ if ($options && $options.installClasses)
+ this.classList.add(...this.constructor.$classNames);
+
+ if ($transclude && constructor.slotTemplates) {
+ for (let slotTemplate of constructor.slotTemplates)
+ this.fillSlots(slotTemplate);
+ }
}
$postLink() {
@@ -26,7 +41,7 @@ export default class Component extends EventEmitter {
let attrs = this.$element[0].attributes;
let $scope = this.$;
for (let attr of attrs) {
- if (attr.name.substr(0, 2) !== 'on') continue;
+ if (!attr.name.startsWith('on-')) continue;
let eventName = kebabToCamel(attr.name.substr(3));
let callback = locals => $scope.$parent.$eval(attr.nodeValue, locals);
this.on(eventName, callback);
@@ -58,6 +73,72 @@ export default class Component extends EventEmitter {
return this.$translate.instant(string, params);
}
+ /**
+ * Fills the default transclude slot.
+ *
+ * @param {JQElement|String} template The slot template
+ */
+ fillDefaultSlot(template) {
+ const linkFn = this.$compile(template);
+ this.$transclude.$$boundTransclude = this.createBoundTranscludeFn(linkFn);
+ }
+
+ /**
+ * Fills a named transclude slot.
+ *
+ * @param {String} slot The trasnclude slot name
+ * @param {JQElement|String} template The slot name
+ */
+ fillSlot(slot, template) {
+ const linkFn = this.$compile(template);
+ const slots = this.$transclude.$$boundTransclude.$$slots;
+ slots[slot] = this.createBoundTranscludeFn(linkFn);
+ }
+
+ /**
+ * Fills component transclude slots using the passed HTML template string
+ * as source.
+ *
+ * @param {String} template The HTML template string
+ */
+ fillSlots(template) {
+ const name = this.constructor.$options.name;
+ const transclude = this.constructor.$options.transclude;
+
+ if (!transclude)
+ throw new Error(`No transclusion option defined in '${name}'`);
+ if (!this.$transclude)
+ throw new Error(`No $transclude injected in '${name}'`);
+
+ let slotMap = {};
+ for (let slotName in transclude) {
+ let slotTag = transclude[slotName].match(/\w+$/)[0];
+ slotMap[slotTag] = slotName;
+ }
+
+ const $template = angular.element(template);
+ for (let i = 0; i < $template.length; i++) {
+ let slotElement = $template[i];
+ if (slotElement.nodeType != Node.ELEMENT_NODE) continue;
+ let tagName = kebabToCamel(slotElement.tagName.toLowerCase());
+
+ if (tagName == 'default')
+ this.fillDefaultSlot(slotElement.childNodes);
+ else {
+ let slotName = slotMap[tagName];
+ if (!slotName)
+ throw new Error(`No slot found for '${tagName}' in '${name}'`);
+ this.fillSlot(slotName, slotElement);
+ }
+ }
+ }
+
+ /**
+ * Creates a bounded transclude function from a linking function.
+ *
+ * @param {Function} linkFn The linking function
+ * @return {Function} The bounded transclude function
+ */
createBoundTranscludeFn(linkFn) {
let scope = this.$;
let previousBoundTranscludeFn = this.$transclude.$$boundTransclude;
@@ -78,17 +159,6 @@ export default class Component extends EventEmitter {
return vnBoundTranscludeFn;
}
- fillDefaultSlot(template) {
- let linkFn = this.$compile(template);
- this.$transclude.$$boundTransclude = this.createBoundTranscludeFn(linkFn);
- }
-
- fillSlot(slot, template) {
- let slots = this.$transclude.$$boundTransclude.$$slots;
- let linkFn = this.$compile(template);
- slots[slot] = this.createBoundTranscludeFn(linkFn);
- }
-
copySlot(slot, $transclude) {
this.$transclude.$$boundTransclude.$$slots[slot] =
$transclude.$$boundTransclude.$$slots[slot];
@@ -96,38 +166,18 @@ export default class Component extends EventEmitter {
}
Component.$inject = ['$element', '$scope'];
-function runFn(
- $translate,
- $q,
- $http,
- $state,
- $stateParams,
- $timeout,
- $transitions,
- $compile,
- $filter,
- $interpolate,
- $window,
- vnApp,
- vnToken,
- vnConfig,
- aclService) {
- Object.assign(Component.prototype, {
- $translate,
- $q,
- $http,
- $state,
- $params: $stateParams,
- $timeout,
- $transitions,
- $compile,
- $filter,
- $interpolate,
- $window,
- vnApp,
- vnToken,
- vnConfig,
- aclService
+/*
+ * Automatically adds the most used services to the prototype, so they are
+ * available as component properties.
+ */
+function runFn(...args) {
+ const proto = Component.prototype;
+
+ for (let i = 0; i < runFn.$inject.length; i++)
+ proto[runFn.$inject[i]] = args[i];
+
+ Object.assign(proto, {
+ $params: proto.$stateParams
});
}
runFn.$inject = [
diff --git a/front/core/module.js b/front/core/module.js
index 82a954892..f80f11853 100644
--- a/front/core/module.js
+++ b/front/core/module.js
@@ -1,6 +1,16 @@
import {ng, ngDeps} from './vendor';
import {camelToKebab} from './lib/string';
+/**
+ * Extended component options.
+ *
+ * @property {Boolean} installClassses Whether to install CSS classes equivalent to the component's and parents name
+ * @property {String} slotTemplate HTML template used to fill component transclude slots
+ */
+const defaultOptions = {
+ installClasses: true
+};
+
/**
* Acts like native Module.component() function but merging component options
* with parent component options. This method establishes the $options property
@@ -17,7 +27,7 @@ import {camelToKebab} from './lib/string';
function vnComponent(name, options) {
let controller = options.controller;
let parent = Object.getPrototypeOf(controller);
- let parentOptions = parent.$options || {};
+ let parentOptions = parent.$options || defaultOptions;
let parentTransclude = parentOptions.transclude;
let transclude = parentTransclude instanceof Object
@@ -32,10 +42,11 @@ function vnComponent(name, options) {
} else if (options.transclude !== undefined)
transclude = options.transclude;
- let mergedOptions = Object.assign({},
+ let $options = Object.assign({},
parentOptions,
options,
{
+ name,
transclude,
bindings: Object.assign({},
parentOptions.bindings,
@@ -47,13 +58,17 @@ function vnComponent(name, options) {
)
}
);
- controller.$options = mergedOptions;
+
+ let parentSlotTemplates = parent.slotTemplates || [];
+ if (options.slotTemplate)
+ controller.slotTemplates = parentSlotTemplates.concat([options.slotTemplate]);
let classNames = [camelToKebab(name)];
if (parent.$classNames) classNames = classNames.concat(parent.$classNames);
controller.$classNames = classNames;
- return this.component(name, mergedOptions);
+ controller.$options = $options;
+ return this.component(name, $options);
}
const ngModuleFn = ng.module;
@@ -72,33 +87,12 @@ export function config($translateProvider, $translatePartialLoaderProvider, $ani
// For CSS browser targeting
document.documentElement.setAttribute('data-browser', navigator.userAgent);
- $translatePartialLoaderProvider.addPart('core');
-
- let conf = {urlTemplate: '/locale/{part}/{lang}.json'};
-
- let fallbackLang = 'es';
- let langs = ['en', 'es'];
- let langAliases = {
- en_US: 'en',
- en_GB: 'en',
- es_ES: 'es',
- es_AR: 'es'
- };
-
$translateProvider
.useSanitizeValueStrategy('escape')
- .useLoader('$translatePartialLoader', conf)
- .registerAvailableLanguageKeys(langs, langAliases)
- // FIXME: Circular dependency due to vnInterceptor
- // .fallbackLanguage(fallbackLang)
- .determinePreferredLanguage(() => {
- let locale = $translateProvider.resolveClientLocale();
- if (langs.indexOf(locale) !== -1)
- return locale;
- if (langAliases[locale])
- return langAliases[locale];
- return fallbackLang;
+ .useLoader('$translatePartialLoader', {
+ urlTemplate: '/locale/{part}/{lang}.json'
});
+ $translatePartialLoaderProvider.addPart('core');
$animateProvider.customFilter(
node => node.tagName == 'UI-VIEW');
diff --git a/front/core/styles/layout.scss b/front/core/styles/layout.scss
index 85088db6a..8be4d1c73 100644
--- a/front/core/styles/layout.scss
+++ b/front/core/styles/layout.scss
@@ -4,17 +4,19 @@
html [vn-horizontal], vn-horizontal, .vn-horizontal,
html [vn-vertical], vn-vertical, .vn-vertical {
display: flex;
+
+ & > * {
+ flex: 1;
+ }
}
html [vn-horizontal], vn-horizontal, .vn-horizontal {
flex-direction: row;
}
-vn-horizontal[reverse] {
- flex-direction: row-reverse;
-}
html [vn-vertical], vn-vertical, .vn-vertical {
flex-direction: column;
}
-vn-vertical[reverse] {
+
+html [reverse] {
flex-direction: column-reverse;
}
html [wrap] {
@@ -26,27 +28,12 @@ html [wrap-reverse] {
/* Horizontal & vertical childs */
-html [vn-auto],
-html [vn-none],
-html [vn-one],
-html [vn-two],
-html [vn-three],
-html [vn-four],
-html [vn-five],
-html [vn-six],
-html [vn-seven],
-html [vn-eight],
-html [vn-nine],
-html [vn-ten],
-html [vn-eleven],
-html [vn-twelve]{
- flex-basis: .1px;
-}
html [vn-auto], vn-auto, .vn-auto {
flex-basis: auto;
}
html [vn-none], vn-none, .vn-none {
flex: none;
+ flex-basis: .1px;
}
html [vn-one], vn-one, .vn-one {
flex: 1;
diff --git a/front/salix/components/descriptor-popover/index.html b/front/salix/components/descriptor-popover/index.html
new file mode 100644
index 000000000..bedb32f0f
--- /dev/null
+++ b/front/salix/components/descriptor-popover/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/front/salix/components/descriptor-popover/index.js b/front/salix/components/descriptor-popover/index.js
new file mode 100644
index 000000000..7de04a64b
--- /dev/null
+++ b/front/salix/components/descriptor-popover/index.js
@@ -0,0 +1,83 @@
+import ngModule from '../../module';
+import Popover from 'core/components/popover';
+import './style.scss';
+
+export default class DescriptorPopover extends Popover {
+ constructor(...args) {
+ super(...args);
+ this._quicklinks = {};
+ this.entity = null;
+ }
+
+ get id() {
+ return this._id;
+ }
+
+ set id(value) {
+ if (value == this._id) return;
+ this._id = value;
+ this.loadData();
+ }
+
+ get entity() {
+ return this._entity;
+ }
+
+ set entity(value) {
+ this._entity = value;
+ }
+
+ get quicklinks() {
+ return this._quicklinks;
+ }
+
+ set quicklinks(value = {}) {
+ Object.keys(value).forEach(key => {
+ this._quicklinks[key] = value[key];
+ });
+ }
+
+ show(parent, id) {
+ if (id !== undefined)
+ this.id = id;
+ super.show(parent);
+ }
+
+ /**
+ * Reloads the descriptor data. Should be implemented or overriden by child
+ * classes.
+ */
+ loadData() {
+ throw new Error('DescriptorPopover::loadData() method not implemented');
+ }
+
+ getData(url, options) {
+ if (this.canceler) this.canceler.resolve();
+ this.canceler = this.$q.defer();
+ this.entity = null;
+
+ options = Object.assign(options || {}, {
+ timeout: this.canceler.promise
+ });
+
+ this.relocate();
+ return this.$http.get(url, options)
+ .then(res => {
+ this.canceler = null;
+ this.$.$applyAsync(() => this.relocate());
+ return res;
+ });
+ }
+}
+
+ngModule.vnComponent('vnDescriptorPopover', {
+ slotTemplate: require('./index.html'),
+ controller: DescriptorPopover,
+ bindings: {
+ id: '',
+ entity: '',
+ },
+ transclude: {
+ descriptor: '?slotDescriptor'
+ }
+});
diff --git a/front/salix/components/descriptor-popover/style.scss b/front/salix/components/descriptor-popover/style.scss
new file mode 100644
index 000000000..9d99f77bc
--- /dev/null
+++ b/front/salix/components/descriptor-popover/style.scss
@@ -0,0 +1,13 @@
+@import "variables";
+
+.vn-descriptor-popover {
+ .content > vn-spinner {
+ padding: $spacing-md;
+ display: block;
+ margin: 0 auto;
+ height: 45px;
+ }
+ .descriptor-wrapper {
+ width: 260px;
+ }
+}
\ No newline at end of file
diff --git a/front/salix/components/descriptor/index.js b/front/salix/components/descriptor/index.js
index 504812b15..844e33542 100644
--- a/front/salix/components/descriptor/index.js
+++ b/front/salix/components/descriptor/index.js
@@ -1,12 +1,21 @@
import ngModule from '../../module';
+import Component from 'core/lib/component';
+import './quick-links';
import './style.scss';
-export default class QuickLinks {}
-
-ngModule.component('vnQuickLinks', {
- template: require('./index.html'),
- controller: QuickLinks,
- bindings: {
- links: ''
+export default class Descriptor extends Component {
+ set quicklinks(value = {}) {
+ this._quicklinks = Object.assign(value, this._quicklinks);
}
+
+ get quicklinks() {
+ return this._quicklinks;
+ }
+}
+
+ngModule.vnComponent('vnDescriptor', {
+ controller: Descriptor,
+ bindings: {
+ quicklinks: '<'
+ },
});
diff --git a/front/salix/components/descriptor/quick-links.html b/front/salix/components/descriptor/quick-links.html
new file mode 100644
index 000000000..4a50be430
--- /dev/null
+++ b/front/salix/components/descriptor/quick-links.html
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/front/salix/components/descriptor/quick-links.js b/front/salix/components/descriptor/quick-links.js
new file mode 100644
index 000000000..e7f9bdb24
--- /dev/null
+++ b/front/salix/components/descriptor/quick-links.js
@@ -0,0 +1,11 @@
+import ngModule from '../../module';
+
+export default class QuickLinks {}
+
+ngModule.component('vnQuickLinks', {
+ template: require('./quick-links.html'),
+ controller: QuickLinks,
+ bindings: {
+ links: ''
+ }
+});
diff --git a/front/salix/components/index.js b/front/salix/components/index.js
index 2afd55edf..1586272c0 100644
--- a/front/salix/components/index.js
+++ b/front/salix/components/index.js
@@ -1,6 +1,7 @@
import './app/app';
import './background/background';
import './descriptor';
+import './descriptor-popover';
import './home/home';
import './layout';
import './left-menu/left-menu';
diff --git a/front/salix/components/layout/index.html b/front/salix/components/layout/index.html
index 0ad400114..a139c6297 100644
--- a/front/salix/components/layout/index.html
+++ b/front/salix/components/layout/index.html
@@ -74,4 +74,5 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/front/salix/components/layout/style.scss b/front/salix/components/layout/style.scss
index 14af8ac23..680ed3e41 100644
--- a/front/salix/components/layout/style.scss
+++ b/front/salix/components/layout/style.scss
@@ -32,7 +32,7 @@ vn-layout {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
- padding-left: 6px;
+ padding-left: 10px;
}
& > vn-spinner {
padding: 0 6px;
@@ -80,7 +80,7 @@ vn-layout {
padding-right: $menu-width;
}
[fixed-bottom-right] {
- right: 64px + $menu-width;
+ right: 32px + $menu-width;
}
}
& > .main-view {
diff --git a/front/salix/components/module-card/index.js b/front/salix/components/module-card/index.js
index 9131cc772..9e547445f 100644
--- a/front/salix/components/module-card/index.js
+++ b/front/salix/components/module-card/index.js
@@ -6,11 +6,6 @@ import './style.scss';
* Base class for module cards.
*/
export default class ModuleCard extends Component {
- constructor($element, $) {
- super($element, $);
- this.element.classList.add('vn-module-card');
- }
-
$onInit() {
this.reload();
}
diff --git a/front/salix/components/module-main/index.js b/front/salix/components/module-main/index.js
index 39fbe42b8..ab292273c 100644
--- a/front/salix/components/module-main/index.js
+++ b/front/salix/components/module-main/index.js
@@ -2,12 +2,7 @@ import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss';
-export default class ModuleMain extends Component {
- constructor($element, $) {
- super($element, $);
- this.element.classList.add('vn-module-main');
- }
-}
+export default class ModuleMain extends Component {}
ngModule.vnComponent('vnModuleMain', {
template: require('./index.html'),
diff --git a/front/salix/components/section/index.js b/front/salix/components/section/index.js
index c34459147..f2440964c 100644
--- a/front/salix/components/section/index.js
+++ b/front/salix/components/section/index.js
@@ -2,17 +2,7 @@ import ngModule from '../../module';
import Component from 'core/lib/component';
import './style.scss';
-export default class Section extends Component {
- constructor($element, $) {
- super($element, $);
- this.element.classList.add('vn-section');
- }
-
- stopEvent(event) {
- event.preventDefault();
- event.stopImmediatePropagation();
- }
-}
+export default class Section extends Component {}
ngModule.vnComponent('vnSection', {
controller: Section
diff --git a/front/salix/components/user-popover/index.js b/front/salix/components/user-popover/index.js
index 764b0cae9..88efb26d1 100644
--- a/front/salix/components/user-popover/index.js
+++ b/front/salix/components/user-popover/index.js
@@ -1,15 +1,6 @@
import ngModule from '../../module';
import './style.scss';
-
-let languages = {
- es: 'Español',
- en: 'English',
- ca: 'Català',
- pt: 'Português',
- fr: 'Français',
- nl: 'Nederlands',
- mn: 'Монгол хэл'
-};
+import config from '../../config.json';
class Controller {
constructor($, $translate, vnConfig, vnAuth) {
@@ -25,7 +16,7 @@ class Controller {
for (let code of $translate.getAvailableLanguageKeys()) {
this.langs.push({
code: code,
- name: languages[code] ? languages[code] : code
+ name: config.languages[code] ? config.languages[code] : code
});
}
diff --git a/front/salix/config.json b/front/salix/config.json
new file mode 100644
index 000000000..d87b70ae9
--- /dev/null
+++ b/front/salix/config.json
@@ -0,0 +1,25 @@
+{
+ "imagePath": "//verdnatura.es/vn-image-data",
+ "langOptions": {
+ "fallbackLang": "es",
+ "langs": [
+ "en",
+ "es"
+ ],
+ "langAliases": {
+ "en_US": "en",
+ "en_GB": "en",
+ "es_ES": "es",
+ "es_AR": "es"
+ }
+ },
+ "languages": {
+ "es": "Español",
+ "en": "English",
+ "ca": "Català",
+ "pt": "Português",
+ "fr": "Français",
+ "nl": "Nederlands",
+ "mn": "Монгол хэл"
+ }
+}
diff --git a/front/salix/module.js b/front/salix/module.js
index 34e53b8bd..c3e8dcb8a 100644
--- a/front/salix/module.js
+++ b/front/salix/module.js
@@ -1,4 +1,5 @@
import {ng} from 'core/vendor';
+import appConfig from './config.json';
import 'core';
export const appName = 'salix';
@@ -8,6 +9,8 @@ export default ngModule;
run.$inject = ['$window', '$rootScope', 'vnAuth', 'vnApp', '$state'];
export function run($window, $rootScope, vnAuth, vnApp, $state) {
+ $rootScope.imagePath = appConfig.imagePath;
+
$window.validations = {};
vnApp.name = appName;
@@ -57,8 +60,22 @@ export function run($window, $rootScope, vnAuth, vnApp, $state) {
}
ngModule.run(run);
-config.$inject = ['$translatePartialLoaderProvider', '$httpProvider', '$compileProvider'];
-export function config($translatePartialLoaderProvider, $httpProvider, $compileProvider) {
+config.$inject = ['$translateProvider', '$translatePartialLoaderProvider', '$httpProvider', '$compileProvider'];
+export function config($translateProvider, $translatePartialLoaderProvider, $httpProvider, $compileProvider) {
+ const langOptions = appConfig.langOptions;
+ $translateProvider
+ .registerAvailableLanguageKeys(langOptions.langs, langOptions.langAliases)
+ // TODO: Circular dependency due to vnInterceptor
+ // .fallbackLanguage(langOptions.fallbackLang)
+ .determinePreferredLanguage(() => {
+ const locale = $translateProvider.resolveClientLocale();
+ if (langOptions.langs.indexOf(locale) !== -1)
+ return locale;
+ if (langOptions.langAliases[locale])
+ return langOptions.langAliases[locale];
+ return fallbackLang;
+ });
+
$translatePartialLoaderProvider.addPart(appName);
$httpProvider.interceptors.push('vnInterceptor');
diff --git a/modules/claim/front/action/index.html b/modules/claim/front/action/index.html
index 31db6dabd..19cb5c06e 100644
--- a/modules/claim/front/action/index.html
+++ b/modules/claim/front/action/index.html
@@ -6,19 +6,16 @@
auto-save="true"
on-save="$ctrl.onSave()">
-
-
-
-
@@ -75,7 +71,7 @@
vn-repeat-last on-last="$ctrl.focusLastInput()">
{{::saleClaimed.sale.itemFk | zeroFill:6}}
@@ -83,7 +79,7 @@
+ ng-click="ticketDescriptor.show($event, saleClaimed.sale.ticketFk)">
{{::saleClaimed.sale.ticketFk}}
@@ -117,7 +113,6 @@
-
-
diff --git a/modules/claim/front/action/index.js b/modules/claim/front/action/index.js
index a847ef009..fe9bb78df 100644
--- a/modules/claim/front/action/index.js
+++ b/modules/claim/front/action/index.js
@@ -63,14 +63,6 @@ export default class Controller extends Section {
});
}
- showTicketDescriptor(event, ticketFk) {
- this.$.ticketDescriptor.ticketFk = ticketFk;
- this.$.ticketDescriptor.parent = event.target;
- this.$.ticketDescriptor.show();
-
- event.preventDefault();
- }
-
focusLastInput() {
let inputs = document.querySelectorAll('#claimDestinationFk');
inputs[inputs.length - 1].querySelector('input').focus();
@@ -172,13 +164,6 @@ export default class Controller extends Section {
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
}
- // Item Descriptor
- showDescriptor(event, itemFk) {
- this.$.descriptor.itemFk = itemFk;
- this.$.descriptor.parent = event.target;
- this.$.descriptor.show();
- }
-
saveResponsibility(value) {
let query = `Claims/${this.$params.id}/updateClaimAction`;
diff --git a/modules/claim/front/descriptor/index.js b/modules/claim/front/descriptor/index.js
index 55048c20c..b65fc870b 100644
--- a/modules/claim/front/descriptor/index.js
+++ b/modules/claim/front/descriptor/index.js
@@ -1,7 +1,7 @@
import ngModule from '../module';
-import Component from 'core/lib/component';
+import Descriptor from 'salix/components/descriptor';
-class Controller extends Component {
+class Controller extends Descriptor {
constructor($element, $, $httpParamSerializer) {
super($element, $);
this.$httpParamSerializer = $httpParamSerializer;
@@ -49,14 +49,6 @@ class Controller extends Component {
};
}
- set quicklinks(value = {}) {
- this._quicklinks = Object.assign(value, this._quicklinks);
- }
-
- get quicklinks() {
- return this._quicklinks;
- }
-
showPickupOrder() {
const params = {
clientId: this.claim.clientFk,
@@ -80,7 +72,7 @@ class Controller extends Component {
claimId: this.claim.id
};
this.$http.get(`email/claim-pickup-order`, {params}).then(
- () => this.vnApp.showMessage(this.$translate.instant('Notification sent!'))
+ () => this.vnApp.showMessage(this.$t('Notification sent!'))
);
}
}
@@ -101,12 +93,11 @@ class Controller extends Component {
Controller.$inject = ['$element', '$scope', '$httpParamSerializer'];
-ngModule.component('vnClaimDescriptor', {
+ngModule.vnComponent('vnClaimDescriptor', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<',
- tags: '<',
- quicklinks: '<'
+ tags: '<'
}
});
diff --git a/modules/claim/front/detail/index.html b/modules/claim/front/detail/index.html
index 7e225b16a..794003e12 100644
--- a/modules/claim/front/detail/index.html
+++ b/modules/claim/front/detail/index.html
@@ -46,9 +46,9 @@
-
+
{{::saleClaimed.sale.concept}}
@@ -98,14 +98,17 @@
-
+
{{sale.landed | date: 'dd/MM/yyyy'}}
{{sale.quantity}}
-
- {{sale.concept}}
+
+ {{sale.itemFk}} - {{sale.concept}}
{{sale.price | currency: 'EUR':2}}
@@ -120,7 +123,7 @@
+ vn-id="itemDescriptor">
{
});
});
- describe('showItemDescriptor()', () => {
- it('should configure the descriptor then show it', () => {
- const itemId = 500;
- const event = {
- stopImmediatePropagation: () => {},
- target: 'the target element'
- };
- jest.spyOn(event, 'stopImmediatePropagation');
- jest.spyOn(controller.$.descriptor, 'show');
-
- controller.showItemDescriptor(event, itemId);
-
- expect(event.stopImmediatePropagation).toHaveBeenCalledWith();
- expect(controller.$.descriptor.itemFk).toEqual(itemId);
- expect(controller.$.descriptor.parent).toEqual(event.target);
- expect(controller.$.descriptor.show).toHaveBeenCalledWith();
- });
- });
-
describe('isClaimEditable()', () => {
it('should check if the claim is editable', () => {
controller.isClaimEditable();
diff --git a/modules/claim/front/development/index.html b/modules/claim/front/development/index.html
index 2b504be11..3a78e6374 100644
--- a/modules/claim/front/development/index.html
+++ b/modules/claim/front/development/index.html
@@ -42,7 +42,6 @@