radiant-database_mailer-extension 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/README.md +159 -0
  2. data/Rakefile +120 -0
  3. data/app/controllers/admin/form_datas_controller.rb +77 -0
  4. data/app/controllers/database_mailer_processing.rb +19 -0
  5. data/app/helpers/admin/form_datas_helper.rb +57 -0
  6. data/app/models/form_data.rb +93 -0
  7. data/app/models/form_data_asset.rb +14 -0
  8. data/app/views/admin/form_datas/_export.html.haml +33 -0
  9. data/app/views/admin/form_datas/_filters.html.haml +27 -0
  10. data/app/views/admin/form_datas/index.html.haml +34 -0
  11. data/app/views/admin/form_datas/show.html.haml +49 -0
  12. data/config/routes.rb +7 -0
  13. data/database_mailer_extension.rb +31 -0
  14. data/db/migrate/001_create_form_datas.rb +16 -0
  15. data/db/migrate/002_add_data_columns.rb +13 -0
  16. data/db/migrate/20090722135916_create_form_data_assets.rb +21 -0
  17. data/features/datasets/database_mailer_dataset.rb +19 -0
  18. data/features/datasets/mailers_dataset.rb +69 -0
  19. data/features/fixtures/attachment.jpg +0 -0
  20. data/features/saving_emails_to_database.feature +45 -0
  21. data/features/step_definitions/admin_steps.rb +6 -0
  22. data/features/step_definitions/email_steps.rb +73 -0
  23. data/features/step_definitions/form_data_steps.rb +3 -0
  24. data/features/step_definitions/webrat_steps.rb +119 -0
  25. data/features/support/env.rb +28 -0
  26. data/features/support/paths.rb +25 -0
  27. data/lib/radiant-database_mailer-extension.rb +8 -0
  28. data/lib/tasks/database_mailer_extension_tasks.rake +31 -0
  29. data/public/javascripts/admin/database_mailer.js +73 -0
  30. data/public/stylesheets/sass/admin/database_mailer.sass +235 -0
  31. data/radiant-database_mailer-extension.gemspec +26 -0
  32. data/spec/controllers/form_datas_controller_spec.rb +272 -0
  33. data/spec/controllers/mail_controller_spec.rb +40 -0
  34. data/spec/helpers/form_datas_helper_spec.rb +5 -0
  35. data/spec/models/form_data_asset_spec.rb +11 -0
  36. data/spec/models/form_data_spec.rb +151 -0
  37. data/spec/spec.opts +6 -0
  38. data/spec/spec_helper.rb +37 -0
  39. data/spec/views/index.html.erb_spec.rb +25 -0
  40. metadata +139 -0
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.namespace :admin do |admin|
3
+ admin.resources :form_datas do |form_data|
4
+ form_data.resources :form_data_assets
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ require_dependency 'application_controller'
2
+ require 'radiant-database_mailer-extension/version'
3
+
4
+ class DatabaseMailerExtension < Radiant::Extension
5
+ version RadiantDatabaseMailerExtension::VERSION
6
+ description RadiantDatabaseMailerExtension::DESCRIPTION
7
+ url RadiantDatabaseMailerExtension::URL
8
+
9
+ def activate
10
+ throw "MailerExtension must be loaded before DatabaseMailerExtension" unless defined?(MailerExtension)
11
+ MailController.class_eval do
12
+ include DatabaseMailerProcessing
13
+ alias_method_chain :process_mail, :database
14
+ end
15
+
16
+ MailerProcess.class_eval do
17
+ include DatabaseMailerProcessing
18
+ alias_method_chain :process_mail, :database
19
+ end
20
+ admin.tabs.add "Database Mailer", "/admin/form_datas", :after => "Layouts", :visibility => [:all]
21
+
22
+ tab "Content" do
23
+ add_item "Database Mailer", "/admin/form_datas"
24
+ end
25
+
26
+ Mime::Type.register "application/vnd.ms-excel", :xls
27
+ end
28
+
29
+ def deactivate
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ class CreateFormDatas < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :form_datas do |t|
4
+ t.column :url, :string
5
+ t.column :blob, :text
6
+ t.column :exported, :datetime
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :form_datas, :url
11
+ end
12
+
13
+ def self.down
14
+ drop_table :form_datas
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class AddDataColumns < ActiveRecord::Migration
2
+ def self.up
3
+ DATABASE_MAILER_COLUMNS.each do |k, v|
4
+ unless FormData.column_names.include?(k.to_s)
5
+ add_column(:form_datas, k, v)
6
+ add_index(:form_datas, k) unless v == :text
7
+ end
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ class CreateFormDataAssets < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :form_data_assets do |t|
4
+ t.references :form_data
5
+ t.string :field_name
6
+ t.string :attachment_file_name
7
+ t.string :attachment_content_type
8
+ t.integer :attachment_file_size
9
+ t.datetime :attachment_updated_at
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ add_index :form_data_assets, :form_data_id
15
+ end
16
+
17
+ def self.down
18
+ remove_index :form_data_assets, :form_data_id
19
+ drop_table :form_data_assets
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ class DatabaseMailerDataset < Dataset::Base
2
+
3
+ def load
4
+ create_record :form_datas, :eric_cartman, {
5
+ :name => "Eric Cartman",
6
+ :email => "eric_cartman@example.com",
7
+ :message => "test message"
8
+ }
9
+
10
+ create_record :form_data_assets, :attachment, {
11
+ :form_data_id => form_datas(:eric_cartman).id,
12
+ :field_name => "attachment",
13
+ :attachment_file_name => "attachment.jpg",
14
+ :attachment_content_type => "image/jpg",
15
+ :attachment_file_size => "1234"
16
+ }
17
+ end
18
+
19
+ end
@@ -0,0 +1,69 @@
1
+ class MailersDataset < Dataset::Base
2
+ uses :home_page
3
+
4
+ def load
5
+ create_page "Contact" do
6
+ create_page_part "contact_body",
7
+ :name => "body",
8
+ :content => %Q{
9
+ <r:mailer:form>
10
+ <label for="name">Name:</label><br/>
11
+ <r:mailer:text name="name" /><br/>
12
+
13
+ <label for="email">Email:</label><br/>
14
+ <r:mailer:text name="email" /><br/>
15
+
16
+ <label for="message">Message:</label><br/>
17
+ <r:mailer:textarea name="message" /> <br/>
18
+
19
+ <label for="attachment">Image:</label><br/>
20
+ <r:mailer:file name="attachment" /><br/>
21
+
22
+ <input type="submit" value="Send" />
23
+ </r:mailer:form>}
24
+
25
+ create_page_part "contact_mailer",
26
+ :name => "mailer",
27
+ :content => %Q{
28
+ subject: Contact email
29
+ from: website@example.com
30
+ redirect_to: /contact/thank-you
31
+ recipients:
32
+ - contact@example.com
33
+ }
34
+ create_page "Thank you"
35
+ end
36
+
37
+ create_page "Contact No Save" do
38
+ create_page_part "contact_body_no_save",
39
+ :name => "body",
40
+ :content => %Q{
41
+ <r:mailer:form>
42
+ <label for="name">Name:</label><br/>
43
+ <r:mailer:text name="name" /><br/>
44
+
45
+ <label for="email">Email:</label><br/>
46
+ <r:mailer:text name="email" /><br/>
47
+
48
+ <label for="message">Message:</label><br/>
49
+ <r:mailer:textarea name="message" /> <br/>
50
+
51
+ <label for="attachment">Image:</label><br/>
52
+ <r:mailer:file name="attachment" /><br/>
53
+
54
+ <input type="submit" value="Send" />
55
+ </r:mailer:form>}
56
+
57
+ create_page_part "mailer_no_save",
58
+ :name => 'mailer',
59
+ :content => %Q{
60
+ subject: Contact email
61
+ from: website@example.com
62
+ redirect_to: /contact/thank-you
63
+ save_to_database: false
64
+ recipients:
65
+ - contact@example.com
66
+ }
67
+ end
68
+ end
69
+ end
Binary file
@@ -0,0 +1,45 @@
1
+ Feature: Database Mailer
2
+ In order to add database persistency to emailed forms
3
+ As an admin
4
+ I want to manage form fields
5
+
6
+ Background:
7
+ Given I am logged in as an admin
8
+
9
+ Scenario: Saving an email to database if 'save_to_database' is true
10
+ Given I am on the contact page
11
+ And I fill in "Name" with "Stan Marsh"
12
+ And I fill in "Email" with "stan_marsh@example.com"
13
+ And I fill in "Message" with "Hello from South Park"
14
+ And I fill in "attachment"
15
+ When I press "Send"
16
+ # email is sent
17
+ Then I should be on the thank you page
18
+ And "contact@example.com" should receive 1 email
19
+ # email is saved to database
20
+ When I go to the form datas index
21
+ Then I should see "Stan Marsh"
22
+ And I should see "Hello from South Park"
23
+ # email attachment is saved to database
24
+ When I follow "Show"
25
+ Then I should see "attachment.jpg"
26
+
27
+ Scenario: Sending an email without saving it to the database
28
+ Given I am on the contact no save page
29
+ And I fill in "Name" with "Stan Marsh"
30
+ And I fill in "Email" with "stan_marsh@example.com"
31
+ And I fill in "Message" with "Hello from South Park"
32
+ And I fill in "attachment"
33
+ When I press "Send"
34
+ Then I should be on the thank you page
35
+ And "contact@example.com" should receive 1 email
36
+ When I go to the form datas index
37
+ Then I should not see "Stan Marsh"
38
+ And I should not see "Hello from South Park"
39
+
40
+ Scenario: Deleting an existing form data
41
+ Given I am on the form datas index
42
+ When I follow "Delete"
43
+ Then I should be on the form datas index
44
+ And I should see "Record deleted!"
45
+ And I should not see "Eric Cartman"
@@ -0,0 +1,6 @@
1
+ Given /^I am logged in as an admin$/ do
2
+ Given "I go to to \"the welcome page\""
3
+ When "I fill in \"Username\" with \"admin\""
4
+ When "I fill in \"Password\" with \"password\""
5
+ When "I press \"Login\""
6
+ end
@@ -0,0 +1,73 @@
1
+ #Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # reset_mailer
7
+ # open_last_email
8
+ # visit_in_email
9
+ # unread_emails_for
10
+ # mailbox_for
11
+ # current_email
12
+ # open_email
13
+ # read_emails_for
14
+ # find_email
15
+
16
+ module EmailHelpers
17
+ def current_email_address
18
+ "example@aissac.ro" # Replace with your a way to find your current_email. e.g current_user.email
19
+ end
20
+ end
21
+ World(EmailHelpers)
22
+
23
+ # Use this step to reset the e-mail queue within a scenario.
24
+ # This is done automatically before each scenario.
25
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
26
+ reset_mailer
27
+ end
28
+
29
+ # Use this step to open the most recently sent e-mail.
30
+ When /^I open the email$/ do
31
+ open_email(current_email_address)
32
+ end
33
+
34
+ When %r{^I follow "([^"]*?)" in the email$} do |link|
35
+ visit_in_email(link)
36
+ end
37
+
38
+ Then /^I should receive (an|\d+) emails?$/ do |amount|
39
+ amount = 1 if amount == "an"
40
+ unread_emails_for(current_email_address).size.should == amount.to_i
41
+ end
42
+
43
+ Then %r{^"([^"]*?)" should receive (\d+) emails?$} do |address, n|
44
+ unread_emails_for(address).size.should == n.to_i
45
+ end
46
+
47
+ Then %r{^"([^"]*?)" should have (\d+) emails?$} do |address, n|
48
+ mailbox_for(address).size.should == n.to_i
49
+ end
50
+
51
+ Then %r{^"([^"]*?)" should not receive an email$} do |address|
52
+ find_email(address).should be_nil
53
+ end
54
+
55
+ Then %r{^I should see "([^"]*?)" in the subject$} do |text|
56
+ current_email.should have_subject(Regexp.new(text))
57
+ end
58
+
59
+ Then %r{^I should see "([^"]*?)" in the email$} do |text|
60
+ current_email.body.should =~ Regexp.new(text)
61
+ end
62
+
63
+ When %r{^"([^"]*?)" opens? the email with subject "([^"]*?)"$} do |address, subject|
64
+ open_email(address, :with_subject => subject)
65
+ end
66
+
67
+ When %r{^"([^"]*?)" opens? the email with text "([^"]*?)"$} do |address, text|
68
+ open_email(address, :with_text => text)
69
+ end
70
+
71
+ When /^I click the first link in the email$/ do
72
+ click_first_link_in_email
73
+ end
@@ -0,0 +1,3 @@
1
+ Given /^I fill in "([^\"]*)"$/ do |field|
2
+ fill_in(field, :with => "#{RAILS_ROOT}/vendor/extensions/database_mailer/features/fixtures/attachment.jpg")
3
+ end
@@ -0,0 +1,119 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
2
+
3
+ # Commonly used webrat steps
4
+ # http://github.com/brynary/webrat
5
+
6
+ Given /^I am on (.+)$/ do |page_name|
7
+ visit path_to(page_name)
8
+ end
9
+
10
+ When /^I go to (.+)$/ do |page_name|
11
+ visit path_to(page_name)
12
+ end
13
+
14
+ When /^I press "([^\"]*)"$/ do |button|
15
+ click_button(button)
16
+ end
17
+
18
+ When /^I follow "([^\"]*)"$/ do |link|
19
+ click_link(link)
20
+ end
21
+
22
+ When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
23
+ fill_in(field, :with => value)
24
+ end
25
+
26
+ When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
27
+ select(value, :from => field)
28
+ end
29
+
30
+ # Use this step in conjunction with Rail's datetime_select helper. For example:
31
+ # When I select "December 25, 2008 10:00" as the date and time
32
+ When /^I select "([^\"]*)" as the date and time$/ do |time|
33
+ select_datetime(time)
34
+ end
35
+
36
+ # Use this step when using multiple datetime_select helpers on a page or
37
+ # you want to specify which datetime to select. Given the following view:
38
+ # <%= f.label :preferred %><br />
39
+ # <%= f.datetime_select :preferred %>
40
+ # <%= f.label :alternative %><br />
41
+ # <%= f.datetime_select :alternative %>
42
+ # The following steps would fill out the form:
43
+ # When I select "November 23, 2004 11:20" as the "Preferred" date and time
44
+ # And I select "November 25, 2004 10:30" as the "Alternative" date and time
45
+ When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
46
+ select_datetime(datetime, :from => datetime_label)
47
+ end
48
+
49
+ # Use this step in conjunction with Rail's time_select helper. For example:
50
+ # When I select "2:20PM" as the time
51
+ # Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
52
+ # will convert the 2:20PM to 14:20 and then select it.
53
+ When /^I select "([^\"]*)" as the time$/ do |time|
54
+ select_time(time)
55
+ end
56
+
57
+ # Use this step when using multiple time_select helpers on a page or you want to
58
+ # specify the name of the time on the form. For example:
59
+ # When I select "7:30AM" as the "Gym" time
60
+ When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
61
+ select_time(time, :from => time_label)
62
+ end
63
+
64
+ # Use this step in conjunction with Rail's date_select helper. For example:
65
+ # When I select "February 20, 1981" as the date
66
+ When /^I select "([^\"]*)" as the date$/ do |date|
67
+ select_date(date)
68
+ end
69
+
70
+ # Use this step when using multiple date_select helpers on one page or
71
+ # you want to specify the name of the date on the form. For example:
72
+ # When I select "April 26, 1982" as the "Date of Birth" date
73
+ When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
74
+ select_date(date, :from => date_label)
75
+ end
76
+
77
+ When /^I check "([^\"]*)"$/ do |field|
78
+ check(field)
79
+ end
80
+
81
+ When /^I uncheck "([^\"]*)"$/ do |field|
82
+ uncheck(field)
83
+ end
84
+
85
+ When /^I choose "([^\"]*)"$/ do |field|
86
+ choose(field)
87
+ end
88
+
89
+ When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
90
+ attach_file(field, path)
91
+ end
92
+
93
+ Then /^I should see "([^\"]*)"$/ do |text|
94
+ response.should contain(text)
95
+ end
96
+
97
+ Then /^I should not see "([^\"]*)"$/ do |text|
98
+ response.should_not contain(text)
99
+ end
100
+
101
+ Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
102
+ field_labeled(field).value.should =~ /#{value}/
103
+ end
104
+
105
+ Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
106
+ field_labeled(field).value.should_not =~ /#{value}/
107
+ end
108
+
109
+ Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
110
+ field_labeled(label).should be_checked
111
+ end
112
+
113
+ Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
114
+ field_labeled(label).should_not be_checked
115
+ end
116
+
117
+ Then /^I should be on (.+)$/ do |page_name|
118
+ URI.parse(current_url).path.should == path_to(page_name)
119
+ end
@@ -0,0 +1,28 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
4
+
5
+ require 'cucumber/rails/world'
6
+ require 'cucumber/formatter/unicode' # Comment out this line if you don't want Cucumber Unicode support
7
+
8
+ require 'webrat'
9
+
10
+ Webrat.configure do |config|
11
+ config.mode = :rails
12
+ end
13
+
14
+ require 'spec'
15
+ require 'email_spec/cucumber'
16
+
17
+ # Comment out the next two lines if you're not using RSpec's matchers (should / should_not) in your steps.
18
+ require 'cucumber/rails/rspec'
19
+ require 'webrat/core/matchers'
20
+
21
+ Cucumber::Rails::World.class_eval do
22
+ include Dataset
23
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
24
+ Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../datasets')
25
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
26
+
27
+ dataset :pages, :users, :mailers, :database_mailer
28
+ end
@@ -0,0 +1,25 @@
1
+ module NavigationHelpers
2
+ def path_to(page_name)
3
+ case page_name
4
+
5
+ when /the welcome page/
6
+ admin_path
7
+ when /the contact page/
8
+ '/contact'
9
+ when /the contact no save page/
10
+ '/contact-no-save'
11
+ when /the thank you page/
12
+ '/contact/thank-you'
13
+ when /the form datas index/
14
+ admin_form_datas_path
15
+
16
+ # Add more page name => path mappings here
17
+
18
+ else
19
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
20
+ "Now, go and add a mapping in features/support/paths.rb"
21
+ end
22
+ end
23
+ end
24
+
25
+ World(NavigationHelpers)
@@ -0,0 +1,8 @@
1
+ module RadiantDatabaseMailerExtension
2
+ VERSION = '1.0.1'
3
+ SUMMARY = %q{Database mailer for Radiant CMS}
4
+ DESCRIPTION = %q{Save fields from mailer forms to the database.}
5
+ URL = "http://blog.aissac.ro/radiant/database-mailer-extension/"
6
+ AUTHORS = ["Cristi Duma", "Istvan Hoka"]
7
+ EMAIL = ["cristi.duma@aissac.ro"]
8
+ end
@@ -0,0 +1,31 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :database_mailer do
4
+
5
+ desc "Runs the migration of the Database Mailer extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+
9
+ DatabaseMailerExtension.migrator.set_schema_version(1) if DatabaseMailerExtension.migrator.current_version > 1
10
+
11
+ if ENV["VERSION"]
12
+ DatabaseMailerExtension.migrator.migrate(ENV["VERSION"].to_i)
13
+ else
14
+ DatabaseMailerExtension.migrator.migrate
15
+ end
16
+ end
17
+
18
+ desc "Copies public assets of the Database Mailer to the instance public/ directory."
19
+ task :update => :environment do
20
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
21
+ puts "Copying assets from DatabaseMailerExtension"
22
+ Dir[DatabaseMailerExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
23
+ path = file.sub(DatabaseMailerExtension.root, '')
24
+ directory = File.dirname(path)
25
+ mkdir_p RAILS_ROOT + directory, :verbose => false
26
+ cp file, RAILS_ROOT + path, :verbose => false
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,73 @@
1
+ document.observe("dom:loaded", function () {
2
+ var element = $('expander');
3
+ element.observe('click', function() {
4
+ if (element.up('#filters').hasClassName('expanded')) {
5
+ hideForm()
6
+ } else {
7
+ showForm()
8
+ }
9
+ });
10
+ center('blob-popup');
11
+ });
12
+
13
+ function hideForm() {
14
+ Effect.SlideUp('form',{ duration: 0.5, afterFinish:function() {
15
+ $('expander').up('#filters').removeClassName('expanded')
16
+ }
17
+ });
18
+ }
19
+
20
+ function showForm () {
21
+ $('expander').up('#filters').addClassName('expanded')
22
+ Effect.SlideDown('form', { duration: 0.5 });
23
+ }
24
+
25
+ function close() {
26
+ if ($('expander').up('#filters').hasClassName('expanded')) {
27
+ hideForm()
28
+ }
29
+ }
30
+
31
+
32
+ document.observe("dom:loaded", function () {
33
+ var element = $('x_expander');
34
+ element.observe('click', function() {
35
+ if (element.up('#x_filters').hasClassName('expanded')) {
36
+ hideXForm()
37
+ } else {
38
+ showXForm()
39
+ }
40
+ });
41
+ });
42
+
43
+ function hideXForm() {
44
+ Effect.SlideUp('x_form',{ duration: 0.5, afterFinish:function() {
45
+ $('x_expander').up('#x_filters').removeClassName('expanded')
46
+ }
47
+ });
48
+ }
49
+
50
+ function showXForm () {
51
+ $('x_expander').up('#x_filters').addClassName('expanded')
52
+ Effect.SlideDown('x_form', { duration: 0.5 });
53
+ }
54
+
55
+ function closeX() {
56
+ if ($('x_expander').up('#x_filters').hasClassName('expanded')) {
57
+ hideXForm()
58
+ }
59
+ }
60
+
61
+ function show_details() {
62
+ $('attachments').hide();
63
+ $('details').show();
64
+ $('details_lnk').addClassName('here');
65
+ $('attachments_lnk').removeClassName('here');
66
+ }
67
+
68
+ function show_attachments() {
69
+ $('attachments').show();
70
+ $('details').hide();
71
+ $('details_lnk').removeClassName('here');
72
+ $('attachments_lnk').addClassName('here');
73
+ }