Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
8be4e0fb1f
|
@ -1,5 +1,6 @@
|
||||||
import './styles/mdl-override.css';
|
import './styles/mdl-override.css';
|
||||||
import './styles/mdi-override.css';
|
import './styles/mdi-override.css';
|
||||||
|
import './styles/zoom-image.css';
|
||||||
|
|
||||||
export * from './module';
|
export * from './module';
|
||||||
export * from './directives/index';
|
export * from './directives/index';
|
||||||
|
|
|
@ -4,3 +4,4 @@ import './dialog';
|
||||||
import './validation';
|
import './validation';
|
||||||
import './acl';
|
import './acl';
|
||||||
import './on-error-src';
|
import './on-error-src';
|
||||||
|
import './zoom-image';
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
describe('Directive zoomImage', () => {
|
||||||
|
let idContainer = 'zoomImage';
|
||||||
|
let compile;
|
||||||
|
let scope;
|
||||||
|
let srcDefault = 'http://default.img.jpg/';
|
||||||
|
let srcZoom = 'http://zoom.img.jpg/';
|
||||||
|
let findContainer;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
angular.mock.module('client');
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($compile, $rootScope) => {
|
||||||
|
compile = $compile;
|
||||||
|
scope = $rootScope.$new();
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
if (findContainer) {
|
||||||
|
findContainer.parentNode.removeChild(findContainer);
|
||||||
|
findContainer = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getCompiledImage(imgHtml) {
|
||||||
|
let element = angular.element(imgHtml);
|
||||||
|
var compiledElement = compile(element)(scope);
|
||||||
|
scope.$digest();
|
||||||
|
return compiledElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should create zoom container when click into image', () => {
|
||||||
|
let image = getCompiledImage(`<img src="${srcDefault}" zoom-image>`);
|
||||||
|
image[0].click();
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
|
||||||
|
expect(findContainer).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detroy zoom container when click outside zoomed image', () => {
|
||||||
|
let image = getCompiledImage(`<img src="${srcDefault}" zoom-image>`);
|
||||||
|
image[0].click();
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
|
||||||
|
let findOutsideImage = findContainer.querySelector('.zoomImage-background');
|
||||||
|
findOutsideImage.click();
|
||||||
|
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
|
||||||
|
expect(findContainer).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create new image, into zoom container, with src as original image src', () => {
|
||||||
|
let image = getCompiledImage(`<img src="${srcDefault}" zoom-image>`);
|
||||||
|
image[0].click();
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
let findNewImage = findContainer.querySelector('img');
|
||||||
|
|
||||||
|
expect(findNewImage.src).toEqual(srcDefault);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create new image, into zoom container, with src likes zoomImage value', () => {
|
||||||
|
let image = getCompiledImage(`<img src="${srcDefault}" zoom-image="${srcZoom}">`);
|
||||||
|
image[0].click();
|
||||||
|
findContainer = document.getElementById(idContainer);
|
||||||
|
let findNewImage = findContainer.querySelector('img');
|
||||||
|
|
||||||
|
expect(findNewImage.src).toEqual(srcZoom);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,89 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
|
||||||
|
export function directive($timeout) {
|
||||||
|
let idContainer = 'zoomImage';
|
||||||
|
let container;
|
||||||
|
let background;
|
||||||
|
let image;
|
||||||
|
|
||||||
|
function createContainers(src) {
|
||||||
|
if (document.getElementById(idContainer)) {
|
||||||
|
destroyContainers();
|
||||||
|
}
|
||||||
|
container = document.createElement('div');
|
||||||
|
container.id = idContainer;
|
||||||
|
|
||||||
|
background = document.createElement('div');
|
||||||
|
background.className = 'zoomImage-background';
|
||||||
|
container.appendChild(background);
|
||||||
|
|
||||||
|
image = document.createElement('img');
|
||||||
|
image.src = src;
|
||||||
|
container.appendChild(image);
|
||||||
|
|
||||||
|
document.body.appendChild(container);
|
||||||
|
|
||||||
|
$timeout(() => {
|
||||||
|
resizeImage();
|
||||||
|
container.className = 'open';
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addListeners() {
|
||||||
|
background.addEventListener('click', destroyContainers);
|
||||||
|
document.addEventListener('keydown', e => keyDownHandler(e));
|
||||||
|
window.addEventListener('resize', resizeImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeListeners() {
|
||||||
|
if (container) {
|
||||||
|
background.removeEventListener('click', destroyContainers);
|
||||||
|
document.removeEventListener('keydown', e => keyDownHandler(e));
|
||||||
|
window.removeEventListener('resize', resizeImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyDownHandler(event) {
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
destroyContainers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroyContainers() {
|
||||||
|
if (document.getElementById(idContainer)) {
|
||||||
|
removeListeners();
|
||||||
|
container.parentNode.removeChild(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
container = undefined;
|
||||||
|
background = undefined;
|
||||||
|
image = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeImage() {
|
||||||
|
if (image) {
|
||||||
|
image.style.marginLeft = `-${Math.floor(image.clientWidth / 2)}px`;
|
||||||
|
image.style.marginTop = `-${Math.floor(image.clientHeight / 2)}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
priority: 9999,
|
||||||
|
link: function($scope, $element, $attrs) {
|
||||||
|
$element.on('click', function(event) {
|
||||||
|
let src = $attrs.zoomImage || $attrs.src;
|
||||||
|
if (src) {
|
||||||
|
createContainers(src);
|
||||||
|
addListeners();
|
||||||
|
} else
|
||||||
|
throw new Error('No image source detected');
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
directive.$inject = ['$timeout'];
|
||||||
|
|
||||||
|
ngModule.directive('zoomImage', directive);
|
|
@ -0,0 +1,40 @@
|
||||||
|
img[zoom-image]{
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#zoomImage, div#zoomImage .zoomImage-background {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
div#zoomImage{
|
||||||
|
opacity: 0;
|
||||||
|
transition: visibility 0s, opacity 0.5s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#zoomImage .zoomImage-background{
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
cursor: zoom-out;
|
||||||
|
}
|
||||||
|
div#zoomImage img{
|
||||||
|
z-index: 12;
|
||||||
|
position: fixed;
|
||||||
|
max-height: 98%;
|
||||||
|
max-width: 98%;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
opacity: 0;
|
||||||
|
transition: visibility 0s, opacity 1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#zoomImage.open {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#zoomImage.open img{
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ class ItemCard {
|
||||||
{relation: "producer"},
|
{relation: "producer"},
|
||||||
{relation: "intrastat"},
|
{relation: "intrastat"},
|
||||||
{relation: "expence"},
|
{relation: "expence"},
|
||||||
{relation: "taxClass"},
|
|
||||||
{relation: "itemTag", scope: {order: "priority ASC", include: {relation: "tag"}}}
|
{relation: "itemTag", scope: {order: "priority ASC", include: {relation: "tag"}}}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,8 +21,8 @@ describe('Item', () => {
|
||||||
describe('$onInit()', () => {
|
describe('$onInit()', () => {
|
||||||
it('should request to patch the propagation of tax status', () => {
|
it('should request to patch the propagation of tax status', () => {
|
||||||
controller.client = {id: 123, isEqualizated: false};
|
controller.client = {id: 123, isEqualizated: false};
|
||||||
$httpBackend.whenGET('/item/api/Items/undefined?filter={"include":[{"relation":"itemType"},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"},{"relation":"taxClass"},{"relation":"itemTag","scope":{"order":"priority ASC","include":{"relation":"tag"}}}]}').respond({data: 'item'});
|
$httpBackend.whenGET('/item/api/Items/undefined?filter={"include":[{"relation":"itemType"},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"},{"relation":"itemTag","scope":{"order":"priority ASC","include":{"relation":"tag"}}}]}').respond({data: 'item'});
|
||||||
$httpBackend.expectGET('/item/api/Items/undefined?filter={"include":[{"relation":"itemType"},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"},{"relation":"taxClass"},{"relation":"itemTag","scope":{"order":"priority ASC","include":{"relation":"tag"}}}]}');
|
$httpBackend.expectGET('/item/api/Items/undefined?filter={"include":[{"relation":"itemType"},{"relation":"origin"},{"relation":"ink"},{"relation":"producer"},{"relation":"intrastat"},{"relation":"expence"},{"relation":"itemTag","scope":{"order":"priority ASC","include":{"relation":"tag"}}}]}');
|
||||||
controller.$onInit();
|
controller.$onInit();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
<vn-title>New item</vn-title>
|
<vn-title>New item</vn-title>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Name" field="$ctrl.item.name" vn-focus></vn-textfield>
|
<vn-textfield vn-one label="Name" field="$ctrl.item.name" vn-focus></vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/ItemTypes"
|
url="/item/api/ItemTypes"
|
||||||
label="Type"
|
label="Type"
|
||||||
|
@ -20,8 +22,6 @@
|
||||||
field="$ctrl.item.typeFk"
|
field="$ctrl.item.typeFk"
|
||||||
>
|
>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/Intrastats"
|
url="/item/api/Intrastats"
|
||||||
label="Intrastat"
|
label="Intrastat"
|
||||||
|
@ -33,7 +33,6 @@
|
||||||
>
|
>
|
||||||
<tpl-item>{{$parent.$parent.item.description}}</tpl-item>
|
<tpl-item>{{$parent.$parent.item.description}}</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-textfield vn-one label="Relevancy" field="$ctrl.item.relevancy" type="number"></vn-textfield>
|
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
|
|
|
@ -60,19 +60,6 @@
|
||||||
initial-data="$ctrl.item.expence"
|
initial-data="$ctrl.item.expence"
|
||||||
></vn-autocomplete>
|
></vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete vn-one
|
|
||||||
url="/item/api/TaxClasses"
|
|
||||||
label="TaxClass"
|
|
||||||
show-field="description"
|
|
||||||
value-field="id"
|
|
||||||
order="description ASC"
|
|
||||||
filter-search="{where: {description: {regexp: 'search'}} }"
|
|
||||||
field="$ctrl.item.taxClassFk"
|
|
||||||
initial-data="$ctrl.item.taxClass"
|
|
||||||
><tpl-item>{{$parent.$parent.item.description}}</tpl-item></vn-autocomplete>
|
|
||||||
<vn-one></vn-one>
|
|
||||||
</vn-horizontal>
|
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
<img ng-src="/static/images/icon_item.png"/>
|
<img ng-src="/static/images/icon_item.png"/>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
<vn-auto pad-medium text-center>
|
<vn-auto pad-medium text-center>
|
||||||
<img ng-src="http://verdnatura.es/vn-image-data/catalog/200x200/{{$ctrl.item.image}}" on-error-src/>
|
<img
|
||||||
|
ng-src="http://verdnatura.es/vn-image-data/catalog/200x200/{{$ctrl.item.image}}"
|
||||||
|
zoom-image="http://verdnatura.es/vn-image-data/catalog/900x900/{{$ctrl.item.image}}" on-error-src/>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
<vn-auto pad-medium>
|
<vn-auto pad-medium>
|
||||||
<div><span translate>Id</span>: <b>{{$ctrl.item.id}}</b></div>
|
<div><span translate>Id</span>: <b>{{$ctrl.item.id}}</b></div>
|
||||||
|
|
|
@ -4,53 +4,42 @@
|
||||||
<vn-textfield vn-one label="Id" model="$ctrl.filter.id" vn-focus></vn-textfield>
|
<vn-textfield vn-one label="Id" model="$ctrl.filter.id" vn-focus></vn-textfield>
|
||||||
<vn-textfield vn-three label="Description" model="$ctrl.filter.description"></vn-textfield>
|
<vn-textfield vn-three label="Description" model="$ctrl.filter.description"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one label="Category" type="number" model="$ctrl.filter.category"></vn-textfield>
|
<vn-textfield vn-one label="Category" type="number" model="$ctrl.filter.category"></vn-textfield>
|
||||||
<vn-textfield vn-one label="Size" type="number" model="$ctrl.filter.itemSize"></vn-textfield>
|
<vn-textfield vn-one label="Size" type="number" model="$ctrl.filter.itemSize"></vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/ItemTypes"
|
url="/item/api/ItemTypes"
|
||||||
label="Type"
|
label="Type"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
field="$ctrl.filter.typeFk"
|
field="$ctrl.filter.typeFk">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/Inks"
|
url="/item/api/Inks"
|
||||||
label="Ink"
|
label="Ink"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
field="$ctrl.filter.inkFk"
|
field="$ctrl.filter.inkFk">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/Origins"
|
url="/item/api/Origins"
|
||||||
label="Origin"
|
label="Origin"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
field="$ctrl.filter.originFk"
|
field="$ctrl.filter.originFk">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
url="/item/api/Producers"
|
url="/item/api/Producers"
|
||||||
label="Producer"
|
label="Producer"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
field="$ctrl.filter.producerFk"
|
field="$ctrl.filter.producerFk">
|
||||||
>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
|
|
||||||
<vn-horizontal margin-large-top>
|
<vn-horizontal margin-large-top>
|
||||||
<vn-submit label="Search"></vn-submit>
|
<vn-submit label="Search"></vn-submit>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,6 @@
|
||||||
"model": "Expence",
|
"model": "Expence",
|
||||||
"foreignKey": "expenceFk"
|
"foreignKey": "expenceFk"
|
||||||
},
|
},
|
||||||
"taxClass": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "TaxClass",
|
|
||||||
"foreignKey": "taxClassFk"
|
|
||||||
},
|
|
||||||
"itemTag": {
|
"itemTag": {
|
||||||
"type": "hasMany",
|
"type": "hasMany",
|
||||||
"model": "ItemTag",
|
"model": "ItemTag",
|
||||||
|
|
Loading…
Reference in New Issue