/* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _GraphPanel = require('./GraphPanel'); var _GraphPanel2 = _interopRequireDefault(_GraphPanel); var _ActionsPanel = require('./ActionsPanel'); var _ActionsPanel2 = _interopRequireDefault(_ActionsPanel); var debounce = require('lodash.debounce'); var React = require('react'); var Color = require('color'); var _require = require('material-ui'); var FontIcon = _require.FontIcon; var Popover = _require.Popover; var Paper = _require.Paper; var Avatar = _require.Avatar; var CardTitle = _require.CardTitle; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var MetaCacheService = require('pydio/http/meta-cache-service'); var PydioApi = require('pydio/http/api'); /** * Generic component for display a user and her avatar (first letters or photo) */ var UserAvatar = (function (_React$Component) { _inherits(UserAvatar, _React$Component); function UserAvatar(props, context) { _classCallCheck(this, UserAvatar); _React$Component.call(this, props, context); this.state = { user: null, avatar: null, graph: null }; } UserAvatar.prototype.componentDidMount = function componentDidMount() { if (this.props.pydio.user && this.props.pydio.user.id === this.props.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else if (this.props.userType === 'user') { this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(this.props.userId); } }; UserAvatar.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (!this.props.userId || this.props.userId !== nextProps.userId) { this.setState({ label: nextProps.userId }); } if (this.props.pydio && this.props.pydio.user && this.props.pydio.user.id === nextProps.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(nextProps.userId); } }; UserAvatar.prototype.componentWillUnmount = function componentWillUnmount() { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } }; UserAvatar.prototype.loadLocalData = function loadLocalData() { var pydio = this.props.pydio; if (!pydio.user) { this.setState({ label: '', avatar: null }); return; } var userName = pydio.user.getPreference('USER_DISPLAY_NAME') || pydio.user.id; var avatarId = pydio.user.getPreference('avatar'); var avatarUrl = PydioApi.getClient().buildUserAvatarUrl(pydio.user.id, avatarId); this.setState({ label: userName, avatar: avatarUrl }); if (!avatarUrl) { this.loadFromExternalProvider(); } }; UserAvatar.prototype.loadPublicData = function loadPublicData(userId) { var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; if (this.cache.hasKey(namespace, userId)) { this.setState(this.cache.getByKey(namespace, userId)); return; } PydioApi.getClient().request({ get_action: 'user_public_data', user_id: userId, graph: this.props.richCard ? 'true' : 'false' }, (function (transport) { var data = transport.responseJSON; if (!data || data.error) { this.cache.setKey(namespace, userId, {}); return; } var user = data.user; var graph = data.graph; var avatarUrl = undefined; var avatarId = user.avatar || null; var label = user.label || userId; if (!user.avatar) { this.loadFromExternalProvider(); } else { avatarUrl = PydioApi.getClient().buildUserAvatarUrl(userId, avatarId); } this.cache.setKey(namespace, userId, { user: user, graph: graph, avatar: avatarUrl }); this.setState({ user: user, graph: graph, avatar: avatarUrl }); }).bind(this)); }; UserAvatar.prototype.loadFromExternalProvider = function loadFromExternalProvider() { if (!this.props.pydio.getPluginConfigs("ajxp_plugin[@id='action.avatar']").get("AVATAR_PROVIDER")) { return; } var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; PydioApi.getClient().request({ get_action: 'get_avatar_url', userid: this.props.userId }, (function (transport) { this.setState({ avatar: transport.responseText }); }).bind(this)); }; UserAvatar.prototype.render = function render() { var _this = this; var _state = this.state; var user = _state.user; var avatar = _state.avatar; var graph = _state.graph; var _props = this.props; var pydio = _props.pydio; var userId = _props.userId; var userType = _props.userType; var icon = _props.icon; var style = _props.style; var labelStyle = _props.labelStyle; var avatarStyle = _props.avatarStyle; var avatarSize = _props.avatarSize; var className = _props.className; var avatarClassName = _props.avatarClassName; var labelClassName = _props.labelClassName; var displayLabel = _props.displayLabel; var displayAvatar = _props.displayAvatar; var useDefaultAvatar = _props.useDefaultAvatar; var richCard = _props.richCard; var cardSize = _props.cardSize; var muiTheme = _props.muiTheme; var label = this.state.label; var userTypeLabel = undefined; if (user) { label = user.label; } else if (!label) { label = this.props.userLabel || this.props.userId; } var avatarContent = undefined, avatarColor = undefined, avatarIcon = undefined; if (richCard) { displayAvatar = useDefaultAvatar = displayLabel = true; } if (displayAvatar && !avatar && label && (!displayLabel || useDefaultAvatar)) { var avatarsColor = muiTheme.palette.avatarsColor; if (userType === 'group' || userType === 'team' || userId.indexOf('AJXP_GRP_/') === 0 || userId.indexOf('/AJXP_TEAM/') === 0) { avatarsColor = Color(avatarsColor).darken(0.2).toString(); } var iconClassName = undefined; switch (userType) { case 'group': iconClassName = 'mdi mdi-account-multiple'; userTypeLabel = '289'; break; case 'team': iconClassName = 'mdi mdi-account-multiple-outline'; userTypeLabel = '603'; break; case 'remote': iconClassName = 'mdi mdi-account-network'; userTypeLabel = '604'; break; default: iconClassName = 'mdi mdi-account'; userTypeLabel = user ? user.external ? '589' : '590' : '288'; break; } if (icon) iconClassName = icon; if (userTypeLabel) userTypeLabel = pydio.MessageHash[userTypeLabel]; if (richCard) { avatarIcon = React.createElement(FontIcon, { className: iconClassName, style: { color: avatarsColor } }); avatarColor = '#f5f5f5'; } else { avatarColor = avatarsColor; if (iconClassName) { avatarIcon = React.createElement(FontIcon, { className: iconClassName }); } else { avatarContent = label.split(' ').map(function (word) { return word[0]; }).join('').substring(0, 2); if (avatarContent.length < 2) avatarContent = label.substring(0, 2); } } } var reloadAction = undefined, onEditAction = undefined, onMouseOver = undefined, onMouseOut = undefined, popover = undefined; if (richCard) { (function () { displayAvatar = true; style = _extends({}, style, { flexDirection: 'column' }); avatarSize = cardSize ? cardSize : '100%'; avatarStyle = { borderRadius: 0 }; var localReload = function localReload() { MetaCacheService.getInstance().deleteKey('user_public_data-rich', _this.props.userId); _this.loadPublicData(_this.props.userId); }; reloadAction = function () { localReload(); if (_this.props.reloadAction) _this.props.reloadAction(); }; onEditAction = function () { localReload(); if (_this.props.onEditAction) _this.props.onEditAction(); }; })(); } else if (this.props.richOnHover) { (function () { onMouseOut = function () { if (!_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }; onMouseOut = debounce(onMouseOut, 350); onMouseOver = function (e) { _this.setState({ showPopover: true, popoverAnchor: e.currentTarget }); onMouseOut.cancel(); }; var onMouseOverInner = function onMouseOverInner(e) { _this.setState({ showPopover: true }); onMouseOut.cancel(); }; var lockOnSubPopoverOpen = function lockOnSubPopoverOpen(status) { _this.lockedBySubPopover = status; onMouseOverInner(); }; popover = React.createElement( Popover, { open: _this.state.showPopover, anchorEl: _this.state.popoverAnchor, onRequestClose: function (reason) { if (reason !== 'clickAway' || !_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }, anchorOrigin: { horizontal: "left", vertical: "center" }, targetOrigin: { horizontal: "right", vertical: "center" }, useLayerForClickAway: false }, React.createElement( Paper, { zDepth: 2, style: { width: 220, height: 320, overflowY: 'auto' }, onMouseOver: onMouseOverInner, onMouseOut: onMouseOut }, React.createElement(UserAvatar, _extends({}, _this.props, { richCard: true, richOnHover: false, cardSize: 220, lockOnSubPopoverOpen: lockOnSubPopoverOpen })) ) ); })(); } var avatarComponent = React.createElement( Avatar, { src: avatar, icon: avatarIcon, size: avatarSize, style: this.props.avatarOnly ? this.props.style : avatarStyle, backgroundColor: avatarColor }, avatarContent ); if (this.props.avatarOnly) { return avatarComponent; } return React.createElement( 'div', { className: className, style: style, onMouseOver: onMouseOver, onMouseOut: onMouseOut }, displayAvatar && (avatar || avatarContent || avatarIcon) && avatarComponent, displayLabel && !richCard && React.createElement( 'div', { className: labelClassName, style: labelStyle }, label ), displayLabel && richCard && React.createElement(CardTitle, { style: { textAlign: 'center' }, title: label, subtitle: userTypeLabel }), richCard && user && React.createElement(_ActionsPanel2['default'], _extends({}, this.state, this.props, { reloadAction: reloadAction, onEditAction: onEditAction })), graph && React.createElement(_GraphPanel2['default'], _extends({ graph: graph }, this.props, { userLabel: label, reloadAction: reloadAction, onEditAction: onEditAction })), this.props.children, popover ); }; return UserAvatar; })(React.Component); UserAvatar.propTypes = { /** * Id of the user to be loaded */ userId: React.PropTypes.string.isRequired, /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Label of the user, if we already have it (otherwise will be loaded) */ userLabel: React.PropTypes.string, /** * Type of user */ userType: React.PropTypes.oneOf(['user', 'group', 'remote', 'team']), /** * Icon to be displayed in avatar */ icon: React.PropTypes.string, /** * Display a rich card or a simple avatar+label chip */ richCard: React.PropTypes.bool, /** * If not rich, display a rich card as popover on mouseover */ richOnHover: React.PropTypes.bool, /** * Add edit action to the card */ userEditable: React.PropTypes.bool, /** * Triggered after successful edition */ onEditAction: React.PropTypes.func, /** * Triggered after deletion */ onDeleteAction: React.PropTypes.func, /** * Triggered if a reload is required */ reloadAction: React.PropTypes.func, /** * Display label element or not */ displayLabel: React.PropTypes.bool, /** * Display avatar element or not */ displayAvatar: React.PropTypes.bool, /** * Display only avatar */ avatarOnly: React.PropTypes.bool, /** * Use default avatar */ useDefaultAvatar: React.PropTypes.bool, /** * Avatar size, 40px by default */ avatarSize: React.PropTypes.number, /** * Add class name to root element */ className: React.PropTypes.string, /** * Add class name to label element */ labelClassName: React.PropTypes.string, /** * Add class name to avatar element */ avatarClassName: React.PropTypes.string, /** * Add style to root element */ style: React.PropTypes.object, /** * Add style to label element */ labelStyle: React.PropTypes.object, /** * Add style to avatar element */ avatarStyle: React.PropTypes.object }; UserAvatar.defaultProps = { displayLabel: true, displayAvatar: true, avatarSize: 40, userType: 'user', className: 'user-avatar-widget', avatarClassName: 'user-avatar', labelClassName: 'user-label' }; exports['default'] = UserAvatar = muiThemeable()(UserAvatar); exports['default'] = UserAvatar; module.exports = exports['default'];