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.

Files changed (521) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +1 -11
  3. data/Gemfile +7 -19
  4. data/Gemfile.lock +166 -166
  5. data/Procfile +1 -1
  6. data/README.md +20 -20
  7. data/app/assets/javascripts/admin/fields.js.coffee +3 -3
  8. data/app/assets/javascripts/application.js.erb +3 -0
  9. data/app/assets/javascripts/crm.js +1 -0
  10. data/app/assets/javascripts/crm_comments.js.coffee +66 -0
  11. data/app/assets/javascripts/lists.js.coffee +45 -2
  12. data/app/assets/javascripts/search.js.coffee +2 -0
  13. data/app/assets/javascripts/timeago.js +17 -0
  14. data/app/assets/stylesheets/advanced_search.css.scss +49 -25
  15. data/app/assets/stylesheets/application.css.erb +3 -0
  16. data/app/assets/stylesheets/common.scss +13 -0
  17. data/app/assets/stylesheets/format_buttons.css.scss +15 -10
  18. data/app/assets/stylesheets/header.scss +3 -0
  19. data/app/assets/stylesheets/lists.css.scss +4 -0
  20. data/app/controllers/admin/fields_controller.rb +5 -5
  21. data/app/controllers/admin/users_controller.rb +1 -3
  22. data/app/controllers/application_controller.rb +23 -23
  23. data/app/controllers/comments_controller.rb +3 -31
  24. data/app/controllers/entities/accounts_controller.rb +3 -3
  25. data/app/controllers/entities/campaigns_controller.rb +4 -4
  26. data/app/controllers/entities/contacts_controller.rb +2 -2
  27. data/app/controllers/entities/leads_controller.rb +3 -3
  28. data/app/controllers/entities/opportunities_controller.rb +4 -3
  29. data/app/controllers/entities_controller.rb +6 -6
  30. data/app/controllers/home_controller.rb +1 -1
  31. data/app/controllers/lists_controller.rb +8 -1
  32. data/app/controllers/tasks_controller.rb +1 -1
  33. data/app/controllers/users_controller.rb +46 -23
  34. data/app/helpers/admin/application_helper.rb +1 -3
  35. data/app/helpers/admin/field_groups_helper.rb +2 -1
  36. data/app/helpers/application_helper.rb +37 -16
  37. data/app/helpers/home_helper.rb +1 -2
  38. data/app/helpers/leads_helper.rb +5 -6
  39. data/app/helpers/tasks_helper.rb +36 -50
  40. data/app/models/entities/account.rb +10 -7
  41. data/app/models/entities/campaign.rb +4 -4
  42. data/app/models/entities/contact.rb +8 -5
  43. data/app/models/entities/lead.rb +8 -8
  44. data/app/models/entities/opportunity.rb +13 -18
  45. data/app/models/fields/custom_field.rb +10 -0
  46. data/app/models/fields/field.rb +3 -3
  47. data/app/models/fields/field_group.rb +1 -1
  48. data/app/models/list.rb +1 -0
  49. data/app/models/polymorphic/address.rb +3 -3
  50. data/app/models/polymorphic/comment.rb +2 -4
  51. data/app/models/polymorphic/task.rb +32 -27
  52. data/app/models/setting.rb +3 -9
  53. data/app/models/users/ability.rb +2 -13
  54. data/app/models/users/user.rb +12 -15
  55. data/app/views/accounts/_edit.html.haml +1 -1
  56. data/app/views/accounts/_index_brief.html.haml +3 -3
  57. data/app/views/accounts/_index_long.html.haml +3 -3
  58. data/app/views/accounts/_new.html.haml +1 -1
  59. data/app/views/accounts/create.js.haml +17 -0
  60. data/app/views/accounts/destroy.js.haml +6 -0
  61. data/app/views/accounts/edit.js.haml +32 -0
  62. data/app/views/accounts/index.js.haml +11 -0
  63. data/app/views/accounts/index.xls.builder +9 -7
  64. data/app/views/accounts/new.js.haml +11 -0
  65. data/app/views/accounts/show.js.haml +5 -0
  66. data/app/views/accounts/update.js.haml +17 -0
  67. data/app/views/admin/field_groups/_edit.html.haml +1 -1
  68. data/app/views/admin/field_groups/_new.html.haml +1 -1
  69. data/app/views/admin/field_groups/confirm.js.haml +7 -0
  70. data/app/views/admin/field_groups/create.js.haml +20 -0
  71. data/app/views/admin/field_groups/destroy.js.haml +9 -0
  72. data/app/views/admin/field_groups/edit.js.haml +12 -0
  73. data/app/views/admin/field_groups/new.js.haml +8 -0
  74. data/app/views/admin/field_groups/update.js.haml +8 -0
  75. data/app/views/admin/fields/_field.html.haml +2 -2
  76. data/app/views/admin/fields/_form.html.haml +2 -2
  77. data/app/views/admin/fields/create.js.haml +17 -0
  78. data/app/views/admin/fields/destroy.js.haml +8 -0
  79. data/app/views/admin/fields/edit.js.haml +3 -0
  80. data/app/views/admin/fields/update.js.haml +13 -0
  81. data/app/views/admin/groups/_edit.html.haml +1 -1
  82. data/app/views/admin/groups/_new.html.haml +1 -1
  83. data/app/views/admin/groups/create.js.haml +10 -0
  84. data/app/views/admin/groups/destroy.js.haml +9 -0
  85. data/app/views/admin/groups/edit.js.haml +14 -0
  86. data/app/views/admin/groups/index.html.haml +1 -1
  87. data/app/views/admin/groups/index.js.haml +2 -0
  88. data/app/views/admin/groups/new.js.haml +9 -0
  89. data/app/views/admin/groups/update.js.haml +9 -0
  90. data/app/views/admin/tags/_edit.html.haml +1 -1
  91. data/app/views/admin/tags/_new.html.haml +1 -1
  92. data/app/views/admin/tags/confirm.js.haml +7 -0
  93. data/app/views/admin/tags/create.js.haml +11 -0
  94. data/app/views/admin/tags/destroy.js.haml +10 -0
  95. data/app/views/admin/tags/edit.js.haml +20 -0
  96. data/app/views/admin/tags/new.js.haml +7 -0
  97. data/app/views/admin/tags/update.js.haml +9 -0
  98. data/app/views/admin/users/_edit.html.haml +1 -1
  99. data/app/views/admin/users/_new.html.haml +1 -1
  100. data/app/views/admin/users/_user.html.haml +1 -1
  101. data/app/views/admin/users/confirm.js.haml +7 -0
  102. data/app/views/admin/users/create.js.haml +10 -0
  103. data/app/views/admin/users/destroy.js.haml +10 -0
  104. data/app/views/admin/users/edit.js.haml +20 -0
  105. data/app/views/admin/users/index.js.haml +2 -0
  106. data/app/views/admin/users/new.js.haml +9 -0
  107. data/app/views/admin/users/reactivate.js.haml +3 -0
  108. data/app/views/admin/users/suspend.js.haml +3 -0
  109. data/app/views/admin/users/update.js.haml +9 -0
  110. data/app/views/authentications/new.html.haml +1 -1
  111. data/app/views/campaigns/_edit.html.haml +1 -1
  112. data/app/views/campaigns/_new.html.haml +1 -1
  113. data/app/views/campaigns/create.js.haml +20 -0
  114. data/app/views/campaigns/destroy.js.haml +6 -0
  115. data/app/views/campaigns/edit.js.haml +33 -0
  116. data/app/views/campaigns/index.js.haml +11 -0
  117. data/app/views/campaigns/index.xls.builder +9 -7
  118. data/app/views/campaigns/new.js.haml +11 -0
  119. data/app/views/campaigns/show.js.haml +5 -0
  120. data/app/views/campaigns/update.js.haml +20 -0
  121. data/app/views/comments/_comment.html.haml +1 -1
  122. data/app/views/comments/_edit.html.haml +1 -1
  123. data/app/views/comments/_new.html.haml +3 -2
  124. data/app/views/comments/create.js.haml +14 -0
  125. data/app/views/comments/destroy.js.haml +5 -0
  126. data/app/views/comments/edit.js.haml +11 -0
  127. data/app/views/comments/update.js.haml +9 -0
  128. data/app/views/contacts/_edit.html.haml +1 -1
  129. data/app/views/contacts/_index_full.html.haml +1 -1
  130. data/app/views/contacts/_index_long.html.haml +2 -1
  131. data/app/views/contacts/_new.html.haml +1 -1
  132. data/app/views/contacts/_section_general.html.haml +3 -3
  133. data/app/views/contacts/create.js.haml +23 -0
  134. data/app/views/contacts/destroy.js.haml +9 -0
  135. data/app/views/contacts/edit.js.haml +35 -0
  136. data/app/views/contacts/index.js.haml +11 -0
  137. data/app/views/contacts/index.xls.builder +9 -7
  138. data/app/views/contacts/new.js.haml +13 -0
  139. data/app/views/contacts/show.js.haml +5 -0
  140. data/app/views/contacts/update.js.haml +22 -0
  141. data/app/views/emails/destroy.js.haml +5 -0
  142. data/app/views/entities/_permissions.html.haml +1 -1
  143. data/app/views/entities/attach.js.haml +21 -0
  144. data/app/views/entities/contacts.js.haml +3 -0
  145. data/app/views/entities/discard.js.haml +6 -0
  146. data/app/views/entities/leads.js.haml +3 -0
  147. data/app/views/entities/opportunities.js.haml +3 -0
  148. data/app/views/entities/subscription_update.js.haml +4 -0
  149. data/app/views/entities/versions.js.haml +3 -0
  150. data/app/views/fields/group.js.erb +3 -0
  151. data/app/views/home/_account.html.haml +3 -3
  152. data/app/views/home/_opportunity.html.haml +3 -3
  153. data/app/views/home/index.atom.builder +3 -3
  154. data/app/views/home/index.js.haml +7 -0
  155. data/app/views/home/index.rss.builder +2 -2
  156. data/app/views/home/options.js.haml +7 -0
  157. data/app/views/layouts/_footer.html.haml +0 -4
  158. data/app/views/layouts/_sidebar.html.haml +1 -0
  159. data/app/views/layouts/_tabbed.html.haml +1 -4
  160. data/app/views/layouts/admin/application.html.haml +0 -1
  161. data/app/views/layouts/application.html.haml +5 -7
  162. data/app/views/leads/_convert.html.haml +1 -1
  163. data/app/views/leads/_edit.html.haml +1 -1
  164. data/app/views/leads/_index_long.html.haml +2 -2
  165. data/app/views/leads/_new.html.haml +1 -1
  166. data/app/views/leads/convert.js.haml +35 -0
  167. data/app/views/leads/create.js.haml +21 -0
  168. data/app/views/leads/destroy.js.haml +9 -0
  169. data/app/views/leads/edit.js.haml +35 -0
  170. data/app/views/leads/index.js.haml +11 -0
  171. data/app/views/leads/index.xls.builder +9 -7
  172. data/app/views/leads/new.js.haml +11 -0
  173. data/app/views/leads/promote.js.haml +26 -0
  174. data/app/views/leads/reject.js.haml +12 -0
  175. data/app/views/leads/show.js.haml +5 -0
  176. data/app/views/leads/update.js.haml +26 -0
  177. data/app/views/lists/_personal_sidebar.html.haml +28 -0
  178. data/app/views/lists/_sidebar.html.haml +10 -7
  179. data/app/views/lists/create.js.haml +10 -0
  180. data/app/views/lists/destroy.js.haml +1 -0
  181. data/app/views/opportunities/_edit.html.haml +1 -1
  182. data/app/views/opportunities/_index_brief.html.haml +3 -3
  183. data/app/views/opportunities/_index_long.html.haml +3 -3
  184. data/app/views/opportunities/_new.html.haml +1 -2
  185. data/app/views/opportunities/_top_section.html.haml +4 -0
  186. data/app/views/opportunities/contacts.js.haml +3 -0
  187. data/app/views/opportunities/create.js.haml +29 -0
  188. data/app/views/opportunities/destroy.js.haml +13 -0
  189. data/app/views/opportunities/edit.js.haml +35 -0
  190. data/app/views/opportunities/index.js.haml +11 -0
  191. data/app/views/opportunities/index.xls.builder +9 -7
  192. data/app/views/opportunities/new.js.haml +13 -0
  193. data/app/views/opportunities/show.js.haml +5 -0
  194. data/app/views/opportunities/update.js.haml +25 -0
  195. data/app/views/passwords/edit.html.haml +1 -1
  196. data/app/views/passwords/new.html.haml +1 -1
  197. data/app/views/shared/_comment.html.haml +1 -1
  198. data/app/views/shared/_inline_styles.html.haml +1 -1
  199. data/app/views/tasks/_edit.html.haml +1 -1
  200. data/app/views/tasks/_new.html.haml +1 -1
  201. data/app/views/tasks/complete.js.haml +14 -0
  202. data/app/views/tasks/create.js.haml +39 -0
  203. data/app/views/tasks/destroy.js.haml +7 -0
  204. data/app/views/tasks/discard.js.haml +1 -0
  205. data/app/views/tasks/edit.js.haml +26 -0
  206. data/app/views/tasks/filter.js.haml +4 -0
  207. data/app/views/tasks/index.xls.builder +7 -5
  208. data/app/views/tasks/new.js.haml +8 -0
  209. data/app/views/tasks/update.js.haml +19 -0
  210. data/app/views/users/_password.html.haml +1 -1
  211. data/app/views/users/_profile.html.haml +1 -1
  212. data/app/views/users/avatar.js.haml +9 -0
  213. data/app/views/users/change_password.js.haml +13 -0
  214. data/app/views/users/edit.js.haml +9 -0
  215. data/app/views/users/new.html.haml +1 -1
  216. data/app/views/users/password.js.haml +10 -0
  217. data/app/views/users/update.js.haml +9 -0
  218. data/app/views/users/upload_avatar.js.haml +7 -0
  219. data/app/views/versions/_version.html.haml +1 -1
  220. data/config/application.rb +1 -4
  221. data/config/environments/production.rb +3 -2
  222. data/config/initializers/custom_field_ransack_translations.rb +15 -0
  223. data/config/initializers/locale.rb +9 -1
  224. data/config/initializers/secret_token.rb +1 -25
  225. data/config/initializers/views.rb +20 -20
  226. data/config/locales/cz.yml +245 -211
  227. data/config/locales/cz_fat_free_crm.yml +105 -181
  228. data/config/locales/de.yml +162 -118
  229. data/config/locales/de_fat_free_crm.yml +760 -731
  230. data/config/locales/de_ransack.yml +91 -0
  231. data/config/locales/en-GB.yml +158 -119
  232. data/config/locales/en-GB_fat_free_crm.yml +161 -279
  233. data/config/locales/en-US.yml +158 -121
  234. data/config/locales/en-US_fat_free_crm.yml +185 -179
  235. data/config/locales/en-US_ransack.yml +81 -82
  236. data/config/locales/es.yml +164 -123
  237. data/config/locales/es_fat_free_crm.yml +151 -209
  238. data/config/locales/fr-CA.yml +167 -130
  239. data/config/locales/fr-CA_fat_free_crm.yml +142 -202
  240. data/config/locales/fr.yml +170 -125
  241. data/config/locales/fr_fat_free_crm.yml +199 -302
  242. data/config/locales/it.yml +158 -122
  243. data/config/locales/it_fat_free_crm.yml +105 -168
  244. data/config/locales/ja.yml +162 -131
  245. data/config/locales/ja_fat_free_crm.yml +118 -188
  246. data/config/locales/pl.yml +168 -132
  247. data/config/locales/pl_fat_free_crm.yml +115 -186
  248. data/config/locales/pt-BR.yml +160 -127
  249. data/config/locales/pt-BR_fat_free_crm.yml +125 -182
  250. data/config/locales/ru.yml +256 -233
  251. data/config/locales/ru_fat_free_crm.yml +136 -193
  252. data/config/locales/sv-SE.yml +164 -181
  253. data/config/locales/sv-SE_fat_free_crm.yml +129 -193
  254. data/config/locales/th_fat_free_crm.yml +114 -194
  255. data/config/locales/zh-CN.yml +176 -149
  256. data/config/locales/zh-CN_fat_free_crm.yml +78 -167
  257. data/config/routes.rb +1 -1
  258. data/config/settings.default.yml +74 -23
  259. data/custom_plan.rb +11 -0
  260. data/db/migrate/20131207033244_add_user_id_to_lists.rb +6 -0
  261. data/db/schema.rb +4 -1
  262. data/fat_free_crm.gemspec +3 -3
  263. data/lib/fat_free_crm.rb +1 -11
  264. data/lib/fat_free_crm/export_csv.rb +3 -3
  265. data/lib/fat_free_crm/fields.rb +10 -0
  266. data/lib/fat_free_crm/gem_dependencies.rb +1 -2
  267. data/lib/fat_free_crm/i18n.rb +9 -5
  268. data/lib/fat_free_crm/version.rb +2 -2
  269. data/lib/fat_free_crm/view_factory.rb +8 -5
  270. data/lib/tasks/ffcrm/config.rake +9 -12
  271. data/lib/tasks/ffcrm/missing_translations.rake +2 -1
  272. data/spec/controllers/admin/users_controller_spec.rb +6 -4
  273. data/spec/controllers/applications_controller_spec.rb +4 -4
  274. data/spec/controllers/authentications_controller_spec.rb +15 -15
  275. data/spec/controllers/comments_controller_spec.rb +9 -87
  276. data/spec/controllers/emails_controller_spec.rb +1 -1
  277. data/spec/controllers/entities/accounts_controller_spec.rb +7 -7
  278. data/spec/controllers/entities/campaigns_controller_spec.rb +5 -5
  279. data/spec/controllers/entities/contacts_controller_spec.rb +7 -7
  280. data/spec/controllers/entities/leads_controller_spec.rb +14 -14
  281. data/spec/controllers/entities/opportunities_controller_spec.rb +8 -8
  282. data/spec/controllers/home_controller_spec.rb +6 -6
  283. data/spec/controllers/tasks_controller_spec.rb +7 -7
  284. data/spec/controllers/users_controller_spec.rb +22 -50
  285. data/spec/features/support/selector_helpers.rb +1 -6
  286. data/spec/features/tasks_spec.rb +2 -2
  287. data/spec/helpers/application_helper_spec.rb +15 -15
  288. data/spec/lib/fields_spec.rb +29 -29
  289. data/spec/lib/mail_processor/base_spec.rb +7 -7
  290. data/spec/lib/mail_processor/dropbox_spec.rb +3 -3
  291. data/spec/lib/view_factory_spec.rb +14 -14
  292. data/spec/models/entities/opportunity_spec.rb +1 -1
  293. data/spec/models/fields/custom_field_date_pair_spec.rb +14 -14
  294. data/spec/models/fields/custom_field_pair_spec.rb +13 -13
  295. data/spec/models/fields/custom_field_spec.rb +5 -5
  296. data/spec/models/fields/field_spec.rb +2 -2
  297. data/spec/models/observers/entity_observer_spec.rb +2 -2
  298. data/spec/models/users/user_spec.rb +7 -7
  299. data/spec/routing/comments_routing_spec.rb +0 -9
  300. data/spec/shared/controllers.rb +75 -77
  301. data/spec/shared/models.rb +1 -1
  302. data/spec/spec_helper.rb +1 -2
  303. data/spec/support/auth_macros.rb +3 -3
  304. data/spec/support/mail_processor_mocks.rb +13 -13
  305. data/spec/views/accounts/_edit.haml_spec.rb +1 -1
  306. data/spec/views/accounts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
  307. data/spec/views/accounts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
  308. data/spec/views/accounts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
  309. data/spec/views/accounts/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -11
  310. data/spec/views/accounts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  311. data/spec/views/accounts/show.haml_spec.rb +1 -1
  312. data/spec/views/accounts/{update.rjs_spec.rb → update.js.haml_spec.rb} +16 -25
  313. data/spec/views/admin/field_groups/create.js.haml_spec.rb +31 -0
  314. data/spec/views/admin/field_groups/destroy.js.haml_spec.rb +31 -0
  315. data/spec/views/admin/field_groups/edit.js.haml_spec.rb +24 -0
  316. data/spec/views/admin/field_groups/new.js.haml_spec.rb +25 -0
  317. data/spec/views/admin/field_groups/update.js.haml_spec.rb +30 -0
  318. data/spec/views/admin/users/_create.haml_spec.rb +1 -1
  319. data/spec/views/admin/users/{create.rjs_spec.rb → create.js.haml_spec.rb} +6 -9
  320. data/spec/views/admin/users/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
  321. data/spec/views/admin/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +6 -12
  322. data/spec/views/admin/users/index.haml_spec.rb +0 -0
  323. data/spec/views/admin/users/{index.rjs_spec.rb → index.js.haml_spec.rb} +3 -5
  324. data/spec/views/admin/users/{new.rjs_spec.rb → new.js.haml_spec.rb} +4 -6
  325. data/spec/views/admin/users/{reactivate.rjs_spec.rb → reactivate.js.haml_spec.rb} +2 -4
  326. data/spec/views/admin/users/show.haml_spec.rb +0 -0
  327. data/spec/views/admin/users/{suspend.rjs_spec.rb → suspend.js.haml_spec.rb} +2 -4
  328. data/spec/views/admin/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +6 -10
  329. data/spec/views/campaigns/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
  330. data/spec/views/campaigns/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
  331. data/spec/views/campaigns/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +11 -19
  332. data/spec/views/campaigns/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
  333. data/spec/views/campaigns/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  334. data/spec/views/campaigns/{update.rjs_spec.rb → update.js.haml_spec.rb} +14 -21
  335. data/spec/views/comments/{new.rjs_spec.rb → edit.js.haml_spec.rb} +12 -9
  336. data/spec/views/contacts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -16
  337. data/spec/views/contacts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
  338. data/spec/views/contacts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -19
  339. data/spec/views/contacts/index.haml_spec.rb +1 -1
  340. data/spec/views/contacts/{index.rjs_spec.rb → index.js.html_spec.rb} +7 -11
  341. data/spec/views/contacts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -7
  342. data/spec/views/contacts/{update.rjs_spec.rb → update.js.haml_spec.rb} +20 -35
  343. data/spec/views/home/{index.rjs_spec.rb → index.js.haml_spec.rb} +2 -4
  344. data/spec/views/home/{options.rjs_spec.rb → options.js.haml_spec.rb} +7 -12
  345. data/spec/views/leads/{convert.rjs_spec.rb → convert.js.haml_spec.rb} +12 -20
  346. data/spec/views/leads/{create.rjs_spec.rb → create.js.haml_spec.rb} +13 -19
  347. data/spec/views/leads/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -12
  348. data/spec/views/leads/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -20
  349. data/spec/views/leads/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
  350. data/spec/views/leads/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  351. data/spec/views/leads/{promote.rjs_spec.rb → promote.js.haml_spec.rb} +28 -43
  352. data/spec/views/leads/{reject.rjs_spec.rb → reject.js.haml_spec.rb} +10 -17
  353. data/spec/views/leads/{update.rjs_spec.rb → update.js.haml_spec.rb} +25 -38
  354. data/spec/views/opportunities/{create.rjs_spec.rb → create.js.haml_spec.rb} +16 -26
  355. data/spec/views/opportunities/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +13 -16
  356. data/spec/views/opportunities/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
  357. data/spec/views/opportunities/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -12
  358. data/spec/views/opportunities/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  359. data/spec/views/opportunities/{update.rjs_spec.rb → update.js.haml_spec.rb} +29 -46
  360. data/spec/views/tasks/_edit.haml_spec.rb +1 -1
  361. data/spec/views/tasks/{complete.rjs_spec.rb → complete.js.haml_spec.rb} +9 -14
  362. data/spec/views/tasks/{create.rjs_spec.rb → create.js.haml_spec.rb} +25 -33
  363. data/spec/views/tasks/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -11
  364. data/spec/views/tasks/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +9 -14
  365. data/spec/views/tasks/index.haml_spec.rb +1 -2
  366. data/spec/views/tasks/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
  367. data/spec/views/tasks/{update.rjs_spec.rb → update.js.haml_spec.rb} +28 -41
  368. data/spec/views/users/{avatar.rjs_spec.rb → avatar.js.haml_spec.rb} +7 -9
  369. data/spec/views/users/{change_password.rjs_spec.rb → change_password.js.haml_spec.rb} +10 -12
  370. data/spec/views/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +8 -10
  371. data/spec/views/users/{password.rjs_spec.rb → password.js.haml_spec.rb} +9 -11
  372. data/spec/views/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +7 -15
  373. data/spec/views/users/{upload_avatar.rjs_spec.rb → upload_avatar.js.haml_spec.rb} +8 -10
  374. data/vendor/assets/javascripts/ajax-chosen-jquery.js +2 -0
  375. data/vendor/assets/javascripts/ajax-chosen-prototype.js +2 -0
  376. data/vendor/assets/javascripts/ajax-chosen.jquery.coffee +81 -0
  377. data/vendor/assets/javascripts/ajax-chosen.proto.coffee +98 -0
  378. data/vendor/assets/javascripts/jquery_timeago/index.js +17 -0
  379. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js +18 -0
  380. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js +18 -0
  381. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js +20 -0
  382. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js +20 -0
  383. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js +18 -0
  384. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js +17 -0
  385. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js +17 -0
  386. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js +16 -0
  387. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js +19 -0
  388. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js +194 -0
  389. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js +31 -0
  390. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js +18 -0
  391. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js +34 -0
  392. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js +18 -0
  393. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js +20 -0
  394. data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js +20 -0
  395. data/zeus.json +2 -1
  396. metadata +240 -245
  397. data/app/assets/images/delete.png +0 -0
  398. data/app/assets/images/iconset_attribution.png +0 -0
  399. data/app/views/accounts/create.js.rjs +0 -14
  400. data/app/views/accounts/destroy.js.rjs +0 -3
  401. data/app/views/accounts/edit.js.rjs +0 -33
  402. data/app/views/accounts/index.js.rjs +0 -8
  403. data/app/views/accounts/new.js.rjs +0 -9
  404. data/app/views/accounts/show.js.erb +0 -2
  405. data/app/views/accounts/update.js.rjs +0 -17
  406. data/app/views/admin/field_groups/confirm.js.rjs +0 -6
  407. data/app/views/admin/field_groups/create.js.rjs +0 -20
  408. data/app/views/admin/field_groups/destroy.js.rjs +0 -11
  409. data/app/views/admin/field_groups/edit.js.rjs +0 -14
  410. data/app/views/admin/field_groups/new.js.rjs +0 -9
  411. data/app/views/admin/field_groups/update.js.rjs +0 -9
  412. data/app/views/admin/fields/create.js.erb +0 -19
  413. data/app/views/admin/fields/destroy.js.erb +0 -9
  414. data/app/views/admin/fields/edit.js.erb +0 -1
  415. data/app/views/admin/fields/update.js.erb +0 -13
  416. data/app/views/admin/groups/create.js.rjs +0 -11
  417. data/app/views/admin/groups/destroy.js.rjs +0 -11
  418. data/app/views/admin/groups/edit.js.rjs +0 -21
  419. data/app/views/admin/groups/index.js.rjs +0 -2
  420. data/app/views/admin/groups/new.js.rjs +0 -9
  421. data/app/views/admin/groups/update.js.rjs +0 -10
  422. data/app/views/admin/tags/confirm.js.rjs +0 -6
  423. data/app/views/admin/tags/create.js.rjs +0 -12
  424. data/app/views/admin/tags/destroy.js.rjs +0 -11
  425. data/app/views/admin/tags/edit.js.rjs +0 -21
  426. data/app/views/admin/tags/new.js.rjs +0 -8
  427. data/app/views/admin/tags/update.js.rjs +0 -10
  428. data/app/views/admin/users/confirm.js.rjs +0 -6
  429. data/app/views/admin/users/create.js.rjs +0 -11
  430. data/app/views/admin/users/destroy.js.rjs +0 -11
  431. data/app/views/admin/users/edit.js.rjs +0 -21
  432. data/app/views/admin/users/index.js.rjs +0 -3
  433. data/app/views/admin/users/new.js.rjs +0 -8
  434. data/app/views/admin/users/reactivate.js.rjs +0 -3
  435. data/app/views/admin/users/suspend.js.rjs +0 -3
  436. data/app/views/admin/users/update.js.rjs +0 -10
  437. data/app/views/campaigns/create.js.rjs +0 -18
  438. data/app/views/campaigns/destroy.js.rjs +0 -3
  439. data/app/views/campaigns/edit.js.rjs +0 -34
  440. data/app/views/campaigns/index.js.rjs +0 -8
  441. data/app/views/campaigns/new.js.rjs +0 -9
  442. data/app/views/campaigns/show.js.erb +0 -2
  443. data/app/views/campaigns/update.js.rjs +0 -21
  444. data/app/views/comments/create.js.rjs +0 -11
  445. data/app/views/comments/destroy.js.rjs +0 -6
  446. data/app/views/comments/edit.js.rjs +0 -11
  447. data/app/views/comments/new.js.rjs +0 -14
  448. data/app/views/comments/update.js.rjs +0 -11
  449. data/app/views/contacts/create.js.rjs +0 -19
  450. data/app/views/contacts/destroy.js.rjs +0 -7
  451. data/app/views/contacts/edit.js.rjs +0 -36
  452. data/app/views/contacts/index.js.rjs +0 -8
  453. data/app/views/contacts/new.js.rjs +0 -11
  454. data/app/views/contacts/show.js.erb +0 -2
  455. data/app/views/contacts/update.js.rjs +0 -22
  456. data/app/views/emails/destroy.js.rjs +0 -6
  457. data/app/views/entities/attach.js.rjs +0 -24
  458. data/app/views/entities/contacts.js.rjs +0 -3
  459. data/app/views/entities/discard.js.rjs +0 -7
  460. data/app/views/entities/leads.js.rjs +0 -3
  461. data/app/views/entities/opportunities.js.rjs +0 -3
  462. data/app/views/entities/subscription_update.js.rjs +0 -4
  463. data/app/views/entities/versions.js.erb +0 -3
  464. data/app/views/fields/group.js.rjs +0 -7
  465. data/app/views/home/index.js.rjs +0 -7
  466. data/app/views/home/options.js.rjs +0 -8
  467. data/app/views/leads/convert.js.rjs +0 -37
  468. data/app/views/leads/create.js.rjs +0 -19
  469. data/app/views/leads/destroy.js.rjs +0 -7
  470. data/app/views/leads/edit.js.rjs +0 -36
  471. data/app/views/leads/index.js.rjs +0 -8
  472. data/app/views/leads/new.js.rjs +0 -9
  473. data/app/views/leads/promote.js.rjs +0 -27
  474. data/app/views/leads/reject.js.rjs +0 -10
  475. data/app/views/leads/show.js.erb +0 -2
  476. data/app/views/leads/update.js.rjs +0 -27
  477. data/app/views/lists/create.js.rjs +0 -9
  478. data/app/views/lists/destroy.js.rjs +0 -1
  479. data/app/views/opportunities/contacts.js.rjs +0 -3
  480. data/app/views/opportunities/create.js.rjs +0 -29
  481. data/app/views/opportunities/destroy.js.rjs +0 -11
  482. data/app/views/opportunities/edit.js.rjs +0 -36
  483. data/app/views/opportunities/index.js.rjs +0 -8
  484. data/app/views/opportunities/new.js.rjs +0 -12
  485. data/app/views/opportunities/show.js.erb +0 -2
  486. data/app/views/opportunities/update.js.rjs +0 -26
  487. data/app/views/tasks/complete.js.rjs +0 -17
  488. data/app/views/tasks/create.js.rjs +0 -41
  489. data/app/views/tasks/destroy.js.rjs +0 -7
  490. data/app/views/tasks/discard.rjs +0 -1
  491. data/app/views/tasks/edit.js.rjs +0 -23
  492. data/app/views/tasks/filter.js.rjs +0 -1
  493. data/app/views/tasks/new.js.rjs +0 -9
  494. data/app/views/tasks/update.js.rjs +0 -21
  495. data/app/views/users/avatar.js.rjs +0 -10
  496. data/app/views/users/change_password.js.rjs +0 -15
  497. data/app/views/users/edit.js.rjs +0 -10
  498. data/app/views/users/password.js.rjs +0 -11
  499. data/app/views/users/update.js.rjs +0 -10
  500. data/app/views/users/upload_avatar.js.rjs +0 -8
  501. data/lib/fat_free_crm/secret_token_generator.rb +0 -65
  502. data/spec/lib/secret_token_generator_spec.rb +0 -79
  503. data/spec/models/users/abilities/user_ability_spec.rb +0 -58
  504. data/spec/support/rjs_support.rb +0 -14
  505. data/vendor/assets/images/brief.png +0 -0
  506. data/vendor/assets/images/full.png +0 -0
  507. data/vendor/assets/images/long.png +0 -0
  508. data/vendor/assets/images/tab_icons/accounts.png +0 -0
  509. data/vendor/assets/images/tab_icons/accounts_active.png +0 -0
  510. data/vendor/assets/images/tab_icons/campaigns.png +0 -0
  511. data/vendor/assets/images/tab_icons/campaigns_active.png +0 -0
  512. data/vendor/assets/images/tab_icons/contacts.png +0 -0
  513. data/vendor/assets/images/tab_icons/contacts_active.png +0 -0
  514. data/vendor/assets/images/tab_icons/dashboard.png +0 -0
  515. data/vendor/assets/images/tab_icons/dashboard_active.png +0 -0
  516. data/vendor/assets/images/tab_icons/leads.png +0 -0
  517. data/vendor/assets/images/tab_icons/leads_active.png +0 -0
  518. data/vendor/assets/images/tab_icons/opportunities.png +0 -0
  519. data/vendor/assets/images/tab_icons/opportunities_active.png +0 -0
  520. data/vendor/assets/images/tab_icons/tasks.png +0 -0
  521. data/vendor/assets/images/tab_icons/tasks_active.png +0 -0
@@ -0,0 +1,2 @@
1
+ //= require chosen-jquery
2
+ //= require ajax-chosen.jquery
@@ -0,0 +1,2 @@
1
+ //= require chosen-prototype
2
+ //= require ajax-chosen.proto
@@ -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
+ }));