Bivio::UI::XHTML::Widget::RealmDropDown
# Copyright (c) 2007-2009 bivio Software, Inc. All Rights Reserved.
# $Id$
package Bivio::UI::XHTML::Widget::RealmDropDown;
use strict;
use Bivio::Base 'Widget.If';
use Bivio::UI::ViewLanguageAUTOLOAD;
my($_F) = b_use('UI.Facade');
my($_RT) = b_use('Auth.RealmType');
my($_R) = b_use('Auth.Role');
my($_REQUIRED_ROLE_GROUP) = b_use('Model.UserForumList')
->REQUIRED_ROLE_GROUP;
sub DISPLAY_NAME_FIELD {
return 'name';
}
sub NEW_ARGS {
return shift->can('DEFAULT_REALM_TYPES') ? [] : [qw(realm_types)];
}
sub initialize {
my($self) = @_;
b_die('pass realm_types instead of realm_type')
if $self->unsafe_get('realm_type');
$self->put_unless_exists(
control => [sub {$self->internal_control_value(@_)}],
control_on_value => If(
[sub {_one_choice($self, shift)}],
SPAN(_curr_realm($self), {
class => $self->unsafe_get('single_row_class') || 'dd_link',
}),
_drop_down($self),
),
);
return shift->SUPER::initialize(@_);
}
sub internal_choices {
my($self, $source) = @_;
return [sort(
{$a->{display_name} cmp $b->{display_name}}
@{$source->req->map_user_realms(
sub {
my($row) = @_;
return {
name => $row->{'RealmOwner.name'},
display_name => $row->{
'RealmOwner.' . $self->DISPLAY_NAME_FIELD},
};
},
{
'RealmOwner.realm_type' => [
map($_RT->from_any($_), @{_realm_types($self)}),
],
roles => $_REQUIRED_ROLE_GROUP,
},
)},
)];
}
sub internal_control_value {
my($self, $source) = @_;
return @{_choices($self, $source)} == 0 ? 0 : 1;
}
sub _choices {
my($self, $source) = @_;
return $source->req->cache_for_auth_user(
[$self, @{_realm_types($self)}],
sub {$self->internal_choices($source)},
);
}
sub _curr_realm {
my($self) = @_;
return String([qw(->req auth_realm owner), $self->DISPLAY_NAME_FIELD]);
}
sub _drop_down {
my($self) = @_;
my($rt) = _realm_types($self);
my($first_rt) = $rt->[0];
my($res) = DropDown(
If([[qw(->req auth_realm type)], '->equals_by_name', @$rt],
_curr_realm($self),
Prose(vs_text('RealmDropDown', $first_rt)),
),
TaskMenu([
Simple([sub {
my($source) = @_;
my($realms) = _choices($self, $source);
my($r) = $source->req('auth_realm');
$r = $r->get('type')->equals_by_name(@$rt)
? $r->get('owner_name')
: '';
return Join([
map(
Link(String(_value($_, 'display_name')) => URI({
realm => _value($_, 'name'),
task_id => _value($_, 'task_id')
|| $self->render_simple_attr(
task_id => $source,
) || ($first_rt . '_HOME'),
query => undef,
path_info => undef,
})),
grep(_eq($_, $r), @$realms),
grep(!_eq($_, $r), @$realms),
),
]);
}]),
], {
class => 'dd_menu',
}),
)->put(
%{$self->unsafe_get('drop_down_attrs') || {}},
);
return $_F->if_2014style(
$res,
DIV_task_menu_wrapper($res),
);
}
sub _eq {
my($choice, $name) = @_;
return (_value($choice, 'name') || '') eq $name;
}
sub _one_choice {
my($self, $source) = @_;
my($choices) = _choices($self, $source);
my($ar) = $source->req('auth_realm');
return @$choices == 1
&& $ar->has_owner
&& _value($choices->[0], 'name') eq $ar->get('owner_name');
}
sub _realm_types {
my($self) = @_;
return $self->get_if_exists_else_put(_realm_types => sub {
my($rt) = $self->unsafe_get('realm_types')
|| $self->DEFAULT_REALM_TYPES;
return [map(
$_RT->from_any($_)->get_name,
ref($rt) ? @$rt : $rt,
)];
});
}
sub _value {
my($choice, $which) = @_;
return $choice->{$which}
if ref($choice);
return $choice
if $which =~ /name/;
return undef;
}
1;