diff --git a/include/class.queue.php b/include/class.queue.php index 4180162d566ee09abf694bd9d3982f983c6edda8..92ad23ae55f88659acdb2865a3ee57db2dbe3b79 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -1245,10 +1245,10 @@ extends QueueColumnAnnotation { return $query ->annotate(array( - '_locked' => new SqlExpr(array(new Q(array( + '_locked' => new SqlExpr(new Q(array( 'lock__expire__gt' => SqlFunction::NOW(), Q::not(array('lock__staff_id' => $thisstaff->getId())), - )))) + ))) )); } @@ -1262,6 +1262,65 @@ extends QueueColumnAnnotation { } } +class AssigneeAvatarDecoration +extends QueueColumnAnnotation { + static $icon = "user"; + static $desc = /* @trans */ 'Assignee Avatar'; + + function annotate($query) { + return $query->values('staff_id', 'team_id'); + } + + function getDecoration($row, $text) { + if ($row['staff_id'] && ($staff = Staff::lookup($row['staff_id']))) + return sprintf('<span class="avatar">%s</span>', + $staff->getAvatar(16)); + elseif ($row['team_id'] && ($team = Team::lookup($row['team_id']))) { + $avatars = []; + foreach ($team->getMembers() as $T) + $avatars[] = $T->getAvatar(16); + return sprintf('<span class="avatar group %s">%s</span>', + count($avatars), implode('', $avatars)); + } + } + + function isVisible($row) { + return $row['staff_id'] + $row['team_id'] > 0; + } + + function getWidth($row) { + if (!$this->isVisible($row)) + return 0; + + // If assigned to a team with no members, return 0 width + $width = 10; + if ($row['team_id'] && ($team = Team::lookup($row['team_id']))) + $width += (count($team->getMembers()) - 1) * 10; + + return $width ? $width + 10 : $width; + } +} + +class UserAvatarDecoration +extends QueueColumnAnnotation { + static $icon = "user"; + static $desc = /* @trans */ 'User Avatar'; + + function annotate($query) { + return $query->values('user_id'); + } + + function getDecoration($row, $text) { + if ($row['user_id'] && ($user = User::lookup($row['user_id']))) + return sprintf('<span class="avatar">%s</span>', + $user->getAvatar(16)); + } + + function isVisible($row) { + return $row['user_id'] > 0; + } +} + class DataSourceField extends ChoiceField { function getChoices($verbose=false) { @@ -1548,8 +1607,9 @@ extends VerySimpleModel { } function getFilter() { - if ($this->filter) - return QueueColumnFilter::getInstance($this->filter); + if ($this->filter + && ($F = QueueColumnFilter::getInstance($this->filter))) + return $F; } function getName() { @@ -2095,8 +2155,9 @@ abstract class QueueColumnFilter { static function getInstance($id) { if (isset(static::$registry[$id])) { - list(, $class) = static::$registry[$id]; - return new $class(); + list(, $class) = @static::$registry[$id]; + if ($class && class_exists($class)) + return new $class(); } } diff --git a/include/class.user.php b/include/class.user.php index e4cadc37fb7eb51bebf45a9d1c6a8fbb0f37ea78..a24efed69de28ec41cb2b289edf3be086c086264 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -269,10 +269,13 @@ implements TemplateVariable, Searchable { return new EmailAddress($this->default_email->address); } - function getAvatar() { + function getAvatar($size=null) { global $cfg; $source = $cfg->getClientAvatarSource(); - return $source->getAvatar($this); + $avatar = $source->getAvatar($this); + if (isset($size)) + $avatar->setSize($size); + return $avatar; } function getFullName() { diff --git a/scp/css/scp.css b/scp/css/scp.css index c9e2f4d192e295530bc1f3ba77b3f81dbe908be7..725c169b9866d9be8827bbd6872d6a1352dfce17 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -1532,6 +1532,7 @@ a#post-note:hover { margin-left: -60px; display:inline-block; width:48px; + max-height:48px; height:auto; } .avatar { @@ -1547,7 +1548,9 @@ img.avatar { margin-right: 5px; } .avatar > img.avatar { - width: 100%; + width: auto; + max-width: 100%; + max-height: 100%; height: auto; } .thread-entry .header { @@ -3598,6 +3601,28 @@ a.attachment { .conditions .condition + .condition { margin-top: 10px; } +img.avatar + img.avatar { + margin-left: -14px; + z-index: 1; + transition: margin-left 0.1s linear; +} +.avatar.group:hover > img.avatar + img.avatar { + margin-left: -4px; +} +.avatar.group { + position: relative; + z-index: 1; + transition: margin-right 0.1s linear; +} + +.avatar.group.\32:hover { margin-right: -10px; } +.avatar.group.\33:hover { margin-right: -20px; } +.avatar.group.\34:hover { margin-right: -30px; } +.avatar.group.\35:hover { margin-right: -40px; } +.avatar.group.\36:hover { margin-right: -50px; } +.avatar.group.\37:hover { margin-right: -60px; } +.avatar.group.\38:hover { margin-right: -70px; } +.avatar.group.\39:hover { margin-right: -80px; } /* FIXME: Drop this with select2 4.0.1 * Fixes a rendering issue on Safari