user image
This commit is contained in:
parent
fc957eda6c
commit
4ea5993dcc
|
@ -0,0 +1,94 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('download', {
|
||||
description: 'Get the user image',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'collection',
|
||||
type: 'String',
|
||||
description: 'The image collection',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'size',
|
||||
type: 'String',
|
||||
description: 'The image size',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
description: 'The user id',
|
||||
http: {source: 'path'}
|
||||
}
|
||||
|
||||
],
|
||||
returns: [
|
||||
{
|
||||
arg: 'body',
|
||||
type: 'file',
|
||||
root: true
|
||||
},
|
||||
{
|
||||
arg: 'Content-Type',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
},
|
||||
{
|
||||
arg: 'Content-Disposition',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/:collection/:size/:id/download`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.download = async function(collection, size, id) {
|
||||
const filter = {
|
||||
where: {
|
||||
collectionFk: collection,
|
||||
name: id},
|
||||
include: {
|
||||
relation: 'collection',
|
||||
scope: {
|
||||
fields: ['name', 'readRoleFk'],
|
||||
include: {
|
||||
relation: 'readRole'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const image = await Self.app.models.Image.findOne(filter);
|
||||
if (!image) return;
|
||||
|
||||
const imageRole = image.collection().readRole().name;
|
||||
const hasRole = await Self.app.models.Account.hasRole(id, imageRole);
|
||||
if (!hasRole)
|
||||
throw new UserError(`You don't have enough privileges`);
|
||||
|
||||
let file;
|
||||
let env = process.env.NODE_ENV;
|
||||
if (env && env != 'development') {
|
||||
file = {
|
||||
path: `/var/lib/salix/image/${collection}/${size}/${id}.png`,
|
||||
contentType: 'image/png',
|
||||
name: `${id}.png`
|
||||
};
|
||||
} else {
|
||||
file = {
|
||||
path: `${process.cwd()}/storage/image/${collection}/${size}/${id}.png`,
|
||||
contentType: 'image/png',
|
||||
name: `${id}.png`
|
||||
};
|
||||
}
|
||||
await fs.access(file.path);
|
||||
let stream = fs.createReadStream(file.path);
|
||||
return [stream, file.contentType, `filename="${file.name}"`];
|
||||
};
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('image download()', () => {
|
||||
const collection = 'user';
|
||||
const size = '160x160';
|
||||
|
||||
it('should return the image content-type of the user', async() => {
|
||||
const userId = 9;
|
||||
const image = await app.models.Image.download(collection, size, userId);
|
||||
|
||||
expect(image[1]).toEqual('image/png');
|
||||
});
|
||||
|
||||
it(`should don't return an image if the user don't have it`, async() => {
|
||||
const userId = 8;
|
||||
const image = await app.models.Image.download(collection, size, userId);
|
||||
|
||||
expect(image).toBeUndefined();
|
||||
});
|
||||
});
|
|
@ -43,7 +43,12 @@
|
|||
"model": "ImageCollectionSize",
|
||||
"foreignKey": "collectionFk",
|
||||
"property": "id"
|
||||
}
|
||||
},
|
||||
"readRole": {
|
||||
"type": "belongsTo",
|
||||
"model": "Role",
|
||||
"foreignKey": "readRoleFk"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
|
|
|
@ -3,6 +3,8 @@ const sharp = require('sharp');
|
|||
const path = require('path');
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/image/download')(Self);
|
||||
|
||||
Self.getPath = function() {
|
||||
return '/var/lib/salix/image';
|
||||
};
|
||||
|
|
|
@ -29,6 +29,14 @@
|
|||
"default": 0
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"collection": {
|
||||
"type": "belongsTo",
|
||||
"model": "ImageCollection",
|
||||
"foreignKey": "collectionFk",
|
||||
"primaryKey": "name"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierContact', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
ALTER TABLE `hedera`.`imageCollection`
|
||||
ADD COLUMN `readRoleFk` VARCHAR(45) NULL DEFAULT NULL AFTER `column`;
|
||||
|
||||
update `hedera`.`imageCollection` set `readRoleFk` = 1 where id = 6;
|
|
@ -443,7 +443,7 @@ USE `hedera`;
|
|||
|
||||
LOCK TABLES `imageCollection` WRITE;
|
||||
/*!40000 ALTER TABLE `imageCollection` DISABLE KEYS */;
|
||||
INSERT INTO `imageCollection` VALUES (1,'catalog','Artículo',3840,2160,'Item','image','vn','item','image'),(4,'link','Enlace',200,200,'Link','image','hedera','link','image'),(5,'news','Noticias',800,1200,'New','image','hedera','news','image');
|
||||
INSERT INTO `imageCollection` VALUES (1,'catalog','Artículo',3840,2160,'Item','image','vn','item','image'),(4,'link','Enlace',200,200,'Link','image','hedera','link','image'),(5,'news','Noticias',800,1200,'New','image','hedera','news','image'),('6','user','Usuario','800','1200','Account','image','account','user','image');
|
||||
/*!40000 ALTER TABLE `imageCollection` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
|
@ -2141,3 +2141,10 @@ INSERT INTO `vn`.`campaign`(`code`, `dated`)
|
|||
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-11-01')),
|
||||
('allSaints', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -3 YEAR)), '-11-01'));
|
||||
|
||||
INSERT INTO `hedera`.`image`(`collectionFk`, `name`)
|
||||
VALUES
|
||||
('user', 9);
|
||||
|
||||
INSERT INTO `hedera`.`imageCollectionSize`(`id`, `collectionFk`,`width`, `height`)
|
||||
VALUES
|
||||
(1, 4, 160, 160);
|
|
@ -31,12 +31,14 @@
|
|||
ng-if="$ctrl.rightMenu"
|
||||
ng-click="$ctrl.rightMenu.show()">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
id="user"
|
||||
icon="account_circle"
|
||||
<button class="buttonAccount">
|
||||
<img
|
||||
ng-src="{{$ctrl.getImageUrl()}}"
|
||||
ng-click="userPopover.show($event)"
|
||||
translate-attr="{title: 'Account'}">
|
||||
</vn-icon-button>
|
||||
translate-attr="{title: 'Account'}"
|
||||
on-error-src/>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<vn-menu vn-id="apps-menu">
|
||||
<vn-list class="modules-menu">
|
||||
|
|
|
@ -18,6 +18,14 @@ export class Layout extends Component {
|
|||
window.localStorage.currentUserWorkerId = json.data.id;
|
||||
});
|
||||
}
|
||||
|
||||
getImageUrl() {
|
||||
if (!this.$.$root.user) return;
|
||||
|
||||
const userId = this.$.$root.user.id;
|
||||
const token = this.vnToken.token;
|
||||
return `/api/Images/user/160x160/${userId}/download?access_token=${token}`;
|
||||
}
|
||||
}
|
||||
Layout.$inject = ['$element', '$scope', 'vnModules'];
|
||||
|
||||
|
|
|
@ -22,4 +22,19 @@ describe('Component vnLayout', () => {
|
|||
expect(controller.$.$root.user.name).toEqual('batman');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getImageUrl()', () => {
|
||||
it('should return the url image if the user is defined', () => {
|
||||
controller.$.$root.user = {id: 1};
|
||||
const url = controller.getImageUrl();
|
||||
|
||||
expect(url).not.toBe(3);
|
||||
});
|
||||
|
||||
it('should return undefined if the user is not defined', () => {
|
||||
const url = controller.getImageUrl();
|
||||
|
||||
expect(url).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -109,6 +109,14 @@ vn-layout {
|
|||
}
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.buttonAccount {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
@media screen and (max-width: $mobile-width) {
|
||||
& > vn-topbar {
|
||||
& > .start > .logo {
|
||||
|
@ -147,3 +155,4 @@ vn-layout {
|
|||
font-size: 1.5rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
<vn-popover vn-id="popover">
|
||||
<vn-vertical class="user-popover vn-pa-md">
|
||||
<div class="profile-card vn-pb-md">
|
||||
<vn-icon icon="account_circle"></vn-icon>
|
||||
<img
|
||||
ng-src="{{$ctrl.getImageUrl($root.user.id)}}"
|
||||
on-error-src/>
|
||||
<div class="vn-pl-sm">
|
||||
<div>
|
||||
<div class="user">
|
||||
|
|
|
@ -3,12 +3,13 @@ import './style.scss';
|
|||
import config from '../../config.json';
|
||||
|
||||
class Controller {
|
||||
constructor($, $translate, vnConfig, vnAuth) {
|
||||
constructor($, $translate, vnConfig, vnAuth, vnToken) {
|
||||
Object.assign(this, {
|
||||
$,
|
||||
$translate,
|
||||
vnConfig,
|
||||
vnAuth,
|
||||
vnToken,
|
||||
lang: $translate.use(),
|
||||
langs: []
|
||||
});
|
||||
|
@ -77,8 +78,12 @@ class Controller {
|
|||
this.$.companies.refresh();
|
||||
this.$.popover.show(event.target);
|
||||
}
|
||||
|
||||
getImageUrl(userId) {
|
||||
return '/api/Images/user/160x160/' + userId + '/download?access_token=' + this.vnToken.token;
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$scope', '$translate', 'vnConfig', 'vnAuth'];
|
||||
Controller.$inject = ['$scope', '$translate', 'vnConfig', 'vnAuth', 'vnToken'];
|
||||
|
||||
ngModule.vnComponent('vnUserPopover', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -57,5 +57,13 @@ describe('Salix', () => {
|
|||
expect(controller.companyFk).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getImageUrl()', () => {
|
||||
it('should return de url image', () => {
|
||||
const url = controller.getImageUrl();
|
||||
|
||||
expect(url).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
font-size: 5rem;
|
||||
color: $color-font-bg-marginal;
|
||||
}
|
||||
img {
|
||||
width: 80px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Loading…
Reference in New Issue