fat_free_crm 0.12.3 → 0.13.0
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.
Potentially problematic release.
This version of fat_free_crm might be problematic. Click here for more details.
- checksums.yaml +5 -13
- data/.travis.yml +1 -11
- data/Gemfile +7 -19
- data/Gemfile.lock +166 -166
- data/Procfile +1 -1
- data/README.md +20 -20
- data/app/assets/javascripts/admin/fields.js.coffee +3 -3
- data/app/assets/javascripts/application.js.erb +3 -0
- data/app/assets/javascripts/crm.js +1 -0
- data/app/assets/javascripts/crm_comments.js.coffee +66 -0
- data/app/assets/javascripts/lists.js.coffee +45 -2
- data/app/assets/javascripts/search.js.coffee +2 -0
- data/app/assets/javascripts/timeago.js +17 -0
- data/app/assets/stylesheets/advanced_search.css.scss +49 -25
- data/app/assets/stylesheets/application.css.erb +3 -0
- data/app/assets/stylesheets/common.scss +13 -0
- data/app/assets/stylesheets/format_buttons.css.scss +15 -10
- data/app/assets/stylesheets/header.scss +3 -0
- data/app/assets/stylesheets/lists.css.scss +4 -0
- data/app/controllers/admin/fields_controller.rb +5 -5
- data/app/controllers/admin/users_controller.rb +1 -3
- data/app/controllers/application_controller.rb +23 -23
- data/app/controllers/comments_controller.rb +3 -31
- data/app/controllers/entities/accounts_controller.rb +3 -3
- data/app/controllers/entities/campaigns_controller.rb +4 -4
- data/app/controllers/entities/contacts_controller.rb +2 -2
- data/app/controllers/entities/leads_controller.rb +3 -3
- data/app/controllers/entities/opportunities_controller.rb +4 -3
- data/app/controllers/entities_controller.rb +6 -6
- data/app/controllers/home_controller.rb +1 -1
- data/app/controllers/lists_controller.rb +8 -1
- data/app/controllers/tasks_controller.rb +1 -1
- data/app/controllers/users_controller.rb +46 -23
- data/app/helpers/admin/application_helper.rb +1 -3
- data/app/helpers/admin/field_groups_helper.rb +2 -1
- data/app/helpers/application_helper.rb +37 -16
- data/app/helpers/home_helper.rb +1 -2
- data/app/helpers/leads_helper.rb +5 -6
- data/app/helpers/tasks_helper.rb +36 -50
- data/app/models/entities/account.rb +10 -7
- data/app/models/entities/campaign.rb +4 -4
- data/app/models/entities/contact.rb +8 -5
- data/app/models/entities/lead.rb +8 -8
- data/app/models/entities/opportunity.rb +13 -18
- data/app/models/fields/custom_field.rb +10 -0
- data/app/models/fields/field.rb +3 -3
- data/app/models/fields/field_group.rb +1 -1
- data/app/models/list.rb +1 -0
- data/app/models/polymorphic/address.rb +3 -3
- data/app/models/polymorphic/comment.rb +2 -4
- data/app/models/polymorphic/task.rb +32 -27
- data/app/models/setting.rb +3 -9
- data/app/models/users/ability.rb +2 -13
- data/app/models/users/user.rb +12 -15
- data/app/views/accounts/_edit.html.haml +1 -1
- data/app/views/accounts/_index_brief.html.haml +3 -3
- data/app/views/accounts/_index_long.html.haml +3 -3
- data/app/views/accounts/_new.html.haml +1 -1
- data/app/views/accounts/create.js.haml +17 -0
- data/app/views/accounts/destroy.js.haml +6 -0
- data/app/views/accounts/edit.js.haml +32 -0
- data/app/views/accounts/index.js.haml +11 -0
- data/app/views/accounts/index.xls.builder +9 -7
- data/app/views/accounts/new.js.haml +11 -0
- data/app/views/accounts/show.js.haml +5 -0
- data/app/views/accounts/update.js.haml +17 -0
- data/app/views/admin/field_groups/_edit.html.haml +1 -1
- data/app/views/admin/field_groups/_new.html.haml +1 -1
- data/app/views/admin/field_groups/confirm.js.haml +7 -0
- data/app/views/admin/field_groups/create.js.haml +20 -0
- data/app/views/admin/field_groups/destroy.js.haml +9 -0
- data/app/views/admin/field_groups/edit.js.haml +12 -0
- data/app/views/admin/field_groups/new.js.haml +8 -0
- data/app/views/admin/field_groups/update.js.haml +8 -0
- data/app/views/admin/fields/_field.html.haml +2 -2
- data/app/views/admin/fields/_form.html.haml +2 -2
- data/app/views/admin/fields/create.js.haml +17 -0
- data/app/views/admin/fields/destroy.js.haml +8 -0
- data/app/views/admin/fields/edit.js.haml +3 -0
- data/app/views/admin/fields/update.js.haml +13 -0
- data/app/views/admin/groups/_edit.html.haml +1 -1
- data/app/views/admin/groups/_new.html.haml +1 -1
- data/app/views/admin/groups/create.js.haml +10 -0
- data/app/views/admin/groups/destroy.js.haml +9 -0
- data/app/views/admin/groups/edit.js.haml +14 -0
- data/app/views/admin/groups/index.html.haml +1 -1
- data/app/views/admin/groups/index.js.haml +2 -0
- data/app/views/admin/groups/new.js.haml +9 -0
- data/app/views/admin/groups/update.js.haml +9 -0
- data/app/views/admin/tags/_edit.html.haml +1 -1
- data/app/views/admin/tags/_new.html.haml +1 -1
- data/app/views/admin/tags/confirm.js.haml +7 -0
- data/app/views/admin/tags/create.js.haml +11 -0
- data/app/views/admin/tags/destroy.js.haml +10 -0
- data/app/views/admin/tags/edit.js.haml +20 -0
- data/app/views/admin/tags/new.js.haml +7 -0
- data/app/views/admin/tags/update.js.haml +9 -0
- data/app/views/admin/users/_edit.html.haml +1 -1
- data/app/views/admin/users/_new.html.haml +1 -1
- data/app/views/admin/users/_user.html.haml +1 -1
- data/app/views/admin/users/confirm.js.haml +7 -0
- data/app/views/admin/users/create.js.haml +10 -0
- data/app/views/admin/users/destroy.js.haml +10 -0
- data/app/views/admin/users/edit.js.haml +20 -0
- data/app/views/admin/users/index.js.haml +2 -0
- data/app/views/admin/users/new.js.haml +9 -0
- data/app/views/admin/users/reactivate.js.haml +3 -0
- data/app/views/admin/users/suspend.js.haml +3 -0
- data/app/views/admin/users/update.js.haml +9 -0
- data/app/views/authentications/new.html.haml +1 -1
- data/app/views/campaigns/_edit.html.haml +1 -1
- data/app/views/campaigns/_new.html.haml +1 -1
- data/app/views/campaigns/create.js.haml +20 -0
- data/app/views/campaigns/destroy.js.haml +6 -0
- data/app/views/campaigns/edit.js.haml +33 -0
- data/app/views/campaigns/index.js.haml +11 -0
- data/app/views/campaigns/index.xls.builder +9 -7
- data/app/views/campaigns/new.js.haml +11 -0
- data/app/views/campaigns/show.js.haml +5 -0
- data/app/views/campaigns/update.js.haml +20 -0
- data/app/views/comments/_comment.html.haml +1 -1
- data/app/views/comments/_edit.html.haml +1 -1
- data/app/views/comments/_new.html.haml +3 -2
- data/app/views/comments/create.js.haml +14 -0
- data/app/views/comments/destroy.js.haml +5 -0
- data/app/views/comments/edit.js.haml +11 -0
- data/app/views/comments/update.js.haml +9 -0
- data/app/views/contacts/_edit.html.haml +1 -1
- data/app/views/contacts/_index_full.html.haml +1 -1
- data/app/views/contacts/_index_long.html.haml +2 -1
- data/app/views/contacts/_new.html.haml +1 -1
- data/app/views/contacts/_section_general.html.haml +3 -3
- data/app/views/contacts/create.js.haml +23 -0
- data/app/views/contacts/destroy.js.haml +9 -0
- data/app/views/contacts/edit.js.haml +35 -0
- data/app/views/contacts/index.js.haml +11 -0
- data/app/views/contacts/index.xls.builder +9 -7
- data/app/views/contacts/new.js.haml +13 -0
- data/app/views/contacts/show.js.haml +5 -0
- data/app/views/contacts/update.js.haml +22 -0
- data/app/views/emails/destroy.js.haml +5 -0
- data/app/views/entities/_permissions.html.haml +1 -1
- data/app/views/entities/attach.js.haml +21 -0
- data/app/views/entities/contacts.js.haml +3 -0
- data/app/views/entities/discard.js.haml +6 -0
- data/app/views/entities/leads.js.haml +3 -0
- data/app/views/entities/opportunities.js.haml +3 -0
- data/app/views/entities/subscription_update.js.haml +4 -0
- data/app/views/entities/versions.js.haml +3 -0
- data/app/views/fields/group.js.erb +3 -0
- data/app/views/home/_account.html.haml +3 -3
- data/app/views/home/_opportunity.html.haml +3 -3
- data/app/views/home/index.atom.builder +3 -3
- data/app/views/home/index.js.haml +7 -0
- data/app/views/home/index.rss.builder +2 -2
- data/app/views/home/options.js.haml +7 -0
- data/app/views/layouts/_footer.html.haml +0 -4
- data/app/views/layouts/_sidebar.html.haml +1 -0
- data/app/views/layouts/_tabbed.html.haml +1 -4
- data/app/views/layouts/admin/application.html.haml +0 -1
- data/app/views/layouts/application.html.haml +5 -7
- data/app/views/leads/_convert.html.haml +1 -1
- data/app/views/leads/_edit.html.haml +1 -1
- data/app/views/leads/_index_long.html.haml +2 -2
- data/app/views/leads/_new.html.haml +1 -1
- data/app/views/leads/convert.js.haml +35 -0
- data/app/views/leads/create.js.haml +21 -0
- data/app/views/leads/destroy.js.haml +9 -0
- data/app/views/leads/edit.js.haml +35 -0
- data/app/views/leads/index.js.haml +11 -0
- data/app/views/leads/index.xls.builder +9 -7
- data/app/views/leads/new.js.haml +11 -0
- data/app/views/leads/promote.js.haml +26 -0
- data/app/views/leads/reject.js.haml +12 -0
- data/app/views/leads/show.js.haml +5 -0
- data/app/views/leads/update.js.haml +26 -0
- data/app/views/lists/_personal_sidebar.html.haml +28 -0
- data/app/views/lists/_sidebar.html.haml +10 -7
- data/app/views/lists/create.js.haml +10 -0
- data/app/views/lists/destroy.js.haml +1 -0
- data/app/views/opportunities/_edit.html.haml +1 -1
- data/app/views/opportunities/_index_brief.html.haml +3 -3
- data/app/views/opportunities/_index_long.html.haml +3 -3
- data/app/views/opportunities/_new.html.haml +1 -2
- data/app/views/opportunities/_top_section.html.haml +4 -0
- data/app/views/opportunities/contacts.js.haml +3 -0
- data/app/views/opportunities/create.js.haml +29 -0
- data/app/views/opportunities/destroy.js.haml +13 -0
- data/app/views/opportunities/edit.js.haml +35 -0
- data/app/views/opportunities/index.js.haml +11 -0
- data/app/views/opportunities/index.xls.builder +9 -7
- data/app/views/opportunities/new.js.haml +13 -0
- data/app/views/opportunities/show.js.haml +5 -0
- data/app/views/opportunities/update.js.haml +25 -0
- data/app/views/passwords/edit.html.haml +1 -1
- data/app/views/passwords/new.html.haml +1 -1
- data/app/views/shared/_comment.html.haml +1 -1
- data/app/views/shared/_inline_styles.html.haml +1 -1
- data/app/views/tasks/_edit.html.haml +1 -1
- data/app/views/tasks/_new.html.haml +1 -1
- data/app/views/tasks/complete.js.haml +14 -0
- data/app/views/tasks/create.js.haml +39 -0
- data/app/views/tasks/destroy.js.haml +7 -0
- data/app/views/tasks/discard.js.haml +1 -0
- data/app/views/tasks/edit.js.haml +26 -0
- data/app/views/tasks/filter.js.haml +4 -0
- data/app/views/tasks/index.xls.builder +7 -5
- data/app/views/tasks/new.js.haml +8 -0
- data/app/views/tasks/update.js.haml +19 -0
- data/app/views/users/_password.html.haml +1 -1
- data/app/views/users/_profile.html.haml +1 -1
- data/app/views/users/avatar.js.haml +9 -0
- data/app/views/users/change_password.js.haml +13 -0
- data/app/views/users/edit.js.haml +9 -0
- data/app/views/users/new.html.haml +1 -1
- data/app/views/users/password.js.haml +10 -0
- data/app/views/users/update.js.haml +9 -0
- data/app/views/users/upload_avatar.js.haml +7 -0
- data/app/views/versions/_version.html.haml +1 -1
- data/config/application.rb +1 -4
- data/config/environments/production.rb +3 -2
- data/config/initializers/custom_field_ransack_translations.rb +15 -0
- data/config/initializers/locale.rb +9 -1
- data/config/initializers/secret_token.rb +1 -25
- data/config/initializers/views.rb +20 -20
- data/config/locales/cz.yml +245 -211
- data/config/locales/cz_fat_free_crm.yml +105 -181
- data/config/locales/de.yml +162 -118
- data/config/locales/de_fat_free_crm.yml +760 -731
- data/config/locales/de_ransack.yml +91 -0
- data/config/locales/en-GB.yml +158 -119
- data/config/locales/en-GB_fat_free_crm.yml +161 -279
- data/config/locales/en-US.yml +158 -121
- data/config/locales/en-US_fat_free_crm.yml +185 -179
- data/config/locales/en-US_ransack.yml +81 -82
- data/config/locales/es.yml +164 -123
- data/config/locales/es_fat_free_crm.yml +151 -209
- data/config/locales/fr-CA.yml +167 -130
- data/config/locales/fr-CA_fat_free_crm.yml +142 -202
- data/config/locales/fr.yml +170 -125
- data/config/locales/fr_fat_free_crm.yml +199 -302
- data/config/locales/it.yml +158 -122
- data/config/locales/it_fat_free_crm.yml +105 -168
- data/config/locales/ja.yml +162 -131
- data/config/locales/ja_fat_free_crm.yml +118 -188
- data/config/locales/pl.yml +168 -132
- data/config/locales/pl_fat_free_crm.yml +115 -186
- data/config/locales/pt-BR.yml +160 -127
- data/config/locales/pt-BR_fat_free_crm.yml +125 -182
- data/config/locales/ru.yml +256 -233
- data/config/locales/ru_fat_free_crm.yml +136 -193
- data/config/locales/sv-SE.yml +164 -181
- data/config/locales/sv-SE_fat_free_crm.yml +129 -193
- data/config/locales/th_fat_free_crm.yml +114 -194
- data/config/locales/zh-CN.yml +176 -149
- data/config/locales/zh-CN_fat_free_crm.yml +78 -167
- data/config/routes.rb +1 -1
- data/config/settings.default.yml +74 -23
- data/custom_plan.rb +11 -0
- data/db/migrate/20131207033244_add_user_id_to_lists.rb +6 -0
- data/db/schema.rb +4 -1
- data/fat_free_crm.gemspec +3 -3
- data/lib/fat_free_crm.rb +1 -11
- data/lib/fat_free_crm/export_csv.rb +3 -3
- data/lib/fat_free_crm/fields.rb +10 -0
- data/lib/fat_free_crm/gem_dependencies.rb +1 -2
- data/lib/fat_free_crm/i18n.rb +9 -5
- data/lib/fat_free_crm/version.rb +2 -2
- data/lib/fat_free_crm/view_factory.rb +8 -5
- data/lib/tasks/ffcrm/config.rake +9 -12
- data/lib/tasks/ffcrm/missing_translations.rake +2 -1
- data/spec/controllers/admin/users_controller_spec.rb +6 -4
- data/spec/controllers/applications_controller_spec.rb +4 -4
- data/spec/controllers/authentications_controller_spec.rb +15 -15
- data/spec/controllers/comments_controller_spec.rb +9 -87
- data/spec/controllers/emails_controller_spec.rb +1 -1
- data/spec/controllers/entities/accounts_controller_spec.rb +7 -7
- data/spec/controllers/entities/campaigns_controller_spec.rb +5 -5
- data/spec/controllers/entities/contacts_controller_spec.rb +7 -7
- data/spec/controllers/entities/leads_controller_spec.rb +14 -14
- data/spec/controllers/entities/opportunities_controller_spec.rb +8 -8
- data/spec/controllers/home_controller_spec.rb +6 -6
- data/spec/controllers/tasks_controller_spec.rb +7 -7
- data/spec/controllers/users_controller_spec.rb +22 -50
- data/spec/features/support/selector_helpers.rb +1 -6
- data/spec/features/tasks_spec.rb +2 -2
- data/spec/helpers/application_helper_spec.rb +15 -15
- data/spec/lib/fields_spec.rb +29 -29
- data/spec/lib/mail_processor/base_spec.rb +7 -7
- data/spec/lib/mail_processor/dropbox_spec.rb +3 -3
- data/spec/lib/view_factory_spec.rb +14 -14
- data/spec/models/entities/opportunity_spec.rb +1 -1
- data/spec/models/fields/custom_field_date_pair_spec.rb +14 -14
- data/spec/models/fields/custom_field_pair_spec.rb +13 -13
- data/spec/models/fields/custom_field_spec.rb +5 -5
- data/spec/models/fields/field_spec.rb +2 -2
- data/spec/models/observers/entity_observer_spec.rb +2 -2
- data/spec/models/users/user_spec.rb +7 -7
- data/spec/routing/comments_routing_spec.rb +0 -9
- data/spec/shared/controllers.rb +75 -77
- data/spec/shared/models.rb +1 -1
- data/spec/spec_helper.rb +1 -2
- data/spec/support/auth_macros.rb +3 -3
- data/spec/support/mail_processor_mocks.rb +13 -13
- data/spec/views/accounts/_edit.haml_spec.rb +1 -1
- data/spec/views/accounts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
- data/spec/views/accounts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
- data/spec/views/accounts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
- data/spec/views/accounts/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -11
- data/spec/views/accounts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/accounts/show.haml_spec.rb +1 -1
- data/spec/views/accounts/{update.rjs_spec.rb → update.js.haml_spec.rb} +16 -25
- data/spec/views/admin/field_groups/create.js.haml_spec.rb +31 -0
- data/spec/views/admin/field_groups/destroy.js.haml_spec.rb +31 -0
- data/spec/views/admin/field_groups/edit.js.haml_spec.rb +24 -0
- data/spec/views/admin/field_groups/new.js.haml_spec.rb +25 -0
- data/spec/views/admin/field_groups/update.js.haml_spec.rb +30 -0
- data/spec/views/admin/users/_create.haml_spec.rb +1 -1
- data/spec/views/admin/users/{create.rjs_spec.rb → create.js.haml_spec.rb} +6 -9
- data/spec/views/admin/users/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
- data/spec/views/admin/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +6 -12
- data/spec/views/admin/users/index.haml_spec.rb +0 -0
- data/spec/views/admin/users/{index.rjs_spec.rb → index.js.haml_spec.rb} +3 -5
- data/spec/views/admin/users/{new.rjs_spec.rb → new.js.haml_spec.rb} +4 -6
- data/spec/views/admin/users/{reactivate.rjs_spec.rb → reactivate.js.haml_spec.rb} +2 -4
- data/spec/views/admin/users/show.haml_spec.rb +0 -0
- data/spec/views/admin/users/{suspend.rjs_spec.rb → suspend.js.haml_spec.rb} +2 -4
- data/spec/views/admin/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +6 -10
- data/spec/views/campaigns/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
- data/spec/views/campaigns/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
- data/spec/views/campaigns/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +11 -19
- data/spec/views/campaigns/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
- data/spec/views/campaigns/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/campaigns/{update.rjs_spec.rb → update.js.haml_spec.rb} +14 -21
- data/spec/views/comments/{new.rjs_spec.rb → edit.js.haml_spec.rb} +12 -9
- data/spec/views/contacts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -16
- data/spec/views/contacts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
- data/spec/views/contacts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -19
- data/spec/views/contacts/index.haml_spec.rb +1 -1
- data/spec/views/contacts/{index.rjs_spec.rb → index.js.html_spec.rb} +7 -11
- data/spec/views/contacts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -7
- data/spec/views/contacts/{update.rjs_spec.rb → update.js.haml_spec.rb} +20 -35
- data/spec/views/home/{index.rjs_spec.rb → index.js.haml_spec.rb} +2 -4
- data/spec/views/home/{options.rjs_spec.rb → options.js.haml_spec.rb} +7 -12
- data/spec/views/leads/{convert.rjs_spec.rb → convert.js.haml_spec.rb} +12 -20
- data/spec/views/leads/{create.rjs_spec.rb → create.js.haml_spec.rb} +13 -19
- data/spec/views/leads/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -12
- data/spec/views/leads/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -20
- data/spec/views/leads/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
- data/spec/views/leads/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/leads/{promote.rjs_spec.rb → promote.js.haml_spec.rb} +28 -43
- data/spec/views/leads/{reject.rjs_spec.rb → reject.js.haml_spec.rb} +10 -17
- data/spec/views/leads/{update.rjs_spec.rb → update.js.haml_spec.rb} +25 -38
- data/spec/views/opportunities/{create.rjs_spec.rb → create.js.haml_spec.rb} +16 -26
- data/spec/views/opportunities/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +13 -16
- data/spec/views/opportunities/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
- data/spec/views/opportunities/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -12
- data/spec/views/opportunities/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/opportunities/{update.rjs_spec.rb → update.js.haml_spec.rb} +29 -46
- data/spec/views/tasks/_edit.haml_spec.rb +1 -1
- data/spec/views/tasks/{complete.rjs_spec.rb → complete.js.haml_spec.rb} +9 -14
- data/spec/views/tasks/{create.rjs_spec.rb → create.js.haml_spec.rb} +25 -33
- data/spec/views/tasks/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -11
- data/spec/views/tasks/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +9 -14
- data/spec/views/tasks/index.haml_spec.rb +1 -2
- data/spec/views/tasks/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/tasks/{update.rjs_spec.rb → update.js.haml_spec.rb} +28 -41
- data/spec/views/users/{avatar.rjs_spec.rb → avatar.js.haml_spec.rb} +7 -9
- data/spec/views/users/{change_password.rjs_spec.rb → change_password.js.haml_spec.rb} +10 -12
- data/spec/views/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +8 -10
- data/spec/views/users/{password.rjs_spec.rb → password.js.haml_spec.rb} +9 -11
- data/spec/views/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +7 -15
- data/spec/views/users/{upload_avatar.rjs_spec.rb → upload_avatar.js.haml_spec.rb} +8 -10
- data/vendor/assets/javascripts/ajax-chosen-jquery.js +2 -0
- data/vendor/assets/javascripts/ajax-chosen-prototype.js +2 -0
- data/vendor/assets/javascripts/ajax-chosen.jquery.coffee +81 -0
- data/vendor/assets/javascripts/ajax-chosen.proto.coffee +98 -0
- data/vendor/assets/javascripts/jquery_timeago/index.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js +16 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js +19 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js +194 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js +31 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js +34 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js +20 -0
- data/zeus.json +2 -1
- metadata +240 -245
- data/app/assets/images/delete.png +0 -0
- data/app/assets/images/iconset_attribution.png +0 -0
- data/app/views/accounts/create.js.rjs +0 -14
- data/app/views/accounts/destroy.js.rjs +0 -3
- data/app/views/accounts/edit.js.rjs +0 -33
- data/app/views/accounts/index.js.rjs +0 -8
- data/app/views/accounts/new.js.rjs +0 -9
- data/app/views/accounts/show.js.erb +0 -2
- data/app/views/accounts/update.js.rjs +0 -17
- data/app/views/admin/field_groups/confirm.js.rjs +0 -6
- data/app/views/admin/field_groups/create.js.rjs +0 -20
- data/app/views/admin/field_groups/destroy.js.rjs +0 -11
- data/app/views/admin/field_groups/edit.js.rjs +0 -14
- data/app/views/admin/field_groups/new.js.rjs +0 -9
- data/app/views/admin/field_groups/update.js.rjs +0 -9
- data/app/views/admin/fields/create.js.erb +0 -19
- data/app/views/admin/fields/destroy.js.erb +0 -9
- data/app/views/admin/fields/edit.js.erb +0 -1
- data/app/views/admin/fields/update.js.erb +0 -13
- data/app/views/admin/groups/create.js.rjs +0 -11
- data/app/views/admin/groups/destroy.js.rjs +0 -11
- data/app/views/admin/groups/edit.js.rjs +0 -21
- data/app/views/admin/groups/index.js.rjs +0 -2
- data/app/views/admin/groups/new.js.rjs +0 -9
- data/app/views/admin/groups/update.js.rjs +0 -10
- data/app/views/admin/tags/confirm.js.rjs +0 -6
- data/app/views/admin/tags/create.js.rjs +0 -12
- data/app/views/admin/tags/destroy.js.rjs +0 -11
- data/app/views/admin/tags/edit.js.rjs +0 -21
- data/app/views/admin/tags/new.js.rjs +0 -8
- data/app/views/admin/tags/update.js.rjs +0 -10
- data/app/views/admin/users/confirm.js.rjs +0 -6
- data/app/views/admin/users/create.js.rjs +0 -11
- data/app/views/admin/users/destroy.js.rjs +0 -11
- data/app/views/admin/users/edit.js.rjs +0 -21
- data/app/views/admin/users/index.js.rjs +0 -3
- data/app/views/admin/users/new.js.rjs +0 -8
- data/app/views/admin/users/reactivate.js.rjs +0 -3
- data/app/views/admin/users/suspend.js.rjs +0 -3
- data/app/views/admin/users/update.js.rjs +0 -10
- data/app/views/campaigns/create.js.rjs +0 -18
- data/app/views/campaigns/destroy.js.rjs +0 -3
- data/app/views/campaigns/edit.js.rjs +0 -34
- data/app/views/campaigns/index.js.rjs +0 -8
- data/app/views/campaigns/new.js.rjs +0 -9
- data/app/views/campaigns/show.js.erb +0 -2
- data/app/views/campaigns/update.js.rjs +0 -21
- data/app/views/comments/create.js.rjs +0 -11
- data/app/views/comments/destroy.js.rjs +0 -6
- data/app/views/comments/edit.js.rjs +0 -11
- data/app/views/comments/new.js.rjs +0 -14
- data/app/views/comments/update.js.rjs +0 -11
- data/app/views/contacts/create.js.rjs +0 -19
- data/app/views/contacts/destroy.js.rjs +0 -7
- data/app/views/contacts/edit.js.rjs +0 -36
- data/app/views/contacts/index.js.rjs +0 -8
- data/app/views/contacts/new.js.rjs +0 -11
- data/app/views/contacts/show.js.erb +0 -2
- data/app/views/contacts/update.js.rjs +0 -22
- data/app/views/emails/destroy.js.rjs +0 -6
- data/app/views/entities/attach.js.rjs +0 -24
- data/app/views/entities/contacts.js.rjs +0 -3
- data/app/views/entities/discard.js.rjs +0 -7
- data/app/views/entities/leads.js.rjs +0 -3
- data/app/views/entities/opportunities.js.rjs +0 -3
- data/app/views/entities/subscription_update.js.rjs +0 -4
- data/app/views/entities/versions.js.erb +0 -3
- data/app/views/fields/group.js.rjs +0 -7
- data/app/views/home/index.js.rjs +0 -7
- data/app/views/home/options.js.rjs +0 -8
- data/app/views/leads/convert.js.rjs +0 -37
- data/app/views/leads/create.js.rjs +0 -19
- data/app/views/leads/destroy.js.rjs +0 -7
- data/app/views/leads/edit.js.rjs +0 -36
- data/app/views/leads/index.js.rjs +0 -8
- data/app/views/leads/new.js.rjs +0 -9
- data/app/views/leads/promote.js.rjs +0 -27
- data/app/views/leads/reject.js.rjs +0 -10
- data/app/views/leads/show.js.erb +0 -2
- data/app/views/leads/update.js.rjs +0 -27
- data/app/views/lists/create.js.rjs +0 -9
- data/app/views/lists/destroy.js.rjs +0 -1
- data/app/views/opportunities/contacts.js.rjs +0 -3
- data/app/views/opportunities/create.js.rjs +0 -29
- data/app/views/opportunities/destroy.js.rjs +0 -11
- data/app/views/opportunities/edit.js.rjs +0 -36
- data/app/views/opportunities/index.js.rjs +0 -8
- data/app/views/opportunities/new.js.rjs +0 -12
- data/app/views/opportunities/show.js.erb +0 -2
- data/app/views/opportunities/update.js.rjs +0 -26
- data/app/views/tasks/complete.js.rjs +0 -17
- data/app/views/tasks/create.js.rjs +0 -41
- data/app/views/tasks/destroy.js.rjs +0 -7
- data/app/views/tasks/discard.rjs +0 -1
- data/app/views/tasks/edit.js.rjs +0 -23
- data/app/views/tasks/filter.js.rjs +0 -1
- data/app/views/tasks/new.js.rjs +0 -9
- data/app/views/tasks/update.js.rjs +0 -21
- data/app/views/users/avatar.js.rjs +0 -10
- data/app/views/users/change_password.js.rjs +0 -15
- data/app/views/users/edit.js.rjs +0 -10
- data/app/views/users/password.js.rjs +0 -11
- data/app/views/users/update.js.rjs +0 -10
- data/app/views/users/upload_avatar.js.rjs +0 -8
- data/lib/fat_free_crm/secret_token_generator.rb +0 -65
- data/spec/lib/secret_token_generator_spec.rb +0 -79
- data/spec/models/users/abilities/user_ability_spec.rb +0 -58
- data/spec/support/rjs_support.rb +0 -14
- data/vendor/assets/images/brief.png +0 -0
- data/vendor/assets/images/full.png +0 -0
- data/vendor/assets/images/long.png +0 -0
- data/vendor/assets/images/tab_icons/accounts.png +0 -0
- data/vendor/assets/images/tab_icons/accounts_active.png +0 -0
- data/vendor/assets/images/tab_icons/campaigns.png +0 -0
- data/vendor/assets/images/tab_icons/campaigns_active.png +0 -0
- data/vendor/assets/images/tab_icons/contacts.png +0 -0
- data/vendor/assets/images/tab_icons/contacts_active.png +0 -0
- data/vendor/assets/images/tab_icons/dashboard.png +0 -0
- data/vendor/assets/images/tab_icons/dashboard_active.png +0 -0
- data/vendor/assets/images/tab_icons/leads.png +0 -0
- data/vendor/assets/images/tab_icons/leads_active.png +0 -0
- data/vendor/assets/images/tab_icons/opportunities.png +0 -0
- data/vendor/assets/images/tab_icons/opportunities_active.png +0 -0
- data/vendor/assets/images/tab_icons/tasks.png +0 -0
- data/vendor/assets/images/tab_icons/tasks_active.png +0 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
(($) ->
|
2
|
+
|
3
|
+
$.fn.ajaxChosen = (options, callback) ->
|
4
|
+
# This will come in handy later.
|
5
|
+
select = this
|
6
|
+
|
7
|
+
# Load chosen. To make things clear, I have taken the liberty
|
8
|
+
# of using the .chzn-autoselect class to specify input elements
|
9
|
+
# we want to use with ajax autocomplete.
|
10
|
+
this.chosen()
|
11
|
+
|
12
|
+
# Now that chosen is loaded normally, we can bootstrap it with
|
13
|
+
# our ajax autocomplete code.
|
14
|
+
this.next('.chzn-container')
|
15
|
+
.find(".search-field > input")
|
16
|
+
.bind 'keyup', ->
|
17
|
+
# This code will be executed every time the user types a letter
|
18
|
+
# into the input form that chosen has created
|
19
|
+
|
20
|
+
# Retrieve the current value of the input form
|
21
|
+
val = $.trim $(this).attr('value')
|
22
|
+
|
23
|
+
# Some simple validation so we don't make excess ajax calls. I am
|
24
|
+
# assuming you don't want to perform a search with less than 3
|
25
|
+
# characters.
|
26
|
+
return false if val.length < 3 or val is $(this).data('prevVal')
|
27
|
+
|
28
|
+
# Set the current search term so we don't execute the ajax call if
|
29
|
+
# the user hits a key that isn't an input letter/number/symbol
|
30
|
+
$(this).data('prevVal', val)
|
31
|
+
|
32
|
+
# This is a useful reference for later
|
33
|
+
field = $(this)
|
34
|
+
|
35
|
+
# I'm assuming that it's ok to use the parameter name `term` to send
|
36
|
+
# the form value during the ajax call. Change if absolutely needed.
|
37
|
+
options.data = term: val
|
38
|
+
|
39
|
+
# If the user provided an ajax success callback, store it so we can
|
40
|
+
# call it after our bootstrapping is finished.
|
41
|
+
success = undefined
|
42
|
+
success ?= options.success
|
43
|
+
|
44
|
+
# Create our own callback that will be executed when the ajax call is
|
45
|
+
# finished.
|
46
|
+
options.success = (data) ->
|
47
|
+
# Exit if the data we're given is invalid
|
48
|
+
return if not data?
|
49
|
+
|
50
|
+
# Go through all of the <option> elements in the <select> and remove
|
51
|
+
# ones that have not been selected by the user.
|
52
|
+
select.find('option').each -> $(this).remove() if not $(this).is(":selected")
|
53
|
+
|
54
|
+
# Send the ajax results to the user callback so we can get an object of
|
55
|
+
# value => text pairs to inject as <option> elements.
|
56
|
+
items = callback data
|
57
|
+
|
58
|
+
# Iterate through the given data and inject the <option> elements into
|
59
|
+
# the DOM
|
60
|
+
$.each items, (value, text) ->
|
61
|
+
$("<option />")
|
62
|
+
.attr('value', value)
|
63
|
+
.html(text)
|
64
|
+
.appendTo(select)
|
65
|
+
|
66
|
+
# Tell chosen that the contents of the <select> input have been updated
|
67
|
+
# This makes chosen update its internal list of the input data.
|
68
|
+
select.trigger("liszt:updated")
|
69
|
+
|
70
|
+
# For some reason, the contents of the input field get removed once you
|
71
|
+
# call trigger above. Often, this can be very annoying (and can make some
|
72
|
+
# searches impossible), so we add the value the user was typing back into
|
73
|
+
# the input field.
|
74
|
+
field.attr('value', val)
|
75
|
+
|
76
|
+
# Finally, call the user supplied callback (if it exists)
|
77
|
+
success() if success?
|
78
|
+
|
79
|
+
# Execute the ajax call to search for autocomplete data
|
80
|
+
$.ajax(options)
|
81
|
+
)(jQuery)
|
@@ -0,0 +1,98 @@
|
|
1
|
+
root = this
|
2
|
+
|
3
|
+
class ajaxChosen extends Chosen
|
4
|
+
activate_field: ->
|
5
|
+
if @options.show_on_activate and not @active_field
|
6
|
+
this.results_show()
|
7
|
+
super
|
8
|
+
|
9
|
+
constructor: (select, @options, callback) ->
|
10
|
+
# Load chosen. To make things clear, I have taken the liberty
|
11
|
+
# of using the .chzn-autoselect class to specify input elements
|
12
|
+
# we want to use with ajax autocomplete.
|
13
|
+
super select, options
|
14
|
+
|
15
|
+
# Save a reference to the chosen object
|
16
|
+
chosen = $(this)
|
17
|
+
|
18
|
+
# Now that chosen is loaded normally, we can bootstrap it with
|
19
|
+
# our ajax autocomplete code.
|
20
|
+
select.next('.chzn-container')
|
21
|
+
.down('.chzn-search > input')
|
22
|
+
.observe 'keyup', ->
|
23
|
+
# This code will be executed every time the user types a letter
|
24
|
+
# into the input form that chosen has created
|
25
|
+
|
26
|
+
# Retrieve the current value of the input form
|
27
|
+
val = $(this).value.strip()
|
28
|
+
# Don't perform the AJAX search until user stops typing for a
|
29
|
+
# minimum delay
|
30
|
+
|
31
|
+
if window.ajaxChosenDelayTimer
|
32
|
+
clearTimeout window.ajaxChosenDelayTimer
|
33
|
+
window.ajaxChosenDelayTimer = null
|
34
|
+
|
35
|
+
# This reference is frozen in the following closures
|
36
|
+
search_field = $(this)
|
37
|
+
|
38
|
+
window.ajaxChosenDelayTimer = setTimeout ->
|
39
|
+
return false if val is search_field.readAttribute('data-prevVal')
|
40
|
+
|
41
|
+
# Set the current search term so we don't execute the ajax call if
|
42
|
+
# the user hits a key that isn't an input letter/number/symbol
|
43
|
+
search_field.writeAttribute('data-prevVal', val)
|
44
|
+
|
45
|
+
# I'm assuming that it's ok to use the parameter name `term` to send
|
46
|
+
# the form value during the ajax call. Change if absolutely needed.
|
47
|
+
query_key = options.query_key || "term"
|
48
|
+
(options.parameters ||= {})[query_key] = val
|
49
|
+
|
50
|
+
# If the user provided an ajax success callback, store it so we can
|
51
|
+
# call it after our bootstrapping is finished.
|
52
|
+
success = options.success
|
53
|
+
|
54
|
+
# Create our own callback that will be executed when the ajax call is
|
55
|
+
# finished.
|
56
|
+
options.onSuccess = (data) ->
|
57
|
+
# Exit if the data we're given is invalid
|
58
|
+
return if not data?
|
59
|
+
|
60
|
+
# Go through all of the <option> elements in the <select> and remove
|
61
|
+
# ones that have not been selected by the user.
|
62
|
+
select.childElements().each (el) -> el.remove() if not el.selected
|
63
|
+
|
64
|
+
# Send the ajax results to the user callback so we can get an object of
|
65
|
+
# value => text pairs to inject as <option> elements.
|
66
|
+
items = if callback then callback(data.responseJSON) else data.responseJSON
|
67
|
+
|
68
|
+
# Iterate through the given data and inject the <option> elements into
|
69
|
+
# the DOM
|
70
|
+
$H(items).each (pair) ->
|
71
|
+
if select.value != pair.key
|
72
|
+
select.insert
|
73
|
+
bottom:
|
74
|
+
new Element("option", {value: pair.key})
|
75
|
+
.update(pair.value)
|
76
|
+
|
77
|
+
val = search_field.value
|
78
|
+
|
79
|
+
# Tell chosen that the contents of the <select> input have been updated
|
80
|
+
# This makes chosen update its internal list of the input data.
|
81
|
+
select.fire("liszt:updated")
|
82
|
+
|
83
|
+
# For some reason, the contents of the input field get removed once you
|
84
|
+
# call trigger above. Often, this can be very annoying (and can make some
|
85
|
+
# searches impossible), so we add the value the user was typing back into
|
86
|
+
# the input field.
|
87
|
+
search_field.value = val
|
88
|
+
|
89
|
+
chosen.winnow_results()
|
90
|
+
|
91
|
+
# Finally, call the user supplied callback (if it exists)
|
92
|
+
success() if success?
|
93
|
+
|
94
|
+
# Execute the ajax call to search for autocomplete data
|
95
|
+
new Ajax.Request options.url, options
|
96
|
+
, 300
|
97
|
+
|
98
|
+
root.ajaxChosen = ajaxChosen
|
@@ -0,0 +1,17 @@
|
|
1
|
+
//= require jquery_timeago/jquery.timeago
|
2
|
+
//= require jquery_timeago/jquery.timeago.cz
|
3
|
+
//= require jquery_timeago/jquery.timeago.de
|
4
|
+
//= require jquery_timeago/jquery.timeago.en-GB
|
5
|
+
//= require jquery_timeago/jquery.timeago.en-US
|
6
|
+
//= require jquery_timeago/jquery.timeago.es
|
7
|
+
//= require jquery_timeago/jquery.timeago.fr-CA
|
8
|
+
//= require jquery_timeago/jquery.timeago.fr
|
9
|
+
//= require jquery_timeago/jquery.timeago.it
|
10
|
+
//= require jquery_timeago/jquery.timeago.ja
|
11
|
+
//= require jquery_timeago/jquery.timeago.js
|
12
|
+
//= require jquery_timeago/jquery.timeago.pl.js
|
13
|
+
//= require jquery_timeago/jquery.timeago.pt-BR
|
14
|
+
//= require jquery_timeago/jquery.timeago.ru.js
|
15
|
+
//= require jquery_timeago/jquery.timeago.sv-SE
|
16
|
+
//= require jquery_timeago/jquery.timeago.th
|
17
|
+
//= require jquery_timeago/jquery.timeago.zh-CN
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// Czech
|
2
|
+
jQuery.timeago.settings.locales['cz'] = {
|
3
|
+
prefixAgo: "před",
|
4
|
+
prefixFromNow: null,
|
5
|
+
suffixAgo: null,
|
6
|
+
suffixFromNow: null,
|
7
|
+
seconds: "méně než minutou",
|
8
|
+
minute: "minutou",
|
9
|
+
minutes: "%d minutami",
|
10
|
+
hour: "hodinou",
|
11
|
+
hours: "%d hodinami",
|
12
|
+
day: "1 dnem",
|
13
|
+
days: "%d dny",
|
14
|
+
month: "1 měsícem",
|
15
|
+
months: "%d měsíci",
|
16
|
+
year: "1 rokem",
|
17
|
+
years: "%d roky"
|
18
|
+
};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// German
|
2
|
+
jQuery.timeago.settings.locales['de'] = {
|
3
|
+
prefixAgo: "vor",
|
4
|
+
prefixFromNow: "in",
|
5
|
+
suffixAgo: "",
|
6
|
+
suffixFromNow: "",
|
7
|
+
seconds: "wenigen Sekunden",
|
8
|
+
minute: "etwa einer Minute",
|
9
|
+
minutes: "%d Minuten",
|
10
|
+
hour: "etwa einer Stunde",
|
11
|
+
hours: "%d Stunden",
|
12
|
+
day: "etwa einem Tag",
|
13
|
+
days: "%d Tagen",
|
14
|
+
month: "etwa einem Monat",
|
15
|
+
months: "%d Monaten",
|
16
|
+
year: "etwa einem Jahr",
|
17
|
+
years: "%d Jahren"
|
18
|
+
};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
// English (Template)
|
2
|
+
jQuery.timeago.settings.locales['en-GB'] = {
|
3
|
+
prefixAgo: null,
|
4
|
+
prefixFromNow: null,
|
5
|
+
suffixAgo: "ago",
|
6
|
+
suffixFromNow: "from now",
|
7
|
+
seconds: "less than a minute",
|
8
|
+
minute: "about a minute",
|
9
|
+
minutes: "%d minutes",
|
10
|
+
hour: "about an hour",
|
11
|
+
hours: "about %d hours",
|
12
|
+
day: "a day",
|
13
|
+
days: "%d days",
|
14
|
+
month: "about a month",
|
15
|
+
months: "%d months",
|
16
|
+
year: "about a year",
|
17
|
+
years: "%d years",
|
18
|
+
wordSeparator: " ",
|
19
|
+
numbers: []
|
20
|
+
};
|
@@ -0,0 +1,20 @@
|
|
1
|
+
// English (Template)
|
2
|
+
jQuery.timeago.settings.locales['en-US'] = {
|
3
|
+
prefixAgo: null,
|
4
|
+
prefixFromNow: null,
|
5
|
+
suffixAgo: "ago",
|
6
|
+
suffixFromNow: "from now",
|
7
|
+
seconds: "less than a minute",
|
8
|
+
minute: "about a minute",
|
9
|
+
minutes: "%d minutes",
|
10
|
+
hour: "about an hour",
|
11
|
+
hours: "about %d hours",
|
12
|
+
day: "a day",
|
13
|
+
days: "%d days",
|
14
|
+
month: "about a month",
|
15
|
+
months: "%d months",
|
16
|
+
year: "about a year",
|
17
|
+
years: "%d years",
|
18
|
+
wordSeparator: " ",
|
19
|
+
numbers: []
|
20
|
+
};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// Spanish
|
2
|
+
jQuery.timeago.settings.locales['es'] = {
|
3
|
+
prefixAgo: "hace",
|
4
|
+
prefixFromNow: "dentro de",
|
5
|
+
suffixAgo: "",
|
6
|
+
suffixFromNow: "",
|
7
|
+
seconds: "menos de un minuto",
|
8
|
+
minute: "un minuto",
|
9
|
+
minutes: "unos %d minutos",
|
10
|
+
hour: "una hora",
|
11
|
+
hours: "%d horas",
|
12
|
+
day: "un día",
|
13
|
+
days: "%d días",
|
14
|
+
month: "un mes",
|
15
|
+
months: "%d meses",
|
16
|
+
year: "un año",
|
17
|
+
years: "%d años"
|
18
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
// French
|
2
|
+
jQuery.timeago.settings.locales['fr-CA'] = {
|
3
|
+
// environ ~= about, it's optional
|
4
|
+
prefixAgo: "il y a",
|
5
|
+
prefixFromNow: "d'ici",
|
6
|
+
seconds: "moins d'une minute",
|
7
|
+
minute: "environ une minute",
|
8
|
+
minutes: "environ %d minutes",
|
9
|
+
hour: "environ une heure",
|
10
|
+
hours: "environ %d heures",
|
11
|
+
day: "environ un jour",
|
12
|
+
days: "environ %d jours",
|
13
|
+
month: "environ un mois",
|
14
|
+
months: "environ %d mois",
|
15
|
+
year: "un an",
|
16
|
+
years: "%d ans"
|
17
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
// French
|
2
|
+
jQuery.timeago.settings.locales['fr'] = {
|
3
|
+
// environ ~= about, it's optional
|
4
|
+
prefixAgo: "il y a",
|
5
|
+
prefixFromNow: "d'ici",
|
6
|
+
seconds: "moins d'une minute",
|
7
|
+
minute: "environ une minute",
|
8
|
+
minutes: "environ %d minutes",
|
9
|
+
hour: "environ une heure",
|
10
|
+
hours: "environ %d heures",
|
11
|
+
day: "environ un jour",
|
12
|
+
days: "environ %d jours",
|
13
|
+
month: "environ un mois",
|
14
|
+
months: "environ %d mois",
|
15
|
+
year: "un an",
|
16
|
+
years: "%d ans"
|
17
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// Italian
|
2
|
+
jQuery.timeago.settings.locales['it'] = {
|
3
|
+
suffixAgo: "fa",
|
4
|
+
suffixFromNow: "da ora",
|
5
|
+
seconds: "meno di un minuto",
|
6
|
+
minute: "circa un minuto",
|
7
|
+
minutes: "%d minuti",
|
8
|
+
hour: "circa un'ora",
|
9
|
+
hours: "circa %d ore",
|
10
|
+
day: "un giorno",
|
11
|
+
days: "%d giorni",
|
12
|
+
month: "circa un mese",
|
13
|
+
months: "%d mesi",
|
14
|
+
year: "circa un anno",
|
15
|
+
years: "%d anni"
|
16
|
+
};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
// Japanese
|
2
|
+
jQuery.timeago.settings.locales['ja'] = {
|
3
|
+
prefixAgo: "",
|
4
|
+
prefixFromNow: "今から",
|
5
|
+
suffixAgo: "前",
|
6
|
+
suffixFromNow: "後",
|
7
|
+
seconds: "1 分未満",
|
8
|
+
minute: "約 1 分",
|
9
|
+
minutes: "%d 分",
|
10
|
+
hour: "約 1 時間",
|
11
|
+
hours: "約 %d 時間",
|
12
|
+
day: "約 1 日",
|
13
|
+
days: "約 %d 日",
|
14
|
+
month: "約 1 月",
|
15
|
+
months: "約 %d 月",
|
16
|
+
year: "約 1 年",
|
17
|
+
years: "約 %d 年",
|
18
|
+
wordSeparator: ""
|
19
|
+
};
|
@@ -0,0 +1,194 @@
|
|
1
|
+
/**
|
2
|
+
* Timeago is a jQuery plugin that makes it easy to support automatically
|
3
|
+
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
|
4
|
+
*
|
5
|
+
* @name timeago
|
6
|
+
* @version 1.3.0
|
7
|
+
* @requires jQuery v1.2.3+
|
8
|
+
* @author Ryan McGeary
|
9
|
+
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
|
10
|
+
*
|
11
|
+
* For usage and examples, visit:
|
12
|
+
* http://timeago.yarp.com/
|
13
|
+
*
|
14
|
+
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
|
15
|
+
*/
|
16
|
+
|
17
|
+
(function (factory) {
|
18
|
+
if (typeof define === 'function' && define.amd) {
|
19
|
+
// AMD. Register as an anonymous module.
|
20
|
+
define(['jquery'], factory);
|
21
|
+
} else {
|
22
|
+
// Browser globals
|
23
|
+
factory(jQuery);
|
24
|
+
}
|
25
|
+
}(function ($) {
|
26
|
+
$.timeago = function(timestamp) {
|
27
|
+
if (timestamp instanceof Date) {
|
28
|
+
return inWords(timestamp);
|
29
|
+
} else if (typeof timestamp === "string") {
|
30
|
+
return inWords($.timeago.parse(timestamp));
|
31
|
+
} else if (typeof timestamp === "number") {
|
32
|
+
return inWords(new Date(timestamp));
|
33
|
+
} else {
|
34
|
+
return inWords($.timeago.datetime(timestamp));
|
35
|
+
}
|
36
|
+
};
|
37
|
+
var $t = $.timeago;
|
38
|
+
|
39
|
+
$.extend($.timeago, {
|
40
|
+
settings: {
|
41
|
+
refreshMillis: 60000,
|
42
|
+
allowFuture: false,
|
43
|
+
localeTitle: false,
|
44
|
+
cutoff: 0,
|
45
|
+
locales: {}, // Added for FFCRM
|
46
|
+
strings: {
|
47
|
+
prefixAgo: null,
|
48
|
+
prefixFromNow: null,
|
49
|
+
suffixAgo: "ago",
|
50
|
+
suffixFromNow: "from now",
|
51
|
+
seconds: "less than a minute",
|
52
|
+
minute: "about a minute",
|
53
|
+
minutes: "%d minutes",
|
54
|
+
hour: "about an hour",
|
55
|
+
hours: "about %d hours",
|
56
|
+
day: "a day",
|
57
|
+
days: "%d days",
|
58
|
+
month: "about a month",
|
59
|
+
months: "%d months",
|
60
|
+
year: "about a year",
|
61
|
+
years: "%d years",
|
62
|
+
wordSeparator: " ",
|
63
|
+
numbers: []
|
64
|
+
}
|
65
|
+
},
|
66
|
+
inWords: function(distanceMillis) {
|
67
|
+
var $l = this.settings.strings;
|
68
|
+
var prefix = $l.prefixAgo;
|
69
|
+
var suffix = $l.suffixAgo;
|
70
|
+
if (this.settings.allowFuture) {
|
71
|
+
if (distanceMillis < 0) {
|
72
|
+
prefix = $l.prefixFromNow;
|
73
|
+
suffix = $l.suffixFromNow;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
var seconds = Math.abs(distanceMillis) / 1000;
|
78
|
+
var minutes = seconds / 60;
|
79
|
+
var hours = minutes / 60;
|
80
|
+
var days = hours / 24;
|
81
|
+
var years = days / 365;
|
82
|
+
|
83
|
+
function substitute(stringOrFunction, number) {
|
84
|
+
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
|
85
|
+
var value = ($l.numbers && $l.numbers[number]) || number;
|
86
|
+
return string.replace(/%d/i, value);
|
87
|
+
}
|
88
|
+
|
89
|
+
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
|
90
|
+
seconds < 90 && substitute($l.minute, 1) ||
|
91
|
+
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
|
92
|
+
minutes < 90 && substitute($l.hour, 1) ||
|
93
|
+
hours < 24 && substitute($l.hours, Math.round(hours)) ||
|
94
|
+
hours < 42 && substitute($l.day, 1) ||
|
95
|
+
days < 30 && substitute($l.days, Math.round(days)) ||
|
96
|
+
days < 45 && substitute($l.month, 1) ||
|
97
|
+
days < 365 && substitute($l.months, Math.round(days / 30)) ||
|
98
|
+
years < 1.5 && substitute($l.year, 1) ||
|
99
|
+
substitute($l.years, Math.round(years));
|
100
|
+
|
101
|
+
var separator = $l.wordSeparator || "";
|
102
|
+
if ($l.wordSeparator === undefined) { separator = " "; }
|
103
|
+
return $.trim([prefix, words, suffix].join(separator));
|
104
|
+
},
|
105
|
+
parse: function(iso8601) {
|
106
|
+
var s = $.trim(iso8601);
|
107
|
+
s = s.replace(/\.\d+/,""); // remove milliseconds
|
108
|
+
s = s.replace(/-/,"/").replace(/-/,"/");
|
109
|
+
s = s.replace(/T/," ").replace(/Z/," UTC");
|
110
|
+
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
|
111
|
+
return new Date(s);
|
112
|
+
},
|
113
|
+
datetime: function(elem) {
|
114
|
+
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
|
115
|
+
return $t.parse(iso8601);
|
116
|
+
},
|
117
|
+
isTime: function(elem) {
|
118
|
+
// jQuery's `is()` doesn't play well with HTML5 in IE
|
119
|
+
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
|
120
|
+
}
|
121
|
+
});
|
122
|
+
|
123
|
+
// functions that can be called via $(el).timeago('action')
|
124
|
+
// init is default when no action is given
|
125
|
+
// functions are called with context of a single element
|
126
|
+
var functions = {
|
127
|
+
init: function(){
|
128
|
+
var refresh_el = $.proxy(refresh, this);
|
129
|
+
refresh_el();
|
130
|
+
var $s = $t.settings;
|
131
|
+
if ($s.refreshMillis > 0) {
|
132
|
+
setInterval(refresh_el, $s.refreshMillis);
|
133
|
+
}
|
134
|
+
},
|
135
|
+
update: function(time){
|
136
|
+
$(this).data('timeago', { datetime: $t.parse(time) });
|
137
|
+
refresh.apply(this);
|
138
|
+
},
|
139
|
+
updateFromDOM: function(){
|
140
|
+
$(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
|
141
|
+
refresh.apply(this);
|
142
|
+
}
|
143
|
+
};
|
144
|
+
|
145
|
+
$.fn.timeago = function(action, options) {
|
146
|
+
var fn = action ? functions[action] : functions.init;
|
147
|
+
if(!fn){
|
148
|
+
throw new Error("Unknown function name '"+ action +"' for timeago");
|
149
|
+
}
|
150
|
+
// each over objects here and call the requested function
|
151
|
+
this.each(function(){
|
152
|
+
fn.call(this, options);
|
153
|
+
});
|
154
|
+
return this;
|
155
|
+
};
|
156
|
+
|
157
|
+
function refresh() {
|
158
|
+
var data = prepareData(this);
|
159
|
+
var $s = $t.settings;
|
160
|
+
|
161
|
+
if (!isNaN(data.datetime)) {
|
162
|
+
if ( $s.cutoff == 0 || distance(data.datetime) < $s.cutoff) {
|
163
|
+
$(this).text(inWords(data.datetime));
|
164
|
+
}
|
165
|
+
}
|
166
|
+
return this;
|
167
|
+
}
|
168
|
+
|
169
|
+
function prepareData(element) {
|
170
|
+
element = $(element);
|
171
|
+
if (!element.data("timeago")) {
|
172
|
+
element.data("timeago", { datetime: $t.datetime(element) });
|
173
|
+
var text = $.trim(element.text());
|
174
|
+
if ($t.settings.localeTitle) {
|
175
|
+
element.attr("title", element.data('timeago').datetime.toLocaleString());
|
176
|
+
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
|
177
|
+
element.attr("title", text);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
return element.data("timeago");
|
181
|
+
}
|
182
|
+
|
183
|
+
function inWords(date) {
|
184
|
+
return $t.inWords(distance(date));
|
185
|
+
}
|
186
|
+
|
187
|
+
function distance(date) {
|
188
|
+
return (new Date().getTime() - date.getTime());
|
189
|
+
}
|
190
|
+
|
191
|
+
// fix for IE6 suckage
|
192
|
+
document.createElement("abbr");
|
193
|
+
document.createElement("time");
|
194
|
+
}));
|