sub header {
- $main::lxdebug->enter_sub();
+ $::lxdebug->enter_sub;
- # extra code ist currently only used by menuv3 and menuv4 to set their css.
+ # extra code is currently only used by menuv3 and menuv4 to set their css.
# it is strongly deprecated, and will be changed in a future version.
my ($self, $extra_code) = @_;
+ my $db_charset = $::dbcharset || Common::DEFAULT_CHARSET;
+ my @header;
+
+ $::lxdebug->leave_sub and return if !$ENV{HTTP_USER_AGENT} || $self->{header}++;
+
+ $self->{favicon} ||= "favicon.ico";
+ $self->{titlebar} = "$self->{title} - $self->{titlebar}" if $self->{title};
+
+ # build includes
+ if ($self->{refresh_url} || $self->{refresh_time}) {
+ my $refresh_time = $self->{refresh_time} || 3;
+ my $refresh_url = $self->{refresh_url} || $ENV{REFERER};
+ push @header, "<meta http-equiv='refresh' content='$refresh_time;$refresh_url'>";
+ }
+
+ push @header, "<link rel='stylesheet' href='css/$_' type='text/css' title='Lx-Office stylesheet'>"
+ for grep { -f "css/$_" } apply { s|.*/|| } $self->{stylesheet}, $self->{stylesheets};
+
+ push @header, "<style type='text/css'>\@page { size:landscape; }</style>" if $self->{landscape};
+ push @header, "<link rel='shortcut icon' href='$self->{favicon}' type='image/x-icon'>" if -f $self->{favicon};
+ push @header, '<script type="text/javascript" src="js/jquery.js"></script>',
+ '<script type="text/javascript" src="js/common.js"></script>',
+ '<style type="text/css">@import url(js/jscalendar/calendar-win2k-1.css);</style>',
+ '<script type="text/javascript" src="js/jscalendar/calendar.js"></script>',
+ '<script type="text/javascript" src="js/jscalendar/lang/calendar-de.js"></script>',
+ '<script type="text/javascript" src="js/jscalendar/calendar-setup.js"></script>',
+ '<script type="text/javascript" src="js/part_selection.js"></script>';
+ push @header, $self->{javascript} if $self->{javascript};
+ push @header, map { $_->show_javascript } @{ $self->{AJAX} || [] };
+ push @header, "<script type='text/javascript'>function fokus(){ document.$self->{fokus}.focus(); }</script>" if $self->{fokus};
+ push @header, sprintf "<script type='text/javascript'>top.document.title='%s';</script>",
+ join ' - ', grep $_, $self->{title}, $self->{login}, $::myconfig{dbname}, $self->{version} if $self->{title};
- if ($self->{header}) {
- $main::lxdebug->leave_sub();
- return;
- }
-
- my ($stylesheet, $favicon, $pagelayout);
-
- if ($ENV{HTTP_USER_AGENT}) {
- my $doctype;
-
- if ($ENV{'HTTP_USER_AGENT'} =~ m/MSIE\s+\d/) {
- # Only set the DOCTYPE for Internet Explorer. Other browsers have problems displaying the menu otherwise.
- $doctype = qq|<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n|;
- }
-
- my $stylesheets = "$self->{stylesheet} $self->{stylesheets}";
-
- $stylesheets =~ s|^\s*||;
- $stylesheets =~ s|\s*$||;
- foreach my $file (split m/\s+/, $stylesheets) {
- $file =~ s|.*/||;
- next if (! -f "css/$file");
-
- $stylesheet .= qq|<link rel="stylesheet" href="css/$file" TYPE="text/css" TITLE="Lx-Office stylesheet">\n|;
- }
-
- $self->{favicon} = "favicon.ico" unless $self->{favicon};
-
- if ($self->{favicon} && (-f "$self->{favicon}")) {
- $favicon =
- qq|<LINK REL="shortcut icon" HREF="$self->{favicon}" TYPE="image/x-icon">
- |;
- }
-
- my $db_charset = $main::dbcharset ? $main::dbcharset : Common::DEFAULT_CHARSET;
-
- if ($self->{landscape}) {
- $pagelayout = qq|<style type="text/css">
- \@page { size:landscape; }
- </style>|;
- }
-
- my $fokus = qq|
+ # if there is a title, we put some JavaScript in to the page, wich writes a
+ # meaningful title-tag for our frameset.
+ my $title_hack = '';
+ if ($self->{title}) {
+ $title_hack = qq|
<script type="text/javascript">
<!--
- function fokus() {
- document.$self->{fokus}.focus();
- }
+ // Write a meaningful title-tag for our frameset.
+ top.document.title="| . $self->{"title"} . qq| - | . $self->{"login"} . qq| - | . $::myconfig{dbname} . qq| - V| . $self->{"version"} . qq|";
//-->
- </script>
- | if $self->{"fokus"};
-
- # if there is a title, we put some JavaScript in to the page, wich writes a
- # meaningful title-tag for our frameset.
- my $title_hack;
- if ($self->{"title"}){
- $title_hack = qq|
- <script type="text/javascript">
- <!--
- // Write a meaningful title-tag for our frameset.
- top.document.title="| . $self->{"title"} . qq| - | . $self->{"login"} . qq| - | . $::myconfig{dbname} . qq| - V| . $self->{"version"} . qq|";
- //-->
- </script>
- |;
- }
-
- #Set Calendar
- my $jsscript = "";
- if ($self->{jsscript} == 1) {
-
- $jsscript = qq|
- <script type="text/javascript" src="js/jquery.js"></script>
- <script type="text/javascript" src="js/common.js"></script>
- <style type="text/css">\@import url(js/jscalendar/calendar-win2k-1.css);</style>
- <script type="text/javascript" src="js/jscalendar/calendar.js"></script>
- <script type="text/javascript" src="js/jscalendar/lang/calendar-de.js"></script>
- <script type="text/javascript" src="js/jscalendar/calendar-setup.js"></script>
- $self->{javascript}
- |;
- }
-
- $self->{titlebar} =
- ($self->{title})
- ? "$self->{title} - $self->{titlebar}"
- : $self->{titlebar};
- my $ajax = "";
- for my $item (@ { $self->{AJAX} || [] }) {
- $ajax .= $item->show_javascript();
- }
+ </script>|;
+ }
- print $self->create_http_response('content_type' => 'text/html',
- 'charset' => $db_charset,);
- print qq|${doctype}<html>
-<head>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=${db_charset}">
+ # output
+ print $self->create_http_response(content_type => 'text/html', charset => $db_charset);
+ print "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n"
+ if $ENV{'HTTP_USER_AGENT'} =~ m/MSIE\s+\d/; # Other browsers may choke on menu scripts with DOCTYPE.
+ print <<EOT;
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=$db_charset">
<title>$self->{titlebar}</title>
- $stylesheet
- $pagelayout
- $favicon
- $jsscript
- $ajax
- $fokus
- $title_hack
-
+EOT
+ print " $_\n" for @header;
+ print <<EOT;
<link rel="stylesheet" href="css/jquery.autocomplete.css" type="text/css" />
-
<meta name="robots" content="noindex,nofollow" />
-
+ <script type="text/javascript" src="js/highlight_input.js"></script>
<link rel="stylesheet" type="text/css" href="css/tabcontent.css" />
<script type="text/javascript" src="js/tabcontent.js">
***********************************************/
</script>
-
$extra_code
-</head>
+ $title_hack
+ </head>
-|;
- }
- $self->{header} = 1;
+EOT
- $main::lxdebug->leave_sub();
+ $::lxdebug->leave_sub;
}
sub ajax_response_header {
=head1 SPECIAL FUNCTIONS
-=over 4
-
-=item _store_value()
+=head2 C<_store_value()>
parses a complex var name, and stores it in the form.
filter.status[] => $form->{status}->[ val1, val2, ... ]
-=item update_business PARAMS
+=head2 C<update_business> PARAMS
PARAMS (not named):
\%config, - config hashref
special behaviour for empty strings in customerinitnumber field:
will in this case not increase the value, and return undef.
-=item redirect_header $url
+=head2 C<redirect_header> $url
Generates a HTTP redirection header for the new C<$url>. Constructs an
absolute URL including scheme, host name and port. If C<$url> is a
print $::form->redirect_header('oe.pl?action=edit&id=1234');
print $::form->redirect_header('http://www.lx-office.org/');
+=head2 C<header>
+
+Generates a general purpose http/html header and includes most of the scripts
+ans stylesheets needed.
+
+Only one header will be generated. If the method was already called in this
+request it will not output anything and return undef. Also if no
+HTTP_USER_AGENT is found, no header is generated.
+
+Although header does not accept parameters itself, it will honor special
+hashkeys of its Form instance:
+
+=over 4
+
+=item refresh_time
+
+=item refresh_url
+
+If one of these is set, a http-equiv refresh is generated. Missing parameters
+default to 3 seconds and the refering url.
+
+=item stylesheet
+
+=item stylesheets
+
+If these are arrayrefs the contents will be inlined into the header.
+
+=item landscape
+
+If true, a css snippet will be generated that sets the page in landscape mode.
+
+=item favicon
+
+Used to override the default favicon.
+
+=item title
+
+A html page title will be generated from this
+
=back
=cut
$form->isblank('name', $locale->text('The group name is missing.'));
my $groups = $main::auth->read_groups();
+ my %users = map { ( $_->{id} => 1 ) } values %{ { $::auth->read_all_users() } };
foreach my $group (values %{$groups}) {
if (($form->{group_id} != $group->{id})
$group->{name} = $form->{name};
$group->{description} = $form->{description};
- $group->{rights} = {};
-
- map { $group->{rights}->{$_} = $form->{"${_}_granted"} ? 1 : 0 } SL::Auth::all_rights();
+ $group->{rights} = { map { ( $_ => $form->{"${_}_granted"} ? 1 : 0 ) } SL::Auth::all_rights() };
+ $group->{members} = [ grep { $users{$_} } @{ $form->{user_ids} || [] } ];
my $is_new = !$form->{group_id};
$form->show_generic_error($locale->text("No group has been selected, or the group does not exist anymore."));
}
- my $group = $groups->{$form->{group_id}};
-
- my %all_users = $main::auth->read_all_users();
- my %users_by_id = map { $_->{id} => $_ } values %all_users;
-
- my @members = uniq sort { lc $a->{login} cmp lc $b->{login} } @users_by_id{ @{ $group->{members} } };
-
- my %grouped = map { $_ => 1 } uniq @{ $group->{members} };
- my @non_members = sort { lc $a->{login} cmp lc $b->{login} } grep { !$grouped{$_->{id}} } values %all_users;
-
- my @rights = map {
+ my $group = $groups->{$form->{group_id}};
+ my %all_users = $main::auth->read_all_users();
+ my @rights = map {
{ "right" => $_->[0],
"description" => $_->[1],
"is_section" => '--' eq substr($_->[0], 0, 2),
} SL::Auth::all_rights_full();
$form->header();
- print $form->parse_html_template("admin/edit_group", { "USERS_IN_GROUP" => \@members,
- "USERS_NOT_IN_GROUP" => \@non_members,
+ print $form->parse_html_template("admin/edit_group", { ALL_USERS => [ values %all_users ],
+ USER_IDS_IN_GROUP => $group->{members},
"RIGHTS" => \@rights,
"name" => $group->{name},
"description" => $group->{description} });
$main::lxdebug->leave_sub();
}
-sub add_to_group {
- $main::lxdebug->enter_sub();
-
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->isblank('user_id_not_in_group', $locale->text('No user has been selected.'));
-
- my $groups = $main::auth->read_groups();
-
- if (!$form->{group_id} || !$groups->{$form->{group_id}}) {
- $form->show_generic_error($locale->text('No group has been selected, or the group does not exist anymore.'));
- }
-
- my $group = $groups->{$form->{group_id}};
- $group->{members} = [ uniq @{ $group->{members} }, $form->{user_id_not_in_group} ];
-
- $main::auth->save_group($group);
-
- $form->{message} = $locale->text('The user has been added to this group.');
- edit_group();
-
- $main::lxdebug->leave_sub();
-}
-
-sub remove_from_group {
- $main::lxdebug->enter_sub();
-
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->isblank('user_id_in_group', $locale->text('No user has been selected.'));
-
- my $groups = $main::auth->read_groups();
-
- if (!$form->{group_id} || !$groups->{$form->{group_id}}) {
- $form->show_generic_error($locale->text('No group has been selected, or the group does not exist anymore.'));
- }
-
- my $group = $groups->{$form->{group_id}};
- $group->{members} = [ uniq grep { $_ ne $form->{user_id_in_group} } @{ $group->{members} } ];
-
- $main::auth->save_group($group);
-
- $form->{message} = $locale->text('The user has been removed from this group.');
- edit_group();
-
- $main::lxdebug->leave_sub();
-}
-
sub edit_group_membership {
$main::lxdebug->enter_sub();
'All of the exports you have selected were already closed.' => 'Alle von Ihnen ausgewählten Exporte sind bereits abgeschlossen.',
'All reports' => 'Alle Berichte (Kontenübersicht, Summen- u. Saldenliste, GuV, BWA, Bilanz, Projektbuchungen)',
'All the selected exports have already been closed, or all of their items have already been executed.' => 'Alle ausgewählten Exporte sind als abgeschlossen markiert, oder für alle Einträge wurden bereits Zahlungen verbucht.',
+ 'All users' => 'Alle BenutzerInnen',
'Allow access' => 'Zugriff erlauben',
'Allow the following users access to my follow-ups:' => 'Erlaube den folgenden Benutzern Zugriff auf meine Wiedervorlagen:',
'Alternatively you can create a new part which will then be selected.' => 'Sie können auch einen neuen Artikel anlegen, der dann automatisch ausgewählt wird.',
'Edit group ' => 'Gruppe bearbeiten',
'Edit group membership' => 'Gruppenmitgliedschaften bearbeiten',
'Edit groups' => 'Gruppen bearbeiten',
+ 'Edit membership' => 'Mitgliedschaft bearbeiten',
'Edit note' => 'Notiz bearbeiten',
'Edit rights' => 'Rechte bearbeiten',
'Edit templates' => 'Vorlagen bearbeiten',
'No transaction selected!' => 'Keine Transaktion ausgewählt',
'No transfers were executed in this export.' => 'In diesem SEPA-Export wurden keine Überweisungen ausgeführt.',
'No unknown units where found.' => 'Es wurden keine unbekannten Einheiten gefunden.',
- 'No user has been selected.' => 'Es wurde kein Benutzer ausgewählt.',
'No valid number entered for pricegroup "#1".' => 'Für Preisgruppe "#1" wurde keine gültige Nummer eingegeben.',
'No vendor has been selected yet.' => 'Es wurde noch kein Lieferant ausgewählt.',
'No warehouse has been created yet or the quantity of the bins is not configured yet.' => 'Es wurde noch kein Lager angelegt, bzw. die dazugehörigen Lagerplätze sind noch nicht konfiguriert.',
'Remove' => 'Entfernen',
'Remove Draft' => 'Entwurf löschen',
'Remove draft when posting' => 'Entwurf beim Buchen löschen',
- 'Remove from group' => 'Aus Gruppe entfernen',
'Removed spoolfiles!' => 'Druckdateien entfernt!',
'Removing marked entries from queue ...' => 'Markierte Einträge werden von der Warteschlange entfernt ...',
'Rename the group' => 'Gruppe umbenennen',
'The unit in row %d has been deleted in the meantime.' => 'Die Einheit in Zeile %d ist in der Zwischentzeit gelöscht worden.',
'The unit in row %d has been used in the meantime and cannot be changed anymore.' => 'Die Einheit in Zeile %d wurde in der Zwischenzeit benutzt und kann nicht mehr geändert werden.',
'The units have been saved.' => 'Die Einheiten wurden gespeichert.',
- 'The user has been added to this group.' => 'Der Benutzer wurde der Gruppe hinzugefügt.',
- 'The user has been removed from this group.' => 'Der Benutzer wurde aus der Gruppe entfernt.',
'The user is a member in the following group(s):' => 'Der Benutzer ist Mitglied in den folgenden Gruppen:',
'The user migration process is complete.' => 'Der Prozess der Benutzerdatenmigration ist abgeschlossen.',
'The variable name must only consist of letters, numbers and underscores. It must begin with a letter. Example: send_christmas_present' => 'Der Variablenname darf nur aus Zeichen (keine Umlaute), Ziffern und Unterstrichen bestehen. Er muss mit einem Buchstaben beginnen. Beispiel: weihnachtsgruss_verschicken',
'User name' => 'Benutzername',
'User saved!' => 'Benutzer gespeichert!',
'Username' => 'Benutzername',
+ 'Users in this group' => 'BenutzerInnen in dieser Gruppe',
'Ust-IDNr' => 'USt-IdNr.',
'Valid from' => 'Gültig ab',
'Valid until' => 'gültig bis',
-[%- USE T8 %]
-[% USE HTML %]<body>
- <form name="Form" method="post" action="admin.pl">
-
- <input type="hidden" name="group_id" value="[% HTML.escape(group_id) %]">
- <input type="hidden" name="back_nextsub" value="edit_groups">
+[% USE T8 %][% USE HTML %][% USE L %][% USE LxERP -%]
+<body>
+ [% L.stylesheet_tag('jquery.multiselect2side') %]
+ [% L.javascript_tag('jquery.selectboxes', 'jquery.multiselect2side') %]
+ <form name="Form" method="post" action="admin.pl">
[% IF message %]
<p class="message_ok">[% message %]</p>
[% END %]
<hr>
- <p class="listheading">[% 'Rename the group' | $T8 %]</p>
- <table>
- <tr><td><div style="">[% 'Name' | $T8 %]</th><td><input name="name" maxlength="50" value="[% HTML.escape(name) %]"></td></tr>
- <tr><th>[% 'Description' | $T8 %]</th><td><input name="description" value="[% HTML.escape(description) %]"></td></tr>
- </table>
- <br>
- <input type="hidden" name="save_nextsub" value="save_group">
- <input type="submit" class="submit" name="action" value="[% 'Save' | $T8 %]">
-
- <hr>
- <br>
- <div class="listtop">[% 'Group membership' | $T8 %]</div>
- <table>
- <tr>
- <td><p class="listheading">[% 'Members of' | $T8 %]<br>[% HTML.escape(name) %]</p></td>
- <td> </td>
- <td><p class="listheading">[% 'Members not of' | $T8 %]<br>[% HTML.escape(name) %]</p></td>
- </tr>
-
- <tr>
- <td valign="center">
- <select name="user_id_in_group" size="10">
- [% FOREACH user = USERS_IN_GROUP %]<option value="[% HTML.escape(user.id) %]">[% HTML.escape(user.login) %]</option>[% END %]
- </select>
- </td>
-
- <td valign="center">
- <input type="submit" class="submit" name="action" value="[% 'Add to group' | $T8 %]">
- <br>
- <br>
- <input type="submit" class="submit" name="action" value="[% 'Remove from group' | $T8 %]">
- </td>
-
- <td valign="center">
- <select name="user_id_not_in_group" size="10">
- [% FOREACH user = USERS_NOT_IN_GROUP %]<option value="[% HTML.escape(user.id) %]">[% HTML.escape(user.login) %]</option>[% END %]
- </select>
- </td>
- </tr>
- </table>
- <hr>
- <br>
- <div class="listtop">[% 'Edit rights' | $T8 %]</div>
-
- [% FOREACH right = RIGHTS %]
-
- [% IF right.is_section %]
- <br>
- <h4 style="border-bottom: solid; border-bottom-width: 1px; border-bottom-color: #ddd;">[% right.description %]</h4>
- [% ELSE %]
- <p style="/*font-size: 11px;*/ margin: 0;">
- <input type="checkbox" name="[% HTML.escape(right.right) %]_granted" id="[% HTML.escape(right.right) %]_granted" [% IF right.granted %]checked[% END %]>
- <label for="[% HTML.escape(right.right) %]_granted">[% IF right.description %][% right.description %][% ELSE %]<i>[% HTML.escape(right.right) %]</i>[% END %]</label>
- </p>
- [% END %]
-
- [% END %]
-
- <hr>
- <input type="hidden" name="save_nextsub" value="save_group">
- <input type="submit" class="submit" name="action" value="[% 'Back' | $T8 %]">
- <input type="submit" class="submit" name="action" value="[% 'Save' | $T8 %]">
+ <h3 class="listheading">[%- LxERP.t8('Edit membership') %]</h3>
+
+ <div class="clearfix">
+ [% L.select_tag("user_ids[]", L.options_for_select(ALL_USERS, value => 'id', title => 'login', default => USER_IDS_IN_GROUP), 'multiple' => 'multiple') %]
+ </div>
+
+ <h3 class="listheading">[% 'Edit rights' | $T8 %]</h3>
+
+ <p>
+ [% FOREACH right = RIGHTS %]
+ [% IF right.is_section %]
+ <i>[% right.description %]</i><br>
+ [% ELSE %]
+ <input type="checkbox" name="[% HTML.escape(right.right) %]_granted" id="[% HTML.escape(right.right) %]_granted" [% IF right.granted %]checked[% END %]>
+ <label for="[% HTML.escape(right.right) %]_granted">[% IF right.description %][% right.description %][% ELSE %]<i>[% HTML.escape(right.right) %]</i>[% END %]</label>
+ <br>
+ [% END %]
+ [% END %]
+ </p>
+
+ <h3 class="listheading">[% LxERP.t8('Rename the group') %]</h3>
+
+ <table>
+ <tr>
+ <td>[% 'Name' | $T8 %]:</td>
+ <td><input name="name" maxlength="50" value="[% HTML.escape(name) %]"></td>
+ </tr>
+
+ <tr>
+ <td>[% 'Description' | $T8 %]:</td>
+ <td><input name="description" value="[% HTML.escape(description) %]"></td>
+ </tr>
+ </table>
+
+ <p>
+ <input type="hidden" name="group_id" value="[% HTML.escape(group_id) %]">
+ <input type="hidden" name="action" value="save_group">
+ <input type="submit" class="submit" value="[% 'Save' | $T8 %]">
+
+ <a href="admin.pl?action=edit_groups">[% 'Back' | $T8 %]</a>
+ </p>
</form>
+
+ [% L.multiselect2side('user_ids_', labelsx => LxERP.t8('All users'), labeldx => LxERP.t8('Users in this group')) %]
</body>
</html>