From 707215cf3f2d31faac141e2330dae37f6dcef8f8 Mon Sep 17 00:00:00 2001 From: daviddelikat Date: Fri, 6 Nov 2009 11:05:59 -0600 Subject: [PATCH] recover lost work from git --- ...import_ems_ems-badge-listing-default.wgpkg | Bin 0 -> 3494 bytes ...import_ems_ems-event-submission-main.wgpkg | Bin 0 -> 2565 bytes ...mport_ems_ems-event-submission-queue.wgpkg | Bin 0 -> 2380 bytes ...root_import_ems_ems-event-submission.wgpkg | Bin 0 -> 1689 bytes docs/upgrades/upgrade_7.8.4-7.8.5.pl | 116 ++++ lib/WebGUI/Form/Div.pm | 114 ++++ .../Workflow/Activity/CloseResolvedTickets.pm | 1 + .../Workflow/Activity/ProcessEMSApprovals.pm | 123 +++++ lib/WebGUI/i18n/English/Asset_HelpDesk.pm | 1 + lib/WebGUI/i18n/English/Asset_Ticket.pm | 1 + lib/WebGUI/i18n/English/Form_Div.pm | 15 + t/Asset/EMSSubmissionForm.t | 516 ++++++++++++++++++ t/Form/Div.t | 66 +++ www/extras/wobject/EMS/close12_1.gif | Bin 0 -> 85 bytes www/extras/wobject/EMS/indicator.gif | Bin 0 -> 1553 bytes www/extras/wobject/EMS/submission.css | 114 ++++ www/extras/wobject/EMS/submission.js | 408 ++++++++++++++ 17 files changed, 1475 insertions(+) create mode 100644 docs/upgrades/packages-7.8.5/root_import_ems_ems-badge-listing-default.wgpkg create mode 100644 docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-main.wgpkg create mode 100644 docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-queue.wgpkg create mode 100644 docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission.wgpkg create mode 100644 lib/WebGUI/Form/Div.pm create mode 120000 lib/WebGUI/Workflow/Activity/CloseResolvedTickets.pm create mode 100644 lib/WebGUI/Workflow/Activity/ProcessEMSApprovals.pm create mode 120000 lib/WebGUI/i18n/English/Asset_HelpDesk.pm create mode 120000 lib/WebGUI/i18n/English/Asset_Ticket.pm create mode 100644 lib/WebGUI/i18n/English/Form_Div.pm create mode 100644 t/Asset/EMSSubmissionForm.t create mode 100644 t/Form/Div.t create mode 100644 www/extras/wobject/EMS/close12_1.gif create mode 100644 www/extras/wobject/EMS/indicator.gif create mode 100644 www/extras/wobject/EMS/submission.css create mode 100644 www/extras/wobject/EMS/submission.js diff --git a/docs/upgrades/packages-7.8.5/root_import_ems_ems-badge-listing-default.wgpkg b/docs/upgrades/packages-7.8.5/root_import_ems_ems-badge-listing-default.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..64aa307a4c4de947b7032f49f26db2c7d4a14920 GIT binary patch literal 3494 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 UwZK;k{6j79f6G;iJ^(rZ0NMe@%m4rY literal 0 HcmV?d00001 diff --git a/docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-main.wgpkg b/docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-main.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..715fadb732ed9ca4054db31a8653d228e8c56a67 GIT binary patch literal 2565 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 b^?c{?eFeU+!1oncVFmsH7%T-o04x9i;luAD literal 0 HcmV?d00001 diff --git a/docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-queue.wgpkg b/docs/upgrades/packages-7.8.5/root_import_ems_ems-event-submission-queue.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..717ff6cd2317a56800a8be42d692162f3dc11c33 GIT binary patch literal 2380 zcmV-S3A6SeiwFP!00000|Lt0DQ`v8*GmQrdHc^>`M>t|s=tPWho8U; zWroLrix|E}j3Ik8#vY?(!!jf>`tB)QQ(FM{@?q67OA68w{9jm-6zAo$ zSAzAPE=r2|+*Bir(M!wH5;9aZdU0V|Qp&$7O-ja+u2`x#J)7&&<>}vZo>!n0=ecns zbHYnY6weM&i$p1UqEPibRgXmTk(8-h*1h}n;zLM&CgYJ!@Bf&5zdQX+jg3NAR4jh< zVUjWL-Ap{D{NEbBgC22BL5j8S5st8$OXwkS9P9}OS{q2{Y3MVbM~EP4&D=2bqoCs) zIE2Nsnu=Z8pbEmaL+%V48cGTfox7X2Qftsj0jLp4lhcU}h zyt2)p>A&W)hnRIGIQ)$}@-txJi_qO&sVX^~gA7}PbI6)EKNiA=PsvCcL$_AM*J1l< zD+l8pmgmJAXU+^hKu4~d9{>j69Kd49AXs`Yeufvwanu5{8f8d(H|Rc9PtC>ttm0>`;L zepN-}fx9oZ%P#1fRWF|9kWkEu3-*LKP(*96YIM#6zP5j~*X>?s8J>g=4s(I7ZP`aS zI~4GQ3lQ6;Mm)kK&x%ebgNiW`XW}*2w?(AZMu?7#cRR2U&`dytIFTzr0ArEU0WkF? z^v8RiJ@Ug!j*BiNQBEi(k1lmINxTsb34^l18J?mL>Te#_iIe^P5%PxeT0lD=f%ABr z+$@yEy->kjl!Ac*^nFF+7(2%6vaCIRpl(^`$t8vw&ZF_zcL-FN_+X~d+-SENtyWXh zK%^I;G$1BJfG$HzWC9K;mI+Ax9q@>l(^e!xdD`UO7ZeTj0zM7C`V91lJ(Z`!eM=hqekM|ql^N$in-ITO9aO6lD}g;+Vu@h$pD3LP9@~bF`s1}o*y608k5i?pWmaz zS38-@8$v(F+f4A)AieH;LEGADZ*6U~o7$KV-w}Q&$uou+Q{*IQ8{iU028uE|9r=@v z$FWOn4bAEi#qrHgdJmM>&VxXr0kUJU{D@TfJ?Hkc|In|J7IY!1!B81C=|B`oWii=0 zD5BPNsF%h4M%-g0-^sng+%Cg>zy0oV|MTAY-sO99nP#K1`oLR+{!YHNaO82hwPY(H zv$!?WIRIkQxu`ZlZwy3Vz&ime?f_!oXk9*Ve5kPmQ1V!fU&crDQdHee$7bql z`cnBXsgNllTj^%rax`{TO%RuL85aT#ToveCjd9d0jFKpdgQ&-z);YPLv*P^Sy$WgR6aWdKQb z;#E~g9M%(fLqizWLxLu(1z4gikb|`(Zm@SBq5Sq|kO0(wzQ_GRzJ3c7u=)-TKOzrQ zgYpVUJl?}-M`Ztw#|kIaAl3o(5^q>(tge0p323*z`k+NiiXJMcnnMk>0I?Czr>l=# zU-SLd)$V&!Vg{A3v1fiRObG2x zDWv3lLKmeZtx)(A!ahgNf4D^g%MfHsMG>)%K9+YbG5;W+Cj y_iLS~@ynk>O+8t768-p}P(1$h_!@t%@q@i*;TD zT4HP_5~-4u9e3z|-;sJD{T4f}T?|81G*NWqJ;&qSbL8!mw*OSC)kdRHD#34f%x|Z7 zswK~>HFoQ@>fTmqRs5JafkhaeD~~1NWN2%F~~fh|nEhi07}m zWryPsCI~qWF_?xWe3IiB!#4>~E)46I+sl;4s81*YSGq_D3^?MJQ22==w-9X>F+ku} z)C=(}Vjfg)EDI*xqo-lW5X{&1zfD2aNx0_casEHY?v zA#*&EIY0;djSk`^D=NPFA>WziwK&f$3pZl%3h9H#MCTiAzBafClv}6 zY#S>Ui&SmATo|C$vobpwArdq6BI95dY zq0+GeMv=qo77v55dZ4aWKC&vIi^S3*(xs+W=rem(LSD+R<3H{y??-=L9(O*ShQFWP zyyLIU*o23=ny99MOCojaad9Nn{|X+$?W!V@UPOc-%t9dIm;?c)da8AGBI1lQ$&@Fw z$hrXaIZNVBa2ODo&Z-$B@=Ki-v?Sc{uE@0`utwb(BEEwHxZ|ACwyv9TI~@Z8N9`YH zp@8#j4APdH%~tOL89F}P<^&v&;aF8smzWCNVW38LspAwt0TFPg9A6L#)fgmDng=xt zLux_Gg^zlkg<)&K=}8$J1;apxZDwEzQ%hl{rDwt(%sJyiW5Ip2m4x}L`b)1bWGr?j zhk;B#P`7Q<;oJbOfo}>S8<~jka72-aoAk#*x?E-Sbsh`29RH%J5G2jS}Qki16&qEYi(~-v)^Gi_V30NQ9OF&YB-(-MX67E;D#K zH9nvyP1R4h_x7^WY-(RLn-^K1#SB+%krNgW*pc*f>ecodb#M1z|G*5=siKVrZ#svH zKpf*#XI5)Q3m@UmtEV-LE+Q0JsGfk9STqBP9DiUEO!4(zPRk)G5*=j^u|&Bx(fye+ zilJvTwEH@mQqRe^)RbL#jGZy!aAem|3!K<&9$%cipItl=@0n`&q&=vKE)x-N@HI-p zdm}(&9vn0d4)z)~i)%R^5=Gc=@=n#ftpcuwZc`C1W<6rSMjfh>F!hGz_(b5eMU^+K zv;`J2g>Vuv@>4%S47g_Z4MNWMcDw5yvMz{vUPYLo*@p#@}&go%7`wn;^n5W$4`1{B|*KZYt)lo9mS5+ZhmR$=Lk$+~brhLuy)8^;g ztf|*&p}aw5NUsOM0@T!o;yFd5!iN@U0-jPs9M!hW300;438D~Vil@)V0ybU|D{4dW zQv_&20#l!lV|g|w9wq8$hnbIe-(r3|=+nyW=P;>`E$V??>v&x{o$!3+J9NA*1VSn5po|^mYKKvbx^(Sh@;CO*gd_gbQ15~=YHP|F0v=H jPc^K+Kl#3i=J=zIM-M!D;L!vBV-Nfb^ixY$03ZMWM$|Bs literal 0 HcmV?d00001 diff --git a/docs/upgrades/upgrade_7.8.4-7.8.5.pl b/docs/upgrades/upgrade_7.8.4-7.8.5.pl index 1a027df9e..c1f42cd95 100644 --- a/docs/upgrades/upgrade_7.8.4-7.8.5.pl +++ b/docs/upgrades/upgrade_7.8.4-7.8.5.pl @@ -30,6 +30,9 @@ my $quiet; # this line required my $session = start(); # this line required fixPackageFlagOnOlder( $session ); +addEMSSubmissionTables($session); +configEMSActivities($session); + # upgrade functions go here @@ -45,6 +48,119 @@ finish($session); # this line required # print "DONE!\n" unless $quiet; #} +#---------------------------------------------------------------------------- +# Describe what our function does +sub configEMSActivities { + my $session = shift; + print "\tConfigure EMS Activities... " unless $quiet; + my $config = $session->config; + $config->addToArray('workflowActivities/None', 'WebGUI::Workflow::Activity::CleanupEMSSubmissions'); + $config->addToArray('workflowActivities/None', 'WebGUI::Workflow::Activity::ProcessEMSApprovals'); + my $workflow = WebGUI::Workflow->new($session, 'pbworkflow000000000001'); # Daily + BREAK: { foreach my $activity (@{ $workflow->getActivities }) { + last BREAK if $activity->getName() eq 'WebGUI::Workflow::Activity::CleanupEMSSubmissions'; + } + my $activity = $workflow->addActivity('WebGUI::Workflow::Activity::CleanupEMSSubmissions'); + $activity->set('title', 'Purge Denied EMS Submissions'); + $activity->set('description', 'Purges EMS Submissions that were denied and are aged according to parameters.'); + } # end of BREAK block + $workflow = WebGUI::Workflow->new($session, 'pbworkflow000000000004'); # Hourly + BREAK: { foreach my $activity (@{ $workflow->getActivities }) { + last BREAK if $activity->getName() eq 'WebGUI::Workflow::Activity::ProcessEMSApprovals'; + } + my $activity = $workflow->addActivity('WebGUI::Workflow::Activity::ProcessEMSApprovals'); + $activity->set('title', 'Process Approves EMS Submissions'); + $activity->set('description', 'Create EMS Ticket Assets for approved submissions.'); + } # end of BREAK block + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +# make database changes relevant to EMS Submission system +sub addEMSSubmissionTables { + my $session = shift; + print "\tCreate EMS Submission Tables... " unless $quiet; + my $db = $session->db; + + $db->write(<write(<write(<write(<write(<write(<write(<write(<write(<div({ + contentCallback => sub { $self->getDivContents(shift); } + }); + +=head3 additionalTerms + +The following additional parameters have been added via this sub class. + +=head4 contentCallback + +A code enclosure which returns the html text to insert into the div element. The divId is passed as parameter 0 when it is called. This function MUST return good html text, it is NOT processed here at all. + +=cut + +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift || []; + push(@{$definition}, { + contentCallback=>{ + defaultValue=> sub { return '' }, + }, + }); + return $class->SUPER::definition($session, $definition); +} + +#------------------------------------------------------------------- + +=head2 getName ( session ) + +Returns the name of the form control. + +=cut + +sub getName { + my ($class, $session) = @_; + return WebGUI::International->new($session, "Form_Div")->get("topicName"); +} + + +#------------------------------------------------------------------- + +=head2 getValue ( [ value ] ) + +Does some special processing. + +=cut + +sub getValue { + my $self = shift; + return $self->get('contentCallback')->($self->get('id')); +} + +#------------------------------------------------------------------- + +=head2 toHtml ( ) + +Renders an input tag of type text. + +=cut + +sub toHtml { + my $self = shift; + return '
get("extras").'>' . $self->getValue . '
' ; +} + +1; +#vim:ft=perl diff --git a/lib/WebGUI/Workflow/Activity/CloseResolvedTickets.pm b/lib/WebGUI/Workflow/Activity/CloseResolvedTickets.pm new file mode 120000 index 000000000..dcdded4c6 --- /dev/null +++ b/lib/WebGUI/Workflow/Activity/CloseResolvedTickets.pm @@ -0,0 +1 @@ +/data/helpdesk/lib/WebGUI/Workflow/Activity/CloseResolvedTickets.pm \ No newline at end of file diff --git a/lib/WebGUI/Workflow/Activity/ProcessEMSApprovals.pm b/lib/WebGUI/Workflow/Activity/ProcessEMSApprovals.pm new file mode 100644 index 000000000..a670a8ba7 --- /dev/null +++ b/lib/WebGUI/Workflow/Activity/ProcessEMSApprovals.pm @@ -0,0 +1,123 @@ +package WebGUI::Workflow::Activity::ProcessEMSApprovals; + + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2008 Plain Black Corporation. + ------------------------------------------------------------------- + Please read the legal notices (docs/legal.txt) and the license + (docs/license.txt) that came with this distribution before using + this software. + ------------------------------------------------------------------- + http://www.plainblack.com info@plainblack.com + ------------------------------------------------------------------- + +=cut + +use strict; +use base 'WebGUI::Workflow::Activity'; +use WebGUI::Asset; +use WebGUI::International; +use WebGUI::VersionTag; + +=head1 NAME + +Package WebGUI::Workflow::Activity::ProcessEMSApprovals + +=head1 DESCRIPTION + +Uses the settings in the help desk to determine whether the resolved tickets should be closed or not. + +=head1 SYNOPSIS + +See WebGUI::Workflow::Activity for details on how to use any activity. + +=head1 METHODS + +These methods are available from this class: + +=cut + + +#------------------------------------------------------------------- + +=head2 definition ( session, definition ) + +See WebGUI::Workflow::Activity::defintion() for details. + +=cut + +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my $i18n = WebGUI::International->new( $session, "Asset_EMSSubmissionForm" ); + push(@{$definition}, { + name => $i18n->get("activity title approve submissions"), + properties => {} + }); + return $class->SUPER::definition($session,$definition); +} + + +#------------------------------------------------------------------- + +=head2 execute ( ) + +See WebGUI::Workflow::Activity::execute() for details. + +=cut + + +sub execute { + my $self = shift; + my $session = $self->session; + my $root = WebGUI::Asset->getRoot($session); + # keep track of how much time it's taking + my $start = time; + my $limit = 2_500; + my $timeLimit = 60; + + my $list = $root->getLineage( ['descendants'], { returnObjects => 1, + includeOnlyClasses => ['WebGUI::Asset::EMSSubmissionForm'], + } ); + + for my $emsForm ( @$list ) { + my $whereClause = q{ submissionStatus='approved' }; + my $res = $emsForm->getLineage(['children'],{ returnObjects => 1, + joinClass => 'WebGUI::Asset::EMSSubmission', + includeOnlyClasses => ['WebGUI::Asset::EMSSubmission'], + whereClause => $whereClause, + } ); + for my $submission ( @$res ) { + my $properties = { className => 'WebGUI::Asset::Sku::EMSTicket' }; + for my $name ( qw{title description seatsAvailable price vendorId + synopsis location duration startDate sku relatedRibbons + relatedBadgeGroups eventMetaData shipsSeparately} ) { + $properties->{$name} = $submission->get($name); + } + $properties->{eventNumber} = $self->session->db->quickScalar( + "select max(eventNumber)+1 + from EMSTicket left join asset using (assetId) + where parentId=?",[$emsForm->ems->getId]) || 0; + my $newAsset = $emsForm->ems->addChild( $properties ); + if( $newAsset ) { + # TODO this should be addRevision + $submission->update({ ticketId => $newAsset->getId, submissionStatus => 'created' }); + WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, { override => 1, allowComments => 0 }); + } else { + $submission->addComment($@) if $@; + $submission->update({ submissionStatus => 'failed' }); + } + $limit--; + last if ! $limit or time > $start + $timeLimit; + } + } + return $self->WAITING(1) if ! $limit or time > $start + $timeLimit; + return $self->COMPLETE; +} + +1; + + diff --git a/lib/WebGUI/i18n/English/Asset_HelpDesk.pm b/lib/WebGUI/i18n/English/Asset_HelpDesk.pm new file mode 120000 index 000000000..9790cf495 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_HelpDesk.pm @@ -0,0 +1 @@ +/data/helpdesk/lib/WebGUI/i18n/English/Asset_HelpDesk.pm \ No newline at end of file diff --git a/lib/WebGUI/i18n/English/Asset_Ticket.pm b/lib/WebGUI/i18n/English/Asset_Ticket.pm new file mode 120000 index 000000000..ad15b6f7c --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_Ticket.pm @@ -0,0 +1 @@ +/data/helpdesk/lib/WebGUI/i18n/English/Asset_Ticket.pm \ No newline at end of file diff --git a/lib/WebGUI/i18n/English/Form_Div.pm b/lib/WebGUI/i18n/English/Form_Div.pm new file mode 100644 index 000000000..f956a4a01 --- /dev/null +++ b/lib/WebGUI/i18n/English/Form_Div.pm @@ -0,0 +1,15 @@ +package WebGUI::i18n::English::Form_Div; + +use strict; ##Required for all good Perl::Critic compliant code + +our $I18N = { + 'topicName' => { + message => q|Form Control Div Element|, + lastUpdated => 1131394070, #seconds from the epoch + context => q|Name of the form control that generates HTML Div elements| + }, + +}; + +1; +#vim:ft=perl diff --git a/t/Asset/EMSSubmissionForm.t b/t/Asset/EMSSubmissionForm.t new file mode 100644 index 000000000..d6a60e7c3 --- /dev/null +++ b/t/Asset/EMSSubmissionForm.t @@ -0,0 +1,516 @@ +# vim:syntax=perl +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2009 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------ +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------ + +# Write a little about what this script tests. +# +# + +use FindBin; +use strict; +use lib "$FindBin::Bin/../lib"; +use Test::More; +use Test::Deep; +use Test::Warn; +use JSON; +use WebGUI::Test; # Must use this before any other WebGUI modules +use WebGUI::Test::Activity; +use WebGUI::Group; +use WebGUI::User; +use WebGUI::Session; +use WebGUI::Asset::Wobject::EventManagementSystem; +use WebGUI::Asset::Sku::EMSBadge; +use WebGUI::Asset::Sku::EMSTicket; +use WebGUI::Asset::Sku::EMSRibbon; +use WebGUI::Asset::Sku::EMSToken; + +#---------------------------------------------------------------------------- +# Init +my $session = WebGUI::Test->session; + +#---------------------------------------------------------------------------- +# Tests + +plan tests => 52; # Increment this number for each test you create + +(my $submitGroupA = WebGUI::Group->new($session,'new'))->name('groupA'); +(my $submitGroupB = WebGUI::Group->new($session,'new'))->name('groupB'); +(my $registrars = WebGUI::Group->new($session, 'new'))->name('registrars'); +(my $attendees = WebGUI::Group->new($session, 'new'))->name('attendees'); + +(my $registrar = WebGUI::User->new($session,'new'))->update({username=>'registrar'}); +(my $userA = WebGUI::User->new($session,'new'))->update({username=>'userA'}); +(my $userB = WebGUI::User->new($session,'new'))->update({username=>'userB'}); +(my $userC = WebGUI::User->new($session,'new'))->update({username=>'userC'}); + +$registrars->addUsers([$registrar->getId]); +$submitGroupA->addUsers([$userA->userId,$userC->userId]); +$submitGroupB->addUsers([$userB->userId,$userC->userId]); +$attendees->addUsers([$userA->getId, $userB->getId, $userC->getId]); + +WebGUI::Test->groupsToDelete($submitGroupA,$submitGroupB); +WebGUI::Test->groupsToDelete($registrars, $attendees); +WebGUI::Test->usersToDelete($userA,$userB,$userC,$registrar); + +sub loginAdmin { $session->user({userId => 3}); } +sub loginRgstr { $session->user({userId => $registrar->userId}); } +sub loginUserA { $session->user({userId => $userA->userId}); } +sub loginUserB { $session->user({userId => $userB->userId}); } +sub loginUserC { $session->user({userId => $userC->userId}); } +sub logout { $session->user({userId => 1}); } + +#---------------------------------------------------------------------------- +# put your tests here +eval { +my $use = use_ok( 'WebGUI::Asset::EMSSubmissionForm' ) + && use_ok( 'WebGUI::Asset::EMSSubmission' ) + && use_ok( 'WebGUI::Workflow::Activity::CleanupEMSSubmissions' ) + && use_ok( 'WebGUI::Workflow::Activity::ProcessEMSApprovals' ); + +SKIP: { skip 'package compile failed!', 1 unless $use; + +loginAdmin; + +# Create a version tag to work in +my $versionTag = WebGUI::VersionTag->getWorking($session); +$versionTag->set({name=>"EventManagementSystem Test"}); +WebGUI::Test->tagsToRollback($versionTag); + +# Do our work in the import node +my $node = WebGUI::Asset->getImportNode($session); + +loginRgstr ; + +# Add an EMS asset +my $ems = $node->addChild({ + className =>'WebGUI::Asset::Wobject::EventManagementSystem', + title => 'Test EMS', + description => 'This is a test ems', + url => '/test-ems', + workflowIdCommit => 'pbworkflow000000000003', # Commit Content Immediately + registrationStaffGroupId => $registrars->getId, + groupIdView => $attendees->getId, + submittedLocationsList => join( "\n", my @submissionLocations = qw'loc1 loc2' ), +}); +# I scooped this out ot WG::Asset::Wobject::EventManagementSystem +# its not pretty, but there is no other way to add a meta field + $ems->setCollateral("EMSEventMetaField", "fieldId",{ + fieldId=> 'new', + label => 'mfRequiredUrl', + dataType => 'url', + visible => 1, + required => 1, + possibleValues => '', + defaultValues => '', + },1,1); + + $ems->setCollateral("EMSEventMetaField", "fieldId",{ + fieldId=> 'new', + label => 'mfDate', + dataType => 'date', + visible => 1, + required => 0, + possibleValues => '', + defaultValues => '', + },1,1); + +my $i18n = $ems->i18n; + +$versionTag->commit; +$versionTag = WebGUI::VersionTag->getWorking($session); +WebGUI::Test->tagsToRollback($versionTag); + +my $id1 = $ems->getNextSubmissionId; +my $id2 = $ems->getNextSubmissionId; +is( $id1 +1, $id2, ' test getNextSubmissionId' ); + +# quick test of addGroupToSubmitList +is($ems->get('eventSubmissionGroups'),'', 'event submission groups is blank'); +$ems->addGroupToSubmitList('joe'); +is($ems->get('eventSubmissionGroups'),'joe', 'event submission groups has one item'); +$ems->addGroupToSubmitList('frank'); +is($ems->get('eventSubmissionGroups'),'frank joe', 'event submission groups has two items'); +$ems->addGroupToSubmitList('joe'); +is($ems->get('eventSubmissionGroups'),'joe frank', 'event submission groups still has two items'); +$ems->update({eventSubmissionGroups => ''}); +is($ems->get('eventSubmissionGroups'),'', 'event submission groups is reset to blank'); + + +is_deeply($ems->getSubmissionLocations, \@submissionLocations, 'test getSubmissionLocations' ); +is_deeply( $ems->getSubmissionStatus, { + map { $_ => $i18n->get($_) } ( qw/pending feedback failed approved created denied/ ) +}, 'test getSubmissionStatus' ); + + +loginRgstr; + +is( $ems->hasSubmissionForms, 0, 'ems currently has no forms' ); + +#print 'press return to continue test' ; <>; + +my $formAdesc = { + _fieldList => [ qw/title description startDate/ ], + title => 1, + description => 1, + duration => 0, + startDate => 1, + seatsAvailable => 0, + location => 0, +}; + + +my $frmA = $ems->addSubmissionForm({ + title => 'test A -- long', + canSubmitGroupId => $submitGroupA->getId, + daysBeforeCleanup => 1, + formDescription => $formAdesc, +}); +isa_ok( $frmA, 'WebGUI::Asset::EMSSubmissionForm' ); +is( $ems->hasSubmissionForms, 1, 'ems now has forms' ); +is_deeply( $frmA->getFormDescription, $formAdesc, 'form description matches' ); +is( $frmA->ems->getId, $ems->getId, 'test ems access function in form' ); + +my $formBdesc = { + _fieldList => [ qw/title description duration mfRequiredUrl/ ], + title => 1, + description => 1, + duration => 1, + startDate => 0, + mfRequiredUrl => 1, + seatsAvailable => 0, + location => 0, +}; +my $frmB = $ems->addSubmissionForm({ + className => 'WebGUI::Asset::EMSSubmissionForm', + title => 'test B -- short', + daysBeforeCleanup => 1, + canSubmitGroupId => $submitGroupB->getId, + formDescription => $formBdesc, +}); +logout; + +ok( !$ems->canSubmit, 'Visitor cannot submit to this ems' ); +ok( !$frmA->canSubmit, 'Visitor cannot submit to form' ); + +loginUserA; + +ok( $ems->canSubmit, 'UserA can submit to this ems' ); +ok( $frmA->canSubmit, 'UserA can submit to formA' ); +ok( !$frmB->canSubmit, 'UserA cannot submit to formB' ); +#print 'press return to complete test' ; <>; +ok( !$ems->hasSubmissions, 'UserA has no submissions' ); + +my $submission = { + title => 'my favorite thing to talk about', + description => 'the description', + startDate => '1255150800', + }; +$session->request->setup_body($submission); +my $sub1 = $frmA->addSubmission; +WebGUI::Test->assetsToPurge( $sub1 ); +print join( "\n", @{$sub1->{errors}} ),"\n" if defined $sub1->{errors}; +my $isa1 = isa_ok( $sub1, 'WebGUI::Asset::EMSSubmission', "userA/formA valid submission succeeded" ); +ok( $ems->hasSubmissions, 'UserA has submissions on this ems' ); +is( $sub1->ems->getId, $ems->getId, 'test ems access function in submission' ); +loginUserB; + +ok( $ems->canSubmit, 'UserB can submit to this ems' ); +ok( !$frmA->canSubmit, 'UserB cannot submit to formA' ); +ok( $frmB->canSubmit, 'UserB can submit to formB' ); + +$submission = { + title => 'why i like to be important', + description => 'the description', + mfRequiredUrl => 'http://google.com', + }; +$session->request->setup_body($submission); +my $sub2 = $frmB->addSubmission; +WebGUI::Test->assetsToPurge( $sub2 ); +my $isa2 = isa_ok( $sub2, 'WebGUI::Asset::EMSSubmission', "userB/FormB valid submission succeeded" ); + +loginUserC; + +ok( $ems->canSubmit, 'UserC can submit to this ems' ); +ok( $frmA->canSubmit, 'UserC can submit to formA' ); +ok( $frmB->canSubmit, 'UserC can submit to formB' ); + +loginUserA; +cmp_deeply( from_json($ems->www_getAllSubmissions), { + sort => undef, + startIndex => 1, + records => [ + { + lastReplyDate => '', + submissionId => '3', + creationDate => ignore(), + createdBy => 'userA', + url => '/test-ems?func=viewSubmissionQueue#3', + submissionStatus => $i18n->get('pending'), + title => 'my favorite thing to talk about', + lastReplyBy => '' + } + ], + totalRecords => '1', + recordsReturned => 25, + dir => 'DESC', +}, 'test getAllSubmissions for UserA' ); + +$session->request->setup_body({submissionId => 3}); +cmp_deeply( from_json($ems->www_getSubmissionById), { + title => 3, + id => 3, + text => ignore(), +}, 'test getSubmissionById'); + +loginUserC; +cmp_deeply( from_json($ems->www_getAllSubmissions), { + sort => undef, + startIndex => 1, + records => [ + ], + totalRecords => '0', + recordsReturned => 25, + dir => 'DESC', +}, 'test getAllSubmissions for UserC' ); + +loginRgstr; +$session->request->setup_body({ orderByColumn => 'submissionId' }); +cmp_deeply( from_json($ems->www_getAllSubmissions), { + sort => 'submissionId', + startIndex => 1, + records => [ + { + lastReplyDate => '', + submissionId => '4', + creationDate => ignore(), + createdBy => 'userB', + url => '/test-ems?func=viewSubmissionQueue#4', + submissionStatus => $i18n->get('pending'), + title => 'why i like to be important', + lastReplyBy => '' + }, + { + lastReplyDate => '', + submissionId => '3', + creationDate => ignore(), + createdBy => 'userA', + url => '/test-ems?func=viewSubmissionQueue#3', + submissionStatus => $i18n->get('pending'), + title => 'my favorite thing to talk about', + lastReplyBy => '' + }, + ], + totalRecords => '2', + recordsReturned => 25, + dir => 'DESC', +}, 'test getAllSubmissions for Registrar' ); + +SKIP: { skip 'create submission failed', 8 unless $isa1 && $isa2; + +loginUserA; + +$sub1->addComment( 'this is a test comment' ); +cmp_deeply($sub1->get('comments')->[0],{ + id => re( qr/.+/ ), + alias => 'userA', + userId => $userA->userId, + comment => 'this is a test comment', + rating => 0, + date => re( qr/\d{10}/ ), + ip => undef, +}, "successfully added comment" ); + +$sub1->update({ + title => 'the new title' +}); + +is( $sub1->get('title'),'the new title','successfully changed the title'); + +loginRgstr; + +$sub1->update({ submissionStatus => 'approved' }); +is($sub1->get('submissionStatus'),'approved','set status to approved'); + +$sub2->update({ submissionStatus => 'denied' }); +is($sub2->get('submissionStatus'),'denied','set status to denied'); + +SKIP: { skip "workflow activities not coded yet", 10 if 0; + +# create the workflows/activities for processing +my $approveSubmissions = WebGUI::Test::Activity->create( $session, + "WebGUI::Workflow::Activity::ProcessEMSApprovals" +); +my $cleanupSubmissions = WebGUI::Test::Activity->create( $session, + "WebGUI::Workflow::Activity::CleanupEMSSubmissions" +); + +is($approveSubmissions->run, 'complete', 'approval complete'); +is($approveSubmissions->run, 'done', 'approval done'); + +$sub1 = $sub1->cloneFromDb; +is( $sub1->get('submissionStatus'),'created','approval successfull'); + +my $ticket = WebGUI::Asset->newByDynamicClass($session, $sub1->get('ticketId')); +isa_ok( $ticket, 'WebGUI::Asset::Sku::EMSTicket', 'approval created a ticket'); +WebGUI::Test->assetsToPurge( $ticket ) if $ticket ; + +my $newDate = time - ( 60 * 60 * 24 * ( $sub2->getParent->get('daysBeforeCleanup') + 1 ) ), +$sub2->update({ + submissionStatus => 'denied', + # lastModified => $newDate, -- update overrides this... +}); +my $sub2Id = $sub2->getId; +$session->db->write('update assetData set lastModified = ' . $newDate . ' where assetId = "' . $sub2Id . '"' ); + +$cleanupSubmissions->rerun; +is($cleanupSubmissions->run, 'complete', 'cleanup complete'); +is($cleanupSubmissions->run, 'done', 'cleanup done'); + +$sub2 = WebGUI::Asset->newByDynamicClass($session, $sub2Id); +is( $sub2, undef, 'submission deleted'); + +} # end of workflow skip + +} # end of create submission skip + +$versionTag->commit; + +SKIP: { skip 'requires HTML::Form', 2 unless use_ok 'HTML::Form'; +# this is not the greatest testm but it does run through the basic create submissionForm code. +loginRgstr; + +my %settings = ( + assetId => 'new', + fieldNames => 'title description startDate duration seatsAvailable location nzymEeuHPQIsgXY0hZxDxA xlvMNwFi1FWwP0PrUAnxSQ', + title => 'Untitled', + menuTitle => 'Untitled', + url => '', + canSubmitGroupId => 2, + daysBeforeCleanup => 7, + deleteCreatedItems => 0, + submissionDeadline => '1991-06-21', + pastDeadlineMessage => 'The deadline for this submission is past, no more submissions will be taken at this time.', + title_yesNo => 1, + description_yesNo => 1, + startDate_yesNo => 1, + duration_yesNo => 1, + seatsAvailable_yesNo => 1, + location_yesNo => 1, + nzymEeuHPQIsgXY0hZxDxA_yesNo => 1, + xlvMNwFi1FWwP0PrUAnxSQ_yesNo => 1, +); + +my $expected = { + 'submissionDeadline' => '1991-06-21', + 'menuTitle' => 'Untitled', + 'pastDeadlineMessage' => 'The deadline for this submission is past, no more submissions will be taken at this time.', + 'formDescription' => { + 'location' => '1', + 'nzymEeuHPQIsgXY0hZxDxA' => 'xlvMNwFi1FWwP0PrUAnxSQ', + 'seatsAvailable' => '1', + 'duration' => '1', + 'title' => '1', + 'startDate' => '1', + 'description' => '1', + 'submissionStatus' => '0', + '_fieldList' => [ + 'title', + 'description', + 'startDate', + 'duration', + 'seatsAvailable', + 'location', + 'nzymEeuHPQIsgXY0hZxDxA' + ] + }, + 'description' => undef, + '_isValid' => 1, + 'deleteCreatedItems' => undef, + 'canSubmitGroupId' => '2', + 'assetId' => 'new', + 'url' => undef, + 'daysBeforeCleanup' => '7', + 'title' => 'Untitled' + } ; + +my $htmlText = $ems->www_addSubmissionForm; +my $form = HTML::Form->parse($htmlText,'http://localhost/'); +for my $input ( $form->inputs ) { + $input->value($settings{$input->name})if exists $settings{$input->name}; +} +$session->request->setup_body( { $form->form } ); +my $result = WebGUI::Asset::EMSSubmissionForm->processForm($ems); +cmp_deeply( $result, $expected , 'test process form' ); +$expected = { + 'errors' => [ + { + 'text' => ignore(), + } + ], + 'submissionDeadline' => undef, + 'menuTitle' => undef, + 'pastDeadlineMessage' => undef, + 'formDescription' => { + '_fieldList' => [], + 'submissionStatus' => 0, + }, + 'description' => undef, + '_isValid' => 0, + 'deleteCreatedItems' => undef, + 'canSubmitGroupId' => undef, + 'assetId' => undef, + 'url' => undef, + 'daysBeforeCleanup' => undef, + 'title' => undef, + }; +$session->request->setup_body( { } ); +$result = WebGUI::Asset::EMSSubmissionForm->processForm($ems); +cmp_deeply( $result, $expected , 'test process form' ); +} # end of skip HTML::Form + +# these run code to see that it runs, but do not check for correctness + +warnings_are { + +$ems->www_viewSubmissionQueue; +$ems->www_addSubmission; +$ems->www_addSubmissionForm; +$ems->www_editSubmissionForm; +$ems->www_editSubmissionFormSave; +$frmA->www_editSubmissionForm; +$frmA->www_addSubmission; +$frmA->www_editSubmission; +$frmA->www_editSubmissionSave; +$frmA->processForm; +$sub1->drawLocationField; +$sub1->drawRelatedBadgeGroupsField; +$sub1->drawRelatedRibbonsField; +$sub1->drawStatusField; +$sub1->www_editSubmission; +$sub1->www_editSubmissionSave; +$sub1->processForm; +# test comments +$sub1->getFormattedComments; + +} [], 'no warnings from calling a bunch of functions'; + +} # end of use packages skip +}; # end of eval +print $@ if $@; + +#done_testing(); +#print 'press return to complete test' ; <>; +#---------------------------------------------------------------------------- +# Cleanup +END { + + +} +#vim:ft=perl diff --git a/t/Form/Div.t b/t/Form/Div.t new file mode 100644 index 000000000..a31f2249b --- /dev/null +++ b/t/Form/Div.t @@ -0,0 +1,66 @@ +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2009 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +use FindBin; +use strict; +use lib "$FindBin::Bin/../lib"; + +use WebGUI::Test; +use WebGUI::Form; +use WebGUI::Form::Div; +use WebGUI::Session; +use HTML::Form; +use WebGUI::Form_Checking; + +#The goal of this test is to verify that Div form elements work + +use Test::More; + +my $session = WebGUI::Test->session; + +# put your tests here + +plan tests => 3; + +my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session)); + +my $textTag = 'hi this is a piece of text that will get placed in a div'; + +sub myContent { + my $id = shift; + return 'ID = ' . $id . $textTag ; +} + +my $html = join "\n", + $header, + WebGUI::Form::Div->new($session, { + name => 'TestDiv', + contentCallback => sub { myContent(shift); }, + })->toHtml, + $footer; + +my @forms = HTML::Form->parse($html, 'http://www.webgui.org'); + +##Test Form Generation + +is(scalar @forms, 1, '1 form was parsed'); + +my @inputs = $forms[0]->inputs; +is(scalar @inputs, 1, 'The form has 1 inputs'); + +# this is not an input control, we just want to see that we are getting +# the desired output + +ok( $html =~ /$textTag/, 'the tag is in the html, so the div was succeccfully implanted' ); + +# TODO write code to parse the html sing xml or some such + +__END__ + diff --git a/www/extras/wobject/EMS/close12_1.gif b/www/extras/wobject/EMS/close12_1.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2f67d72efc158da4e069822cbe338915761e396 GIT binary patch literal 85 zcmZ?wbhEHbz lf$Gy9znh?Y?^x%Bps9Cfw!UsJn!aoAS>7kV)`>G%0|4uCA&me4 literal 0 HcmV?d00001 diff --git a/www/extras/wobject/EMS/indicator.gif b/www/extras/wobject/EMS/indicator.gif new file mode 100644 index 0000000000000000000000000000000000000000..085ccaecaf5fa5c34bc14cd2c2ed5cbbd8e25dcb GIT binary patch literal 1553 zcma)+TTl~c6vwlh>nb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? literal 0 HcmV?d00001 diff --git a/www/extras/wobject/EMS/submission.css b/www/extras/wobject/EMS/submission.css new file mode 100644 index 000000000..8fa15bbd3 --- /dev/null +++ b/www/extras/wobject/EMS/submission.css @@ -0,0 +1,114 @@ +legend { + font-weight: bold; +} + +form { + margin: 0; + padding: 0 +} +.submission_title { + background: #d8d8d8 url(../../yui/build/assets/skins/sam/sprite.png) repeat-x; + border: solid #a3a3a3; + border-width: 0 1px 0; + font-family: arial; + font-weight: bold; + font-size: 14pt; +} +.submission_body { + background: #FFFFFF; + border: 1px solid #000000; +} +.submission_desc { + background: #d8d8d8; +} +.userArea { + font-family: arial; + font-size: 9pt; + color: black; + background-color: white; + overflow: auto; + height: 310px; +} +.hd_searchBtn { + background-color:silver; + color:white; + border:solid gray 1px; + text-decoration:none; + font-weight:bold; + text-align:center; + cursor:pointer; + font-size:9pt; +} +.inputBox { + border:solid gray 1px; + font-size:9pt; +} +.grayArea { + background-color:#F2F2F2; + border:solid #E8E8E8 1px; + padding:3px; + -moz-box-sizing:border-box; +} +#solutionDialog { + background-color: #FFFFFF; +} +.whiteArea { + font-family: arial; + font-size: 9pt; + color: black; +} +.solutionArea { + font-family: arial; + font-size: 9pt; + color: black; + background-color:#FFFFFF; + overflow: auto; + height: 160px; +} +#userList_div { + overflow: auto; + width: 100%; + height: auto; + font-family: arial; + font-size: 10pt; + border: solid #CACACA 1px; +} +* html #userList_div { + overflow: hidden; + overflow-y: auto; +} +#userList_div img { + padding-right: 10px; + padding-left: 10px; +} +#userList_div td { + background-color: #F2F2F2; + border-top: solid #F9F9F9 1px; + border-bottom: solid #E0E0E0 1px; + text-align: left; + vertical-align: top; +} +#userList_div tr.odd td { + background-color: #EAEAEA; +} +.submission_private { + background-color:#AA0002; + border:solid #E8E8E8 1px; + color:white; + font-size: 9pt; + font-weight: bold; + text-align:center; + -moz-box-sizing:border-box; +} +.submission_public { + background-color:#00FF00; + border:solid #E8E8E8 1px; + color:white; + font-size: 0pt; + font-weight: bold; + text-align:center; + -moz-box-sizing:border-box; +} +.dyn_form_field { + width: 120px; +} diff --git a/www/extras/wobject/EMS/submission.js b/www/extras/wobject/EMS/submission.js new file mode 100644 index 000000000..40423324b --- /dev/null +++ b/www/extras/wobject/EMS/submission.js @@ -0,0 +1,408 @@ + +/*** The WebGUI EMS Submission system + * Requires: YAHOO, Dom, Event, DataSource, DataTable, Paginator, Container + * + */ + +var DataSource = YAHOO.util.DataSource, + DataTable = YAHOO.widget.DataTable, + Paginator = YAHOO.widget.Paginator; + +if ( typeof WebGUI == "undefined" ) { + WebGUI = {}; +} + +/*** WebGUI EMS Object + * + * This object renders the WebGUI EMS Submission datatable + * + * @method WebGUI.EMS.constructor + * @param configs {Object} object containing configuration necessary for creating the datatable. +TODO -- fix this to match what EMS really needs + * datasource {String} Required URL that returns the JSON data structure of data to be displayed. + * container {String} Required id of the HTML Element in which to render both the datatable and the pagination + * dtContainer {String} Required id of the HTML Element in which to render the datatable + * view {String} Required String which is passed to the ticket to properly return uses to the right view [all,my,search]. + * fields {ArrayRef} Required Array Reference of Objects used by the DataSource to configure and store data to be used by the data table + * columns {ArrayRef} Required Array Reference of Objects which define the columns for the datatable to render + * p_containers {ArrayRef} Required Array Reference containing the ids of the HTML Elements in which to render pagination. + * defaultSort {Object} Optional Custom object which defines which column and direction the paginator should sort by + * initRequestString {String} Optional Parameters to append to the end of the url when initializing the datatable + */ + + +WebGUI.EMS = function (configs) { + // Initialize configs + this._configs = {}; + if(configs) { + this._configs = configs; + WebGUI.EMS.url = configs.url; + WebGUI.EMS.tabContent = configs.tabContent; + } + WebGUI.EMS.items = new Object(); + + if(!this._configs.initRequestString) { + this._configs.initRequestString = ';startIndex=0'; + } + + /////////////////////////////////////////////////////////////// + // Internationalization + // this comes first because it is used in other areas... + /////////////////////////////////////////////////////////////// + WebGUI.EMS.i18n = new WebGUI.i18n( { + namespaces : { + 'Asset_EMSSubmission' : [ + '' + ], + 'Asset_EventManagementSystem' : [ + 'close tab', + '' + ] + } +// onpreload : { +// fn : this.initialize, +// obj : this, +// override : true, +// } + } ); + + /////////////////////////////////////////////////////////////// + // Protected Static Methods + /////////////////////////////////////////////////////////////// + + //*********************************************************************************** + // This Method updates the window.location.hash when the user changes tabs + WebGUI.EMS.changeTab = function ( e ) { + alert('tab changed'); + var index = WebGUI.EMS.tabs.getTabIndex( e.newValue ); + if( index == 0 ) { + window.location.hash = ''; + } else { + window.location.hash = WebGUI.EMS.Tabs[index].id; + } + }; + + //*********************************************************************************** + // This method closes the active tab + // + // Parameters: ( integer ) -- if a ticket id is passed in then remove the tab for that ticket + // ( e, object ) -- cancel the event and close the tab associated with the object + // ( ) -- get the current tab from the tabview object and close it + // + WebGUI.EMS.closeTab = function ( e, myTab ) { + var index; + if( typeof(e) == "string" || typeof(e) == "number" ) { + index = e; + myTab = WebGUI.EMS.items[index].tab; + } else { + if( typeof(e) != "undefined" ) { + YAHOO.util.Event.preventDefault(e); + } + if( typeof(myTab) == "undefined" ) { + myTab = WebGUI.EMS.tabs.get('activeTab'); + } + index = WebGUI.EMS.tabs.getTabIndex(myTab); + } + delete WebGUI.EMS.items[index]; + WebGUI.EMS.tabs.removeTab(myTab); + if( WebGUI.EMS.lastTab ) { + WebGUI.EMS.tabs.set('activeTab',WebGUI.EMS.lastTab); + } + }; + + //*********************************************************************************** + // Custom function to handle pagination requests + WebGUI.EMS.handlePagination = function (state,dt) { + var sortedBy = dt.get('sortedBy'); + // Define the new state + var newState = { + startIndex: state.startIndex, + sorting: { + key: sortedBy.key, + dir: ((sortedBy.dir === DataTable.CLASS_ASC) ? "asc" : "desc") + }, + pagination : { // Pagination values + startIndex: state.startIndex, // Go to the proper page offset + rowsPerPage: state.rowsPerPage // Return the proper rows per page + } + }; + + // Create callback object for the request + var oCallback = { + success: dt.onDataReturnSetRows, + failure: dt.onDataReturnSetRows, + scope: dt, + argument: newState // Pass in new state as data payload for callback function to use + }; + + // Send the request + dt.getDataSource().sendRequest(WebGUI.EMS.buildQueryString(newState, dt), oCallback); + }; + + //*********************************************************************************** + //This method is out here so it can be overridden. The datatable uses this method to sort it's columns + WebGUI.EMS.newTab = function(url) { + // the 'loading' 'indicator' + if( typeof(WebGUI.EMS.loadingIndicator) == "undefined" ) { + WebGUI.EMS.loadingIndicator = new YAHOO.widget.Overlay( "loadingIndicator", { + fixedcenter : true, + visible : false + } ); + WebGUI.EMS.loadingIndicator.setBody( "Loading ..." + + "" + ); + WebGUI.EMS.loadingIndicator.render(document.body); + } + WebGUI.EMS.loadingIndicator.show(); + + // Create callback object for the request + var oCallback = { + success: function(o) { + var response = eval('(' + o.responseText + ')'); + var myTab; + if(response.hasError){ + var message = ""; + for(var i = 0; i < response.errors.length; i++) { + message += response.errors[i]; + } + alert(message); + return; + // currently only one tab exists, so instead of checking we just delete it and recreate + // this condition is going to have to search for the id in the list + } else { // if( typeof(WebGUI.EMS.items[response.title]) == "undefined" + // || WebGUI.EMS.items[response.title] == null ) { // } + // if there is a tab .. close it, + // at least until I can get the JS/HTML re-written to handle multiple tabs + // there should only be one + for( var item in WebGUI.EMS.items ) { WebGUI.EMS.closeTab(item) } + var myContent = document.createElement("div"); + myContent.innerHTML = response.text; + myTab = new YAHOO.widget.Tab({ + label: response.title + 'X', + contentEl: myContent + }); + WebGUI.EMS.tabs.addTab( myTab ); + var index = WebGUI.EMS.tabs.getTabIndex(myTab); + YAHOO.util.Event.on(myTab.getElementsByClassName('close')[0], 'click', WebGUI.EMS.closeTab , myTab); + WebGUI.EMS.items[index] = new Object(); + WebGUI.EMS.items[index].tab = myTab; + WebGUI.EMS.items[index].id = response.id; + WebGUI.EMS.items[index].title = response.title; + //} else { + //myTab = WebGUI.EMS.items[response.title].tab; + //myTab.set('content', response.text); + } + // make sure the script on the ticket has run + // if( typeof( WebGUI.ticketJScriptRun ) == "undefined" ) { + // eval( document.getElementById("ticketJScript").innerHTML ); + // } + // delete WebGUI.ticketJScriptRun; + WebGUI.EMS.loadingIndicator.hide(); + WebGUI.EMS.lastTab = WebGUI.EMS.tabs.get('activeTab'); + //initHoverHelp(myTab); + WebGUI.EMS.tabs.set('activeTab',myTab); + }, + failure: function(o) { + WebGUI.EMS.loadingIndicator.hide(); + alert("AJAX call failed"); + } + }; + var request = YAHOO.util.Connect.asyncRequest('GET', url + ';asJson=1' , oCallback); + }; + + //*********************************************************************************** + //This method is out here so it can be overridden. The datatable uses this method to sort it's columns + WebGUI.EMS.sortColumn = function(oColumn,sDir) { + // Default ascending + var sDir = "desc"; + + // If already sorted, sort in opposite direction + if(oColumn.key === this.get("sortedBy").key) { + sDir = (this.get("sortedBy").dir === DataTable.CLASS_ASC) ? "desc" : "asc"; + } + + // Define the new state + var newState = { + startIndex: 0, + sorting: { // Sort values + key: oColumn.key, + dir: (sDir === "asc") ? DataTable.CLASS_ASC : DataTable.CLASS_DESC + }, + pagination : { // Pagination values + startIndex: 0, // Default to first page when sorting + rowsPerPage: this.get("paginator").getRowsPerPage() // Keep current setting + } + }; + + // Create callback object for the request + var oCallback = { + success: this.onDataReturnSetRows, + failure: this.onDataReturnSetRows, + scope: this, + argument: newState // Pass in new state as data payload for callback function to use + }; + + // Send the request + this.getDataSource().sendRequest(WebGUI.EMS.buildQueryString(newState, this), oCallback); + }; + + //*********************************************************************************** + // This method checks for modifier keys pressed during the mouse click + function eventModifiers( e ) { + if( e.event.modifiers ) { + return e.event.modifiers & (Event.ALT_MASK | Event.CONTROL_MASK + | Event.SHIFT_MASK | Event.META_MASK); + } else { + return e.event.altKey | e.event.shiftKey | e.event.ctrlKey; + } + } + + //*********************************************************************************** + // This method does the actual work of loading an item into a tab + // + WebGUI.EMS.loadItem = function ( contentId ) { + var submissionId = parseInt( contentId, 10 ); + var url; + // compare contentId with submissionId incase we get an assetId that starts with numeric chars + if( contentId == submissionId ) { + url = WebGUI.EMS.tabContent['editSubmission'] + ";submissionId=" + submissionId; + } else { + url = WebGUI.EMS.tabContent[contentId]; + } + WebGUI.EMS.newTab(url); + }; + + //*********************************************************************************** + // Load an item when the user clicks on an anchor html element + // + WebGUI.EMS.loadItemFromAnchor = function ( anchorObject ) { + var tabContent = anchorObject.hash.substring(1); + WebGUI.EMS.loadItem(tabContent); + }; + + //*********************************************************************************** + // This method is subscribed to by the DataTable and thus becomes a member of the DataTable + // class even though it is a member of the EMS Class. For this reason, a EMS instance + // is actually passed to the method as it's second parameter. + // + WebGUI.EMS.loadItemFromTable = function ( evt, obj ) { + // if the user pressed a modifier key we want to default + if( eventModifiers( evt ) ) { return } + var target = evt.target; + YAHOO.util.Event.stopEvent(evt.event); + var elCell = this.getTdEl(target); + if(elCell) { + var oRecord = this.getRecord(elCell); + var submissionId = oRecord.getData('submissionId'); + + if( typeof( WebGUI.EMS.items[submissionId] ) != "undefined" ) { + WebGUI.EMS.tabs.set('activeTab',WebGUI.EMS.items[submissionId].tab); + WebGUI.EMS.loadingIndicator.hide(); + } else { + WebGUI.EMS.loadItem( submissionId ); + } + } else { + alert("Could not get table cell for " + target); + } + }; + + + /////////////////////////////////////////////////////////////// + // Public Instance Methods + /////////////////////////////////////////////////////////////// + + //*********************************************************************************** + this.getDataTable = function() { + if(!this.EMSQ) { + return {}; + } + return this.EMSQ; + }; + + //*********************************************************************************** + this.getDefaultSort = function() { + if(this._configs.defaultSort) { + return this._configs.defaultSort; + } + return { + "key" : "creationDate", + "dir" : DataTable.CLASS_DESC + }; + }; + + //*********************************************************************************** + // Override this method if you want pagination to work differently + this.getPaginator = function () { + return new Paginator({ + containers : this._configs.p_containers, + pageLinks : 5, + rowsPerPage : 25, + rowsPerPageOptions : [25,50,100], + template : "{CurrentPageReport} {PreviousPageLink} {PageLinks} {NextPageLink} {RowsPerPageDropdown}" + }); + }; + + //*********************************************************************************** + this.initDataTable = function () { + var datasource = new DataSource(this._configs.datasource); + datasource.responseType = DataSource.TYPE_JSON; + datasource.responseSchema = { + resultsList : 'records', + fields : this._configs.fields, + metaFields : { totalRecords: 'totalRecords' } + }; + + // Initialize the data table + this.EMSQ = new DataTable( + this._configs.dtContainer, + this._configs.columns, + datasource, + { + initialRequest : this._configs.initRequestString, + paginationEventHandler : WebGUI.EMS.handlePagination, + paginator : this.getPaginator(), + dynamicData : true, + sortedBy : this.getDefaultSort() + } + ); + this.EMSQ.subscribe("rowMouseoverEvent", this.EMSQ.onEventHighlightRow); + this.EMSQ.subscribe("rowMouseoutEvent", this.EMSQ.onEventUnhighlightRow); + this.EMSQ.subscribe("cellClickEvent",WebGUI.EMS.loadItemFromTable,this); + // Override function for custom server-side sorting + this.EMSQ.sortColumn = WebGUI.EMS.sortColumn; + this.EMSQ.handleDataReturnPayload = function (oReq, oRes, oPayload ) { + oPayload.totalRecords = parseInt( oRes.meta.totalRecords ); + return oPayload; + }; + this.EMSQ.generateRequest = WebGUI.EMS.buildQueryString; + + //Work around nested scoping for the callback + var myEMSQ = this.EMSQ; + //ensure no memory leaks with the datatable + }; + +}; + +/////////////////////////////////////////////////////////////// +// Public Static Methods +/////////////////////////////////////////////////////////////// + +//*********************************************************************************** +WebGUI.EMS.formatTitle = function ( elCell, oRecord, oColumn, orderNumber ) { + elCell.innerHTML = '