From 2c757d7db4cb6a7b9655de13206fcc84fb7ce61f Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 14 May 2006 16:47:31 +0000 Subject: first part of ACL and re-skinning work and some other small stuff --- httemplate/elements/checkboxes-table.html | 110 ++++ httemplate/elements/cssexpr.js | 66 +++ httemplate/elements/footer.html | 3 + httemplate/elements/header.html | 289 +++++++++- httemplate/elements/menubar.html | 1 + httemplate/elements/select-access_group.html | 15 + httemplate/elements/tr-select-access_group.html | 22 + httemplate/elements/xmenu.css | 185 +++++++ httemplate/elements/xmenu.js | 668 ++++++++++++++++++++++++ 9 files changed, 1347 insertions(+), 12 deletions(-) create mode 100644 httemplate/elements/checkboxes-table.html create mode 100644 httemplate/elements/cssexpr.js create mode 100644 httemplate/elements/select-access_group.html create mode 100644 httemplate/elements/tr-select-access_group.html create mode 100644 httemplate/elements/xmenu.css create mode 100644 httemplate/elements/xmenu.js (limited to 'httemplate/elements') diff --git a/httemplate/elements/checkboxes-table.html b/httemplate/elements/checkboxes-table.html new file mode 100644 index 000000000..d26ebef35 --- /dev/null +++ b/httemplate/elements/checkboxes-table.html @@ -0,0 +1,110 @@ +<% + + ## + # required + ## + # 'target_table' => 'table_name', + # 'link_table' => 'table_name', + # + # 'name_col' => 'name_column', + # #or + # 'name_callback' => sub { }, + # + ## + # recommended (required?) + ## + # 'source_obj' => $obj, + # #or? + # #'source_table' => 'table_name', + # #'sourcenum' => '4', #current value of primary key in source_table + # # # (none is okay, just pass it if you have it) + ## + # optional + ## + # 'disable-able' => 1, + + my( %opt ) = @_; + + my $target_pkey = dbdef->table($opt{'target_table'})->primary_key; + + my( $source_pkey, $sourcenum, $source_obj ); + if ( $opt{'source_obj'} ) { + + $source_obj = $opt{'source_obj'}; + #$source_table = $source_obj->dbdef_table->table; + $source_pkey = $source_obj->dbdef_table->primary_key; + $sourcenum = $source_obj->$source_pkey(); + + } else { + + #$source_obj? + $source_pkey = $opt{'source_table'} + ? dbdef->table($opt{'source_table'})->primary_key + : ''; + $sourcenum = $opt{'sourcenum'}; + } + + my $hashref = $opt{'hashref'} || {}; + + my $extra_sql = ''; + + if ( $opt{'disable-able'} ) { + $hashref->{'disabled'} = ''; + + $extra_sql .= ( $sourcenum && $source_pkey ) + ? "OR $source_pkey = $sourcenum" + : ''; + } + +%> + +<% foreach my $target_obj ( + qsearch({ 'table' => $opt{'target_table'}, + 'hashref' => $hashref, + 'select' => $opt{'target_table'}. '.*', + 'addl_from' => "LEFT JOIN $opt{'link_table'} USING ( $target_pkey )", + 'extra_sql' => $extra_sql, + }) + ) { + + my $targetnum = $target_obj->$target_pkey(); +%> + + $sourcenum, + $target_pkey => $targetnum, + }) + ? 'CHECKED ' + : '' + %> VALUE="ON"> + + <% if ( $opt{'target_link'} ) { %> + + <% + + } + %><%= $targetnum %>: + + <% if ( $opt{'name_callback'} ) { %> + + <%= &{ $opt{'name_callback'} }( $target_obj ) %><%= $opt{'target_link'} ? '' : '' %> + + <% } else { + my $name_col = $opt{'name_col'}; + %> + + <%= $target_obj->$name_col() %><%= $opt{'target_link'} ? '' : '' %> + + <% } %> + + <% if ( $opt{'disable-able'} ) { %> + + <%= $target_obj->disabled =~ /^Y/i ? ' (DISABLED)' : '' %> + + <% } %> + +
+ +<% } %> + diff --git a/httemplate/elements/cssexpr.js b/httemplate/elements/cssexpr.js new file mode 100644 index 000000000..c434d8da0 --- /dev/null +++ b/httemplate/elements/cssexpr.js @@ -0,0 +1,66 @@ +function constExpression(x) { + return x; +} + +function simplifyCSSExpression() { + try { + var ss,sl, rs, rl; + ss = document.styleSheets; + sl = ss.length + + for (var i = 0; i < sl; i++) { + simplifyCSSBlock(ss[i]); + } + } + catch (exc) { + //alert("Got an error while processing css. The page should still work but might be a bit slower"); + throw exc; + } +} + +function simplifyCSSBlock(ss) { + var rs, rl; + + for (var i = 0; i < ss.imports.length; i++) + simplifyCSSBlock(ss.imports[i]); + + if (ss.cssText.indexOf("expression(constExpression(") == -1) + return; + + rs = ss.rules; + rl = rs.length; + for (var j = 0; j < rl; j++) + simplifyCSSRule(rs[j]); + +} + +function simplifyCSSRule(r) { + var str = r.style.cssText; + var str2 = str; + var lastStr; + do { + lastStr = str2; + str2 = simplifyCSSRuleHelper(lastStr); + } while (str2 != lastStr) + + if (str2 != str) + r.style.cssText = str2; +} + +function simplifyCSSRuleHelper(str) { + var i, i2; + i = str.indexOf("expression(constExpression("); + if (i == -1) return str; + i2 = str.indexOf("))", i); + var hd = str.substring(0, i); + var tl = str.substring(i2 + 2); + var exp = str.substring(i + 27, i2); + var val = eval(exp) + return hd + val + tl; +} + +if (/msie/i.test(navigator.userAgent) && window.attachEvent != null) { + window.attachEvent("onload", function () { + simplifyCSSExpression(); + }); +} diff --git a/httemplate/elements/footer.html b/httemplate/elements/footer.html index 6029d7637..32d121996 100644 --- a/httemplate/elements/footer.html +++ b/httemplate/elements/footer.html @@ -1,2 +1,5 @@ + + + diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html index 10e4e40f1..49814577e 100644 --- a/httemplate/elements/header.html +++ b/httemplate/elements/header.html @@ -2,20 +2,285 @@ my($title, $menubar) = ( shift, shift ); my $etc = @_ ? shift : ''; #$etc is for things like onLoad= etc. my $head = @_ ? shift : ''; #$head is for things that go in the section + my $conf = new FS::Conf; %> - - - - <%= $title %> - - - - - <%= $head %> - - > + + + + + <%= $title %> + + + + + + + + <% + + tie my %report_menu, 'Tie::IxHash', + 'Report one' => [ 'there', 'theretip' ], + 'Report too' => [ 'here', 'heretip' ], + ; + + tie my %config_employees, 'Tie::IxHash', + 'View/Edit employees' => [ $fsurl.'browse/access_user.html', 'Setup internal users' ], + 'View/Edit employee groups' => [ $fsurl.'browse/access_group.html', 'Employee groups allow you to control access to the backend' ], + ; + + tie my %config_export_svc_pkg, 'Tie::IxHash', + 'View/Edit exports' => [ $fsurl.'browse/part_export.cgi', 'Provisioning services to external machines, databases and APIs' ], + 'View/Edit service definitions' => [ $fsurl.'browse/part_svc.cgi', 'Services are items you offer to your customers' ], + 'View/Edit package definitions' => [ $fsurl.'browse/part_pkg.cgi', 'One or more services are grouped together into a package and given pricing information. Customers purchase packages, not services' ], + 'View/Edit package classes' => [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for reporting and convenience purposes.' ], + ; + + tie my %config_agent, 'Tie::IxHash', + 'View/Edit agent types' => [ $fsurl.'browse/agent_type.cgi', 'Agent types define groups of package definitions that you can then assign to particular agents' ], + 'View/Edit agents' => [ $fsurl.'browse/agent.cgi', 'Agents are resellers of your service. Agents may be limited to a subset of your full offerings (via their type)' ], + ; + + tie my %config_billing, 'Tie::IxHash', + 'View/Edit payment gateways' => [ $fsurl.'browse/payment_gateway.html', 'Credit card and electronic check processors' ], + 'View/Edit invoice events' => [ $fsurl.'browse/part_bill_event.cgi', 'Actions for overdue invoices' ], + 'View/Edit prepaid cards' => [ $fsurl.'browse/prepay_credit.html', 'View outstanding cards, generate new cards' ], + 'View/Edit call rates and regions' => [ $fsurl.'browse/rate.cgi', 'Manage rate plans, regions and prefixes for VoIP and call billing' ], + 'View/Edit locales and tax rates' => [ $fsurl.'browse/cust_main_county.cgi', 'Change tax rates, or break down a country into states, or a state into counties and assign different tax rates to each' ], + ; + + tie my %config_dialup, 'Tie::IxHash', + 'View/Edit access numbers' => [ $fsurl.'browse/svc_acct_pop.cgi', 'Points of Presence' ], + ; + + tie my %config_broadband, 'Tie::IxHash', + 'View/Edit routers' => [ $fsurl.'browse/router.cgi', 'Broadband access routers' ], + 'View/Edit address blocks' => [ $fsurl.'browse/addr_block.cgi', 'Manage address blocks and block assignments to broadband routers' ], + ; + + tie my %config_misc, 'Tie::IxHash', + 'View/Edit advertising sources' => [ $fsurl.'browse/part_referral.cgi', 'Where a customer heard about your service. Tracked for informational purposes' ], + 'View/Edit virtual fields' => [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ], + 'View/Edit message catalog' => [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ], + 'View/Edit inventory classes and inventory' => [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ], + ; + + tie my %config_menu, 'Tie::IxHash', + 'Settings' => [ $fsurl.'config/config-view.cgi', 'XXXconfigittip' ], + 'separator' => '', #its a separator! + 'Employees' => [ \%config_employees, 'XXXtooltip' ], + 'Provisioning, services and packages' + => [ \%config_export_svc_pkg, 'XXXtootip' ], + 'Resellers' => [ \%config_agent, 'XXXtootip' ], + 'Billing' => [ \%config_billing, 'XXXtootip' ], + 'Dialup' => [ \%config_dialup, 'XXXtootip' ], + 'Fixed (username-less) broadband' + => [ \%config_broadband, 'XXXtootip' ], + 'Miscellaneous' => [ \%config_misc, 'XXXtootip' ], + ; + + tie my %menu, 'Tie::IxHash', + 'Home' => [ $fsurl, 'hometip', ], + 'Top item one' => [ 'nowhere_yet', 'nowheretip', ], + 'Top item too' => [ 'nowhere_yet_either', 'eithertip', ], + 'Reports' => [ \%report_menu, 'reportmenutip' ], + 'Configuration' => [ \%config_menu, 'configmenutip' ], + ; + + use vars qw($gmenunum); + $gmenunum = 0; + + sub submenu { + my($submenu, $title) = @_; + my $menunum = $gmenunum++; + + #return two args: html, menuname + + "var myMenu$menunum = new WebFXMenu;\n". + #"myMenu$menunum.useAutoPosition = true;\n". + "myMenu$menunum.emptyText = '$title';\n". + + ( + join("\n", map { + + if ( !ref( $submenu->{$_} ) ) { + + "myMenu$menunum.add(new WebFXMenuSeparator());"; + + } else { + + my($url_or_submenu, $tooltip ) = @{ $submenu->{$_} }; + if ( ref($url_or_submenu) ) { + + my($subhtml, $submenuname ) = submenu($url_or_submenu, $_); #mmm, recursion + + "$subhtml\n". + "myMenu$menunum.add(new WebFXMenuItem(\"$_\", null, \"$tooltip\", $submenuname ));"; + + } else { + + "myMenu$menunum.add(new WebFXMenuItem(\"$_\", \"$url_or_submenu\", \"$tooltip\" ));"; + + } + + } + + } keys %$submenu ) + ). "\n". + "myMenu$menunum.width = 224\n", + + "myMenu$menunum"; + + } + + %> + + + + + <%= $head %> + + + STYLE="margin-top:0; margin-bottom:0; margin-left:0; margin-right:0"> + + + + + + + + + +
+ freeside + + <%= $conf->config('company_name') %> Billing + Logged in as <%= getotaker %> 
Preferences 

+
+ + + + + <% if ( $conf->config('ticket_system') eq 'RT_Internal' ) { %> + <% eval "use RT;"; %> + + + <% } %> + + +
+ + Freeside v<%= $FS::VERSION %>
+ Documentation
+
+
+ + RT v<%= $RT::VERSION %>
+
Documentation
+
+
+ +
+ + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+
+ + +
+
+ + + + + + + + + + + + + + +<% } %> diff --git a/httemplate/elements/xmenu.css b/httemplate/elements/xmenu.css new file mode 100644 index 000000000..5bb8a0deb --- /dev/null +++ b/httemplate/elements/xmenu.css @@ -0,0 +1,185 @@ + +.webfx-menu, .webfx-menu * { + /* + Set the box sizing to content box + in the future when IE6 supports box-sizing + there will be an issue to fix the sizes + + There is probably an issue with IE5 mac now + because IE5 uses content-box but the script + assumes all versions of IE uses border-box. + + At the time of this writing mozilla did not support + box-sizing for absolute positioned element. + + Opera only supports content-box + */ + box-sizing: content-box; + -moz-box-sizing: content-box; +} + +.webfx-menu { + position: absolute; + z-index: 100; + visibility: hidden; + width: 154px; + border: 1px solid black; + padding: 1px; + background: white; + filter: progid:DXImageTransform.Microsoft.Shadow(color="#777777", Direction=135, Strength=4) + alpha(Opacity=95); + -moz-opacity: 0.95; + /* a drop shadow would be nice in moz/others too... */ +} + +.webfx-menu-empty { + display: block; + border: 1px solid white; + padding: 2px 5px 2px 5px; + font-size: 11px; + /* font-family: Tahoma, Verdan, Helvetica, Sans-Serif; */ + color: black; +} + +.webfx-menu a { + display: block; + width: expression(constExpression(ieBox ? "100%": "auto")); /* should be ignored by mz and op */ + height: expression(constExpression("1px")); + overflow: visible; + padding: 2px 0px 2px 5px; + font-size: 11px; + font-family: Tahoma, Verdan, Helvetica, Sans-Serif; + text-decoration: none; + vertical-align: center; + color: black; + border: 1px solid white; +} + +.webfx-menu a:visited, +.webfx-menu a:visited:hover { + color: black; +} + +.webfx-menu a:hover { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + /* background: #ffe6fe; */ + /* background: #ffc2fe; */ + background: #fff2fe; + border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ +} + +.webfx-menu a .arrow { + float: right; + border: 0; + width: 3px; + margin-right: 3px; + margin-top: 4px; +} + +/* separtor */ +.webfx-menu div { + height: 0; + height: expression(constExpression(ieBox ? "2px" : "0")); + border-top: 1px solid #7e0079; /* rgb(120,172,255); */ + border-bottom: 1px solid rgb(234,242,255); + overflow: hidden; + margin: 2px 0px 2px 0px; + font-size: 0mm; +} + +.webfx-menu-bar { + /* i want a vertical bar */ + display: block; + + /* background: rgb(120,172,255);/*rgb(255,128,0);*/ + /* background: #a097ed; */ + background: #000000; + /* border: 1px solid #7E0079; */ + /* border: 1px solid #000000; */ + /* border: none */ + + padding: 2px; + + font-family: Verdana, Helvetica, Sans-Serif; + font-size: 11px; + + /* IE5.0 has the wierdest box model for inline elements */ + padding: expression(constExpression(ie50 ? "0px" : "2px")); +} + +.webfx-menu-bar a, +.webfx-menu-bar a:visited { + /* i want a vertical bar */ + display: block; + + /* border: 1px solid black; /*rgb(0,0,0);/*rgb(255,128,0);*/ + /* border: 1px solid black; /* #ffffff; */ + /* border-bottom: 1px solid black; */ + border-bottom: 1px solid white; + /* border-bottom: 1px solid rgb(0,66,174); + /* border-bottom: 1px solid black; + border-bottom: 1px solid black; + border-bottom: 1px solid black; */ + + padding: 1px 5px 1px 5px; + + /* color: black; */ + color: white; + text-decoration: none; + + /* IE5.0 Does not paint borders and padding on inline elements without a height/width */ + height: expression(constExpression(ie50 ? "17px" : "auto")); +} + +.webfx-menu-bar a:hover { + /* color: black; */ + color: white; + /* background: rgb(120,172,255); */ + /* background: #BC79B8; */ + background: #7E0079; + /* border-left: 1px solid rgb(234,242,255); + border-right: 1px solid rgb(0,66,174); + border-top: 1px solid rgb(234,242,255); + border-bottom: 1px solid rgb(0,66,174); */ +} + +.webfx-menu-bar a .arrow { + border: 0; + float: right; +/* vertical-align: top; */ + width: 3px; + margin-right: 3px; + margin-top: 4px; +} + +.webfx-menu-bar a:active, .webfx-menu-bar a:focus { + -moz-outline: none; + outline: none; + /* + ie does not support outline but ie55 can hide the outline using + a proprietary property on HTMLElement. Did I say that IE sucks at CSS? + */ + ie-dummy: expression(this.hideFocus=true); + + border-left: 1px solid rgb(0,66,174); + border-right: 1px solid rgb(234,242,255); + border-top: 1px solid rgb(0,66,174); + border-bottom: 1px solid rgb(234,242,255); +} + +.webfx-menu-title { + color: black; + /* background: #faf7fa; #f5ebf4; #efdfef; white; #BC79B8; */ + background: #7e0079; +/* border: 1px solid #7e0079; /*rgb(120,172,255);#ff8800;*/ + padding: 3px 1px 3px 6px; + display: block; + font-size: 13px; + font-family: Tahoma, Verdan, Helvetica, Sans-Serif; + text-decoration: none; + color: white; +/* border: 1px solid white; */ + border-bottom: 1px solid white; +} + diff --git a/httemplate/elements/xmenu.js b/httemplate/elements/xmenu.js new file mode 100644 index 000000000..134265f53 --- /dev/null +++ b/httemplate/elements/xmenu.js @@ -0,0 +1,668 @@ +//
+ +
+ + +
+ <%= $title %> +

- <%= $menubar ? "$menubar

" : '' %> + <%= $menubar !~ /^\s*$/ ? "$menubar

" : '' %> diff --git a/httemplate/elements/menubar.html b/httemplate/elements/menubar.html index 87a50312c..29facb6b6 100644 --- a/httemplate/elements/menubar.html +++ b/httemplate/elements/menubar.html @@ -2,6 +2,7 @@ my($item, $url, @html); while (@_) { ($item, $url) = splice(@_,0,2); + next if $item =~ /^\s*Main\s+Menu\s*$/i; push @html, qq!$item!; } %> diff --git a/httemplate/elements/select-access_group.html b/httemplate/elements/select-access_group.html new file mode 100644 index 000000000..b05f565ea --- /dev/null +++ b/httemplate/elements/select-access_group.html @@ -0,0 +1,15 @@ +<% + my( $groupnum, %opt ) = @_; + + %opt{'records'} = delete $opt{'access_group'} + if $opt{'access_group'}; + +%><%= include( '/elements/select-table.html', + 'table' => 'access_group', + 'name_col' => 'groupname', + 'value' => $groupnum, + 'empty_label' => '(none)', + #'hashref' => { 'disabled' => '' }, + %opt, + ) +%> diff --git a/httemplate/elements/tr-select-access_group.html b/httemplate/elements/tr-select-access_group.html new file mode 100644 index 000000000..0beec0842 --- /dev/null +++ b/httemplate/elements/tr-select-access_group.html @@ -0,0 +1,22 @@ +<% + my( $groupnum, %opt ) = @_; + + $opt{'access_group'} ||= [ qsearch( 'access_group', {} ) ]; # { disabled=>'' } ) + + #warn "***** tr-select-access_group: \n". Dumper(%opt); +%> + +<% if ( scalar(@{ $opt{'access_group'} }) == 0 ) { %> + + + +<% } else { %> + +
<%= $opt{'label'} || 'Access group' %> + <%= include( '/elements/select-access_group.html', $groupnum, %opt ) %> +