summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wells <mark@freeside.biz>2016-04-05 12:51:49 -0700
committerMark Wells <mark@freeside.biz>2016-04-05 13:06:36 -0700
commit06809c379e25e6753d39ca79a39c977e5194c696 (patch)
tree939e5eacd056b404aefc637fbf23e4a3ae6b305d
parent4b39a40f110de90403417bc75a40f35a2861126c (diff)
persistent user prefs for UI pages, #41397
-rw-r--r--FS/FS/Mason.pm4
-rw-r--r--FS/FS/Schema.pm20
-rw-r--r--FS/FS/UI/Web.pm72
-rw-r--r--FS/FS/access_user.pm72
-rw-r--r--FS/FS/access_user_page_pref.pm128
-rw-r--r--FS/MANIFEST2
-rw-r--r--FS/t/access_user_page_pref.t5
-rw-r--r--httemplate/elements/header.html8
-rw-r--r--httemplate/elements/page_pref.js10
-rw-r--r--httemplate/misc/process/set_page_pref.html12
10 files changed, 331 insertions, 2 deletions
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 4d01d7c9e..651cc95a4 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -136,7 +136,8 @@ if ( -e $addl_handler_use_file ) {
use FS::Conf;
use FS::CGI qw(header menubar table itable ntable idiot
eidiot myexit http_header);
- use FS::UI::Web qw(svc_url random_id);
+ use FS::UI::Web qw(svc_url random_id
+ get_page_pref set_page_pref);
use FS::UI::Web::small_custview qw(small_custview);
use FS::UI::bytecount;
use FS::Msgcat qw(gettext geterror);
@@ -389,6 +390,7 @@ if ( -e $addl_handler_use_file ) {
use FS::svc_fiber;
use FS::fiber_olt;
use FS::olt_site;
+ use FS::access_user_page_pref;
# Sammath Naur
if ( $FS::Mason::addl_handler_use ) {
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index a7dcc40b5..316ec4843 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -4093,6 +4093,26 @@ sub tables_hashref {
'index' => [ ['usernum'], ['path'], ['_date'] ],
},
+ 'access_user_page_pref' => {
+ 'columns' => [
+ 'prefnum' => 'serial', '', '', '', '',
+ 'usernum' => 'int', '', '', '', '',
+ 'path' => 'text', '', '', '', '',
+ 'tablenum' => 'int', 'NULL', '', '', '',
+ '_date' => @date_type, '', '',
+ 'prefname' => 'varchar', '', $char_d, '', '',
+ 'prefvalue' => 'text', '', '', '', '',
+ ],
+ 'primary_key' => 'prefnum',
+ 'unique' => [ [ 'usernum', 'path', 'tablenum', 'prefname' ] ],
+ 'index' => [],
+ 'foreign_keys' => [
+ { columns => [ 'usernum' ],
+ table => 'access_user'
+ },
+ ],
+ },
+
'sched_item' => {
'columns' => [
'itemnum', 'serial', '', '', '', '',
diff --git a/FS/FS/UI/Web.pm b/FS/FS/UI/Web.pm
index bfcc1dc45..80af37990 100644
--- a/FS/FS/UI/Web.pm
+++ b/FS/FS/UI/Web.pm
@@ -15,7 +15,7 @@ use FS::cust_main; # are sql_balance and sql_date_balance in the right module?
#@ISA = qw( FS::UI );
@ISA = qw( Exporter );
-@EXPORT_OK = qw( svc_url random_id );
+@EXPORT_OK = qw( get_page_pref set_page_pref svc_url random_id );
$DEBUG = 0;
$me = '[FS::UID::Web]';
@@ -23,9 +23,79 @@ $me = '[FS::UID::Web]';
our $NO_RANDOM_IDS;
###
+# user prefs
+###
+
+=item get_page_pref NAME, TABLENUM
+
+Returns the user's page preference named NAME for the current page. If the
+page is a view or edit page or otherwise shows a single record at a time,
+it should use TABLENUM to link the preference to that record.
+
+=cut
+
+sub get_page_pref {
+ my ($prefname, $tablenum) = @_;
+
+ my $m = $HTML::Mason::Commands::m
+ or die "can't get page pref when running outside the UI";
+ # what's more useful: to tie prefs to the base_comp (usually where
+ # code is executing right now), or to the request_comp (approximately the
+ # one in the URL)? not sure.
+ $FS::CurrentUser::CurrentUser->get_page_pref( $m->request_comp->path,
+ $prefname,
+ $tablenum
+ );
+}
+
+=item set_page_pref NAME, TABLENUM, VALUE
+
+Sets the user's page preference named NAME for the current page. Use TABLENUM
+as for get_page_pref.
+
+If VALUE is an empty string, the preference will be deleted (and
+C<get_page_pref> will return an empty string).
+
+ my $mypref = set_page_pref('mypref', '', 100);
+
+=cut
+
+sub set_page_pref {
+ my ($prefname, $tablenum, $prefvalue) = @_;
+
+ my $m = $HTML::Mason::Commands::m
+ or die "can't set page pref when running outside the UI";
+ $FS::CurrentUser::CurrentUser->set_page_pref( $m->request_comp->path,
+ $prefname,
+ $tablenum,
+ $prefvalue );
+}
+
+###
# date parsing
###
+=item parse_beginning_ending CGI [, PREFIX ]
+
+Parses a beginning/ending date range, as used on many reports. This function
+recognizes two sets of CGI params: "begin" and "end", the integer timestamp
+values, and "beginning" and "ending", the user-readable date fields.
+
+If "begin" contains an integer, that's passed through as the beginning date.
+Otherwise, "beginning" is passed to L<DateTime::Format::Natural> and turned
+into an integer. If this fails or it doesn't have a value, zero is used as the
+beginning date.
+
+The same happens for "end" and "ending", except that if "ending" contains a
+date without a time, it gets moved to the end of that day, and if there's no
+value, the value returned is the highest unsigned 32-bit time value (some time
+in 2037).
+
+PREFIX is optionally a string to prepend (with '_' as a delimiter) to the form
+field names.
+
+=cut
+
use Date::Parse;
sub parse_beginning_ending {
my($cgi, $prefix) = @_;
diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm
index a3a94c475..d13549dcf 100644
--- a/FS/FS/access_user.pm
+++ b/FS/FS/access_user.pm
@@ -759,6 +759,78 @@ sub locale {
$self->{_locale} = $self->option('locale');
}
+=item get_page_pref PATH, NAME, TABLENUM
+
+Returns the user's page preference named NAME for the page at PATH. If the
+page is a view or edit page or otherwise shows a single record at a time,
+it should use TABLENUM to tell which record the preference is for.
+
+=cut
+
+sub get_page_pref {
+ my $self = shift;
+ my ($path, $prefname, $tablenum) = @_;
+ $tablenum ||= '';
+
+ my $access_user_page_pref = qsearchs('access_user_page_pref', {
+ path => $path,
+ usernum => $self->usernum,
+ tablenum => $tablenum,
+ prefname => $prefname,
+ });
+ $access_user_page_pref ? $access_user_page_pref->prefvalue : '';
+}
+
+=item set_page_pref PATH, NAME, TABLENUM, VALUE
+
+Sets the user's page preference named NAME for the page at PATH. Use TABLENUM
+as for get_page_pref.
+
+=cut
+
+sub set_page_pref {
+ my $self = shift;
+ my ($path, $prefname, $tablenum, $prefvalue) = @_;
+ $tablenum ||= '';
+
+ my $error;
+ my $access_user_page_pref = qsearchs('access_user_page_pref', {
+ path => $path,
+ usernum => $self->usernum,
+ tablenum => $tablenum,
+ prefname => $prefname,
+ });
+ if ( $access_user_page_pref ) {
+ if ( $prefvalue eq $access_user_page_pref->get('prefvalue') ) {
+ return '';
+ }
+ if ( length($prefvalue) > 0 ) {
+ $access_user_page_pref->set('prefvalue', $prefvalue);
+ $error = $access_user_page_pref->replace;
+ $error .= " (updating $prefname)" if $error;
+ } else {
+ $error = $access_user_page_pref->delete;
+ $error .= " (removing $prefname)" if $error;
+ }
+ } else {
+ if ( length($prefvalue) > 0 ) {
+ $access_user_page_pref = FS::access_user_page_pref->new({
+ path => $path,
+ usernum => $self->usernum,
+ tablenum => $tablenum,
+ prefname => $prefname,
+ prefvalue => $prefvalue,
+ });
+ $error = $access_user_page_pref->insert;
+ $error .= " (creating $prefname)" if $error;
+ } else {
+ return '';
+ }
+ }
+
+ return $error;
+}
+
=back
=head1 BUGS
diff --git a/FS/FS/access_user_page_pref.pm b/FS/FS/access_user_page_pref.pm
new file mode 100644
index 000000000..890d29f17
--- /dev/null
+++ b/FS/FS/access_user_page_pref.pm
@@ -0,0 +1,128 @@
+package FS::access_user_page_pref;
+use base qw( FS::Record );
+
+use strict;
+use FS::Record qw( qsearch qsearchs );
+
+sub table { 'access_user_page_pref'; }
+
+=head1 NAME
+
+FS::access_user_page_pref - Object methods for access_user_page_pref records
+
+=head1 SYNOPSIS
+
+ use FS::access_user_page_pref;
+
+ $record = new FS::access_user_page_pref \%hash;
+ $record = new FS::access_user_page_pref { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::access_user_page_pref object represents a per-page user interface
+preference. FS::access_user_page_pref inherits from FS::Record. The
+following fields are currently supported:
+
+=over 4
+
+=item prefnum
+
+primary key
+
+=item usernum
+
+The user who has this preference, a L<FS::access_user> foreign key.
+
+=item path
+
+The path of the page where the preference is set, relative to the Mason
+document root.
+
+=item tablenum
+
+For view and edit pages (which show one record at a time), the record primary
+key that the preference applies to.
+
+=item _date
+
+The date the preference was created.
+
+=item prefname
+
+The name of the preference, as defined by the page.
+
+=item prefvalue
+
+The value (a free-text field).
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new preference. To add the preference to the database, see
+L<"insert">.
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=item delete
+
+Delete this record from the database.
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=item check
+
+Checks all fields to make sure this is a valid preference. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ $self->set('_date', time) unless $self->get('_date');
+
+ my $error =
+ $self->ut_numbern('prefnum')
+ || $self->ut_number('usernum')
+ || $self->ut_foreign_key('usernum', 'access_user', 'usernum')
+ || $self->ut_text('path')
+ || $self->ut_numbern('tablenum')
+ || $self->ut_numbern('_date')
+ || $self->ut_text('prefname')
+ || $self->ut_text('prefvalue')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 SEE ALSO
+
+L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 0f3e49494..eafb8e059 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -806,3 +806,5 @@ FS/olt_site.pm
t/olt_site.t
FS/webservice_log.pm
t/webservice_log.t
+FS/access_user_page_pref.pm
+t/access_user_page_pref.t
diff --git a/FS/t/access_user_page_pref.t b/FS/t/access_user_page_pref.t
new file mode 100644
index 000000000..4a45b4d39
--- /dev/null
+++ b/FS/t/access_user_page_pref.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::access_user_page_pref;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/elements/header.html b/httemplate/elements/header.html
index a5dedd749..a67538d11 100644
--- a/httemplate/elements/header.html
+++ b/httemplate/elements/header.html
@@ -61,6 +61,12 @@ Example:
<% $head |n %>
+%# announce our base path, and the Mason comp path of this page
+ <script type="text/javascript">
+ window.fsurl = <% $fsurl |js_string %>;
+ window.request_comp_path = <% $m->request_comp->path |js_string %>;
+ </script>
+
</HEAD>
<BODY BGCOLOR="#f8f8f8" <% $etc |n %> STYLE="margin-top:0; margin-bottom:0; margin-left:0px; margin-right:0px">
<table width="100%" CELLPADDING=0 CELLSPACING=0 STYLE="padding-left:0px; padding-right:4px" CLASS="fshead">
@@ -184,6 +190,7 @@ Example:
% }
<% $menubar !~ /^\s*$/ ? "$menubar<BR><BR>" : '' %>
+
<%init>
my( $title, $title_noescape, $menubar, $etc, $head ) = ( '', '', '', '', '' );
@@ -231,4 +238,5 @@ if ( scalar(@agentnums) == 1 ) {
$company_name = $conf->config('company_name');
$company_url = $conf->config('company_url');
}
+
</%init>
diff --git a/httemplate/elements/page_pref.js b/httemplate/elements/page_pref.js
new file mode 100644
index 000000000..253c6da86
--- /dev/null
+++ b/httemplate/elements/page_pref.js
@@ -0,0 +1,10 @@
+function set_page_pref(prefname, tablenum, prefvalue, success) {
+ jQuery.post( window.fsurl + 'misc/process/set_page_pref.html',
+ { path: window.request_comp_path,
+ name: prefname,
+ num: tablenum,
+ value: prefvalue
+ },
+ success
+ );
+}
diff --git a/httemplate/misc/process/set_page_pref.html b/httemplate/misc/process/set_page_pref.html
new file mode 100644
index 000000000..a7f123116
--- /dev/null
+++ b/httemplate/misc/process/set_page_pref.html
@@ -0,0 +1,12 @@
+<%init>
+my $path = $cgi->param('path');
+my $name = $cgi->param('name');
+my $tablenum = $cgi->param('num') || '';
+my $value = $cgi->param('value');
+
+my $error = $FS::CurrentUser::CurrentUser->set_page_pref($path, $name, $tablenum, $value);
+my $result = { 'error' => $error }; # in case someone cares
+
+http_header('Content-Type', 'application/json');
+</%init>
+<% encode_json($result) %>